Разработка на .NET под FreeBSD
Вы хотели это увидеть? Получите, распишитесь. «Зеленый слоник» от разработки, грайндхаус в коде и ночной кошмар быдлокодеров. Курлык епта.
Это все несерьезно
Не надо пытаться заниматься такой разработкой на серьезных щщах, по моему описанию ниже. Это просто тест для оценки текущего состояния дел с дотнетом и его реальной а не декларируемой кроссплатформенностью
spoiler: все сильно лучше чем я полагал
Есть куда расти и что чинить, но прогресс за 4 года чудовищный.
Если вы ходите заниматься разработкой на дотнете то вам нужен линукс, а лучше — венды, но точно не BSD.
Текущее состояние дел
Текущее состояние дел с дотнетом под FreeBSD выкладывают тут.
.NET был официально открыт Microsoft и выложен в Github в декабре 2018го года, совсем недавно по меркам индустрии — той же Java.
С тех пор выпускается каждый год новая версия:
Вот так выглядел этот исторический момент выкладывания .NET в опенсорс:
Microsoft's press release highlights that the cross-platform commitment now allows for a fully open-source, modern server-side .NET stack. Microsoft released the source code for WPF, Windows Forms and WinUI on December 4, 2018.[16]
Гуй и десктоп
Нативно не поддерживаются конечно, если вы вдруг успели раскатать губу, но процесс пинания вендора ногами идет.
Пока есть запуск через Wine, стабильный:
На текущий момент даже нет поддержки сборки WPF-приложений на линуксе, настолько все плохо.
Есть альтернативные решения, например Avalonia, но на FreeBSD оно не собирается.
Вот тут лежит огромная обзорная статья про всю историю кроссплатформенной разработки с UI на дотнете. Наслаждайтесь, крайне занимательное чтиво.
Вообщем FreeBSD официально не поддерживается нигде, но на удивление работа по поддержке активно идет.
Как пропатчить .NET под FreeBSD
Cуществует и активно развивается вот такой набор скриптов, по сборке из исходников .NET последних версий 6 и 7.
Уже даже над 8й версией идет работа.
Тут же выкладываются бинарные сборки .NET под FreeBSD, поэтому если у вас вдруг почему-то не возникнет желания собирать дотнет из исходников — просто скачайте сборку.
Для запуска дотнета, как самосборного так и бинарника, нужно поставить:
pkg install libunwind icu libinotify
Погружение в тему
Ниже я расскажу как собрать .NET из исходников, если вы недостаточно круты — прокрутите ниже до следующего раздела.
Нужно будет ~40Гб свободного места на диске и минимум 8Гб памяти на машине:
Если памяти меньше — могут быть падения при сборке, поскольку дотнет собирается другим дотнетом, линуксовым.
Ради него и ставился слой совместимости с линуксом.
Оригинальная инстукция описана в README.MD в ветке репозитория для конкретной версии, я использовал 7ю, как последнюю стабильную.
Имейте ввиду что инструкция частично устарела:
1. Run as root install_tools.sh
- make sure to mount all needed things (add them to /etc/fstab, then mount -a)
Речь тут про Java, которая при первой установке на FreeBSD действительно просит себе procfs, если у вас она уже стояла и работала то ничего монтировать не надо.
Нужно поставить вот такие пакеты:
pkg install autoconf libtool automake cmake llvm10 krb5 terminfo-db libunwind icu libinotify python3 pkgconf binutils npm-node14 node14 openjdk11 bash git wget protobuf linux_base-c7 grpc
И запустить слой эмуляции линукса :
service linux onestart
Который скорее всего у вас и так есть и запущен.
Вообщем fstab должен в итоге выглядеть как-то так:
Запускаем инициализацию сборки
2. ./init.sh
Скрипт выше выкачивает рекурсивно репозитории с исходниками дотнета и бинарные сборки, необходимые для запуска.
Бинарные сборки уже для FreeBSD, собранные на линуксе через crossbuild:
Working SDK for FreeBSD - at the moment it's using binaries from https://github.com/Thefrank/dotnet-freebsd-crossbuild created during crosscompile under Linux
Дальше запускаем сборку рантайма .NET:
3. ./build_runtime.sh
Начнется скачивание большого количества библиотек, которое будет регулярно прерываться.
В оригинале предлагается добавить ключ в случае ошибок:
add -v d
inside if it will fail with SEHExceptions...
К сожалению этого не хватит и придется выкачивать все эти библиотеки вручную через wget или curl и перезапускать скрипт.
Дальше мы по шагам собираем части дотнета и по-сути вкладываем результаты одной сборки в другую.
То что в оригинале написано «try to skip» означает что можно взять готовую сборку и подложить ее для следующего шага.
Первый шаг это сборка ASP.NET Core:
4. (try to skip this and gotobuild_aspnetcore.sh
)build_installer_without_aspnet.sh
Дальше происходит как раз подкладывание бинарной сборки (обратите внимание что тут подкладывается 6й дотнет, хотя сборка идет 7го:
5. (try to skip this and gotobuild_aspnetcore.sh
) runtar zxfv ../../installer/artifacts/packages/Release/Shipping/dotnet-sdk-6.0.101-freebsd-x64.tar.gz
insideaspnetcore/.dotnet
to extract newly created SDK
Следующий шаг — сборка ASP.NET Core на 7м дотнете:
6. ./build_aspnetcore.sh
- as for now, this one need v7 SDK - grab one and do
Дальше запускаем «Fake .NET Core Installer for FreeBsd»:
7. ./bsd_dotnet_install.sh sdk7.tgz aspnetcore/
#!/bin/sh # Fake .NET Core Installer for FreeBsd ;) # $1 - SDK BIN for FreeBSD # $2 - dest dir echo Extracting .NET Core SDK into $2... mkdir -p $2/.dotnet tar zxf $1 --directory $2/.dotnet echo 'exit 0' > $2/.dotnet/dotnet-install.sh
Идея думаю понятна — банальная распаковка сборки из предыдущего шага в нужное место.
Дальше запускается сборка дистрибьютива .NET SDK:
8. ./build_installer.sh
- this one also need v7 SDK - do the same as above. Add-v d
inside build script if it will fail, check the logs (maybe download some zips by hand, as this is common fail)
#!/bin/csh if (`uname -m` == "arm64") then setenv ARCH arm64 else setenv ARCH x64 endif mkdir -p installer/artifacts/obj/redist/Release/downloads/ cp runtime/artifacts/packages/Release/Shipping/dotnet-runtime-*-freebsd-$ARCH.tar.gz installer/artifacts/obj/redist/Release/downloads/ cp aspnetcore/artifacts/installers/Release/aspnetcore-runtime-* installer/artifacts/obj/redist/Release/downloads/ cp sdk/artifacts/packages/Release/NonShipping/dotnet-toolset-internal-*.zip installer/artifacts/obj/redist/Release/downloads/ setenv TAG `cat installer.tag` installer/build.sh -c Release -ci -pack --runtime-id freebsd-$ARCH /p:OSName=freebsd /p:OfficialBuildId=`./common.sh $TAG` /p:IncludeAspNetCoreRuntime=true
Тут происходит точно такое же подкладывание готовых артефактов и запуск сборки уже дистрибьютива.
Наконец, в случае успеха вот тут будет финальная сборка:
9. Get and use installer/artifacts/packages/Release/Shipping/dotnet-sdk-*-freebsd-x64.tar.gz
Можно сравнить с тем что выкладывается в раздел релизов:
https://github.com/sec/dotnet-core-freebsd-source-build/releases
Дополнительные шаги
Очистка сборки для освобождения места:
1. clean.sh
if you want to save disk space after use
Упаковать все результаты сборки в один архив:
2. gather_output.sh
to tar artifacts into one big file, for future use (doesn't make sense to compress this, as it contains compressed files already)
Также можно использовать собранный SDK в качестве начального рантайма:
you can use output SDK as seed (instead of the one that was crosscompiled), move it here and rename to sdk.tgz
Будет максимально нативная версия .NET SDK для FreeBSD.
Отладка
Официальный WSL работает только под VSCode и только линуксовым. Альтернативный отладчик от Samsung я пока собрать под FreeBSD не смог, увы.
Но варианты все равно есть:
Unfortunately, this is going to be a very painful experience. There's no real command line debugger available for .NET Core.
However, CoreCLR developers use a plugin for lldb
(on *nix) that teaches lldb about a number of commands that it can use to help debug .NET code.
lldb /path/to/dotnet/dotnet plugin load /path/to/dotnet/shared/Microsoft.NETCore.App/*/libsosplugin.so b SystemNative_ReceiveMessage r run clrstack
Вот тут и тут лежат подробные инструкции, если кому действительно надо расставлять брейкпойнты в managed языке.
Но я например все же как-то справляюсь одним выводом в консоль — старая школа.
Среда разработки
Конечно же это VSCode, который достаточно давно есть в портах и успешно работает.
Если не интересно собирать из портов — можно поставить пакет:
pkg install vscode
Вот так выглядит проект на дотнете из среды разработки под FreeBSD:
Тестовый проект
Я взял для примера знаменитый шаблон AspBoilerplate и сгенерировал на нем тестовый проект.
Если кто вдруг не сталкивался — это большая такая болванка типичного корпоративного проекта, с EF и миграцией данных, с интерфейсом, с авторизацией и так далее.
Новая разработка корпоративного софта с нуля начинается с таких вот шаблонов, которые затем наполняются нужной вам логикой.
Дальше этот шаблон пришлось переделывать на компиляцию 7м дотнетом, использование Postgres вместо Microsoft SQL Server и еще по мелочи.
Полный исходный код выложил вот сюда.
Для работы вам нужен собранный либо скачанный .NET SDK 7 , распакованный и добавленный в переменную окружения PATH.
Еще будет нужно поставить свежую Node.js и yarn.
Нода есть в портах, yarn ставится как обычно:
npm i -g yarn
Сборка
Все достаточно просто и банально.
Скачиваем библиотеки, в дотнете это называется restore dependencies:
dotnet restore
dotnet build
В результате должны появиться папки bin и obj в подпапках модулей
Запуск
В готовом виде (production build) это будет один бинарник, со всеми ресурсами и настройками.
Для разработки бекэнд и фронтэнд запускаются отдельно, на фронте включен hotswap — автоматическая пересборка и обновление SPA в браузере при правках исходного кода.
Запуск бекэнда
Бекэнд запускается из проекта TestApp.Web.Host:
dotnet run
Если запуск будет успешен - сервер поднимется на порту 44311
Запуск фронтэнда
Фронт также в проекте TestApp.Web.Host, запускается через yarn:
yarn start
Работа с базой данных
Я использую DB Visualizer, который даже есть в портах.
К сожалению, даже из портов ставится «бинарная» (на Java) версия, поскольку исходники не открыты. Не то чтобы это была какой-то проблемой, но тем не менее.
Еще можно использовать Aqua Data Studio , он отлично работает на любых BSD и легко находится на торрентах.
Настройка подключения к базе данных находится в appsettings.json:
"ConnectionStrings": { "Default": "User ID=postgres;Password=qwerty;Host=127.0.0.1;Port=5432;Database=test2;Pooling=true;" },
Таких файла два — один будет в проект TestApp.Web.Host, другой в TestApp.Migrator. Настроить подключение нужно будет в обоих.
Перед первым запуском необходимо запустить миграцию, для того чтобы автоматически создались таблицы в базе и наполнились тестовыми данными.
Заходим в каталог с проектом TestApp.Migrator и запускаем:
dotnet run update-database
Результат
После успешного запуска, открываете в браузере http://localhost:4200
admin / 123qwe
Новых пользователей можно задать в самой системе:
Дашборд на самом деле практически пустой, данные тестовые:
Этот тестовый проект сразу идет как multi-tenant, те с поддержкой разделения между пользовательскими данными.
Управление этими самыми тенантами выглядит вот так:
Выводы
Все это было написано лишь для исследования текущего состояния дел с дотнетом вне экосистемы Windows, которое мне показалось очень даже неплохим.
Напомню что прошло лишь 4 года с момента выкладывания исходников .NET в публичный доступ, что для такого проекта очень небольшой срок.
Если у вас есть legacy-проект на дотнете и вы хотите отказаться от Windows-платформы, думаю стоит задуматься.
Могу помочь с оценкой и возможными сроками такого переезда — пишите.