commit -m "better"
2.96K subscribers
872 photos
106 videos
3 files
2.08K links
just random thoughts
Download Telegram
Новости бутстрапа.

Я собрал opengl, во всех его ипостасях(egl, gles[1, 2, 3], etc). Про то, что у меня теперь драйвер видеокарты влинкован в Sway, я расскажу отдельно. А сегодня - про Mesa(https://www.mesa3d.org/). Mesa - это:

1) Реализация различных API(OpenGL, Vulkan, D3D(да, да, он там есть, нативный, но разработчики это скрывают, потому что не хотят, чтобы им пользовался кто-то, кроме Wine))
2) OSS ускоренные драйвера(AMD, Intel, Noveau, Mali, etc)

Вы знаете, я был очень приятно удивлен. Я никогда не видел такой хорошей кодовой базы на C. Чистый, понятный, код, разумное разделение на слои и разделение ответственности. Если вы хотите(хз, правда, зачем) научиться, как хорошо писать на С - почитайте кодовую базу Mesa.

Я почитал(зачем? проект загружает драйвера в виде .so, это требует некой творческой доработки для статической линковки), и имею вам сказать следующее:

1) Что-то я разуверился, что #asahi linux достигнет какого-то разумного прогресса в плане ускоренного десктопа. Все очень просто. Код для asahi в Mesa - это 200 килобайт, драйвер и компилятор шейдеров. Код развитого драйвера в #Mesa - 5 и более мегабайт. Я не верю в чудо, что разработчики asahi смогли уместить такую сложную штуку, как Apple GPU, в 200К. Я не видел там реализации по существу, все это больше похоже на какой-то boilerplate. :(

2) Благодаря Mesa появилась система сборки Meson(https://mesonbuild.com/). На ней основана сборка практически всего графического стека Linux. И это очень хорошая(не побоюсь сказать, что лучшая OSS) система сборки:

* Мало внешних зависимостей. Фактически, только Python. Python собрать проще и быстрее, чем CMake.
* Сборочные файлы основаны на кастрированном подмножестве Python, чтобы не жестить(https://mesonbuild.com/GuiTutorial.html). Skylark украл эту идею из Meson. Сборочные файлы по большей части декларативные, но немного императивщины дозволено - все же, OSS, много настроек, вариабельность.
* Действительно хорошая поддержка тулзов - Meson знает про clang, lld, и умеет с ними обращаться.
* Сборочные скрипты очень чистые и понятные - без жести, все очень по существу вопроса.
* Хорошо поддерживает вариабельность сборки(настройки). Настройки лежат в отдельном файле, их можно узнать, не читая сборочные скрипты. Это реально удобно. В gnu #autohell для этого нужно запустить configure, и не факт, что он выдаст все настройки. В CMake это IMHO вообще невозможно - любой -DXXX - это настройка, выгрепать их все - невозможно.
* Поддержка кросс-компиляции.
* Идеальный custom_command - {'inputs': [...], 'outputs': [...], 'descr': '...', cmd: ['A', 'B', 'C']}. Кто занимается системами сборки, тот поймет. Я аж прослезился.
* Не мешает, и даже помогает, задаче герметичной сборки. Это редкость.
* Очень быстрый configure stage.
* Не совсем про Meson, но. Оно поддерживает coverity из коробки. И werror из коробки. Это многое говорит о проектах, которые ее используют.

Подобное есть в Bazel, но он очень тяжелый, и зависит от Java.

В общем, я свои проекты портирую на #Meson, и вам желаю того же. Хорошая, годная, вещь.

Ну и вот еще - https://gms.tf/the-rise-of-meson.html Meson очень быстро набирает популярность!
#mesa, свет моей жизни, искры на кончиках пальцев. Грех мой, любовь моя. Me-sa.

Для ее сборки была разработана ныне очень популярная система сборки - #meson, и, на самом деле, это очень печально, потому что разработчики Mesa слишком хорошо знают meson, и пользуются любыми всратыми ее фичами.

Фактичеси, Mesa состоит из 2 частей - загрузчика плагинов, который поверх интерфейса плагина реализует всякие там state tracker типа opengl, vulkan, и, собственно, плагинов.

Так как авторы Mesa слишком хорошо знают meson, то сборка Mesa выглядит примерно так:

* собирается K объектных файлов
* из них собирается N архивов, причем, что важно, есть пересечения - один и тот же .o может попасть в несколько архивов
* из этих K + N артефактов собирается M конечных .so. Тоже с произвольным пересечением по .a/.o файлам!

Получается, что каждый конечный артефакт содержит произвольное подмножество исходников.

Пока это все собирается в .so, со скрытыми символами, это не представляет собой проблемы, кроме увеличения объема конечного кода и времени компиляции(потому что некоторые исходники таки переcобираются по нескольку раз).

Если же линковать статически, то мы получаем понятные проблемы - повторяющиеся символы при линковке.

Когда я впервые собирал mesa, я решил это очень странным способом - я свалил все конечные артефакты в одно корыто, и сделал из этого одну мега-библиотеку, которая заменила все конечные артефакты.

В целом, это работает неплохо, кроме одного очень важного сценария - мне таки нужно попилить этот гигантский артефакт на 2 части - loader, и драйвера, и сделать из них 2 физически разные зависимости.

Это нужно, чтобы поднять зависимость от драйверов до конечных программ, а все промежуточные библиотеки должны зависеть только от loader. Это важное требование, если мы не хотим пересобирать все дерево библиотек, нужных для сборки конечных GUI программ, для каждого набора драйверов, и, фактически, для нормального бинарного кеша сборки.

Я подходил к задаче распила раз 5:

* попилить по .o конечный артефакт руками. Ломается о комбинаторный взрыв различных способов собрать драйвера.
* сделать так, чтобы все собиралось в несколько полностью независимых .a файлов - все упиралось в дефекты сборочный системы meson и сособенности сборочных файлов mesa - тут я пытался руками править сборочные скрипты mesa(не масштабируется на апдейты), и саму meson(тут я был ближе всего к победе, но не срослось)

Короче, пока я эту проблему решил так:

* написал generic процедуру вычитания одного .a из другого. По именам .o файлов это сделать нельзя, по причинам что я уже описал выше, поэтому все делается посимвольно. https://github.com/pg83/mix/blob/main/pkgs/lib/mesa/t/sep/substr.py

* последовательным вычитанием привел в порядок загрузчик и библиотеку с драйверами. https://github.com/pg83/mix/blob/main/pkgs/lib/mesa/t/sep/mix.sh#L29

Это гораздо эстетичнее, чем предыдущая идея с мешком обжей, и работает достаточно хорошо(по крайней мере, решает исходную задачу).
👏13
Субботний rant про невменяемые системы сборки.

Нет ни одной OSS системы сборки, которую я бы мог назвать "бескомпромиссно хорошей".

Мало кто из OSS сборок знает, что такое "чистые билды", что такое content addressable storage.

#bazel знает, но написан на java.

#meson не знает, но зато в нем приятные скрипты для описания конфигурации.

Дай, думаю, посмотрю на #premake. https://premake.github.io/

Бугага, в качестве graph execution engine он предлагает gnu makefile, и даже не предлагает ninja.

И, самая мякотка, https://github.com/SpartanJ/efsw/blob/1.3.0/premake5.lua#L121, он позволяет сборочному скрипту контролировать, куда premake положит Makefile.

Вот, реально, сгенеренный Makefile можно положить в любое место, которое придет в голову мейнтейнеру пакета, и переопределить снаружи это невозможно.

Это вообще какое неуважение к тем, кто этот код собирает?

Для запуска Makefile так-то нужно знать, где он лежит.

Набор типовых конфигураций тоже не стандартизован - https://github.com/SpartanJ/efsw/blob/1.3.0/premake5.lua#L123, install таргетов я не нашел, да и вообще, все это выглядит как зумерская поделка.
👍3😢2😐2
Когда проект, по сути, завершен, и программисту в нем нечего делать, он начинает вылизывать в проекте что-нибудь. #ball_lick

Вот, есть такая сборочная система - #meson. Она, по сути, написана. Там есть все, что может пожелать любой sane сборочный скрипт, и даже много чего лишнего.

Но проект же должен развиваться, нужно катить новые релизы.

https://mesonbuild.com/Release-notes-for-1-1-0.html

Давайте я просто оставлю несколько цитат, про то, какие же проблемы решает проект в своем развитии:

"sudo meson install now drops privileges when rebuilding targets"

Нет, это не помощь пользователю, это очередная боль мейнтейнера, который будет вынужден помнить про очередную неочевидную "магию".

Инструменты должны быть простыми, и должны fail fast, вместо того, чтобы "решить проблему любым доступным образом". Потому что "следующий какой-то доступный способ" сделает чуть-чуть иначе, чем основной.

"meson install now supports user-preferred root elevation tools
Previously, when installing a project, if any files could not be installed due to insufficient permissions the install process was automatically re-run using polkit. Now it prompts to ask whether that is desirable, and checks for CLI-based tools such as sudo or opendoas or $MESON_ROOT_CMD, first"

Вы понимаете, сколько в этом говне прикопано "магии", которая, в зависимости от доступного окружения, будет делать разные действия при выполнении одних и тех же команд? Моб твою ять, поведение сборочной системы зависит от того, есть на машине polkit, или нет.

Ну а еще, конечно, любой "promtps" в batch cli по сборке и установке - это харам.

Я бы с радостью заморозил сейчас версию meson у себя, но ведь всегда найдется какой-нить красноглазый студент, решивший заюзать новую клевую фичу именно в своем сборочном файле.
🔥112🥱2😁1🐳1💯1
Хорошо иметь много пользователей!

Потому что у них что-то не работает, и это заставляет нас делать системы лучше и лучше.

Вот, например, мои пользователи часто жаловались на негерметичность первоначальной стадии #bootstrap - если в систему были установлены те или иные библиотеки, то системы сборки часто их находили в системе, вместо моих. С моментальной ошибкой сборки, потому что они несовместимы по ABI.

Я достаточно неплохо выкосил это в autohell скриптах - https://github.com/pg83/ix/blob/main/pkgs/die/c/autohell.sh#L38-L46

Недавно выкосил в #meson, через обертку над clang, которая убирает /usr из search path - https://github.com/pg83/ix/blob/main/pkgs/bld/wrapcc/kuroko/wrapcc.krk#L118

Вот, настала очередь #cmake. Он принудительно добавляет эти пути в пути для поиска библиотек вот тут - https://github.com/Kitware/CMake/blob/master/Modules/Platform/UnixPaths.cmake#L33

Сначала я изящно занулял этот файл при установке cmake, но потом нашел более "изящное" решение. Этот файл имеет include guard, чтобы не включаться повторно - https://github.com/Kitware/CMake/blob/master/Modules/Platform/UnixPaths.cmake#L10

Ну я и обманул cmake, чтобы он думал, что уже включил этот файл - https://github.com/pg83/ix/blob/main/pkgs/die/c/cmake.sh#L66-L67

А зачем там UNIX=1, спросит дотошный читатель?

Ну потому что выставить в cmake флаг про то, что мы собираем под unix, конечно, лучше всего именно в файле, который настраивает юниксовые пути поиска библиотек - https://github.com/Kitware/CMake/blob/master/Modules/Platform/UnixPaths.cmake#L18

(Что?? Да!!)

В целом, кажется, что я обкостылил все более-менее популярные системы сборки, чтобы они не лезли в систему при конфигурировании. Лучше бы, конечно, запилить контейнеризацию сборки, но так я не узнаю о проблемах, которые меня ждут не в Linux.
🔥97🆒2👍1
https://nibblestew.blogspot.com/2023/10/the-road-to-hell-is-paved-with-good.html

Странный текст про модули в С++, от автора #meson.

Я ожидал чего-то горячего, но весь текст, в основном, про то, какие gcc/clang негодяи, как им нужно правильно парсить command line, и как разбирать файлы.

Я бы сказал, что у автора зашкалило ЧСВ, и он, на голубом глазу, рассказывает, как clang/gcc должны выстраивать интерфейсы, чтобы их удобно можно было звать в #ninja.

Ну или он просто не видит дальше своего носа, и не понимает, что модель парсинга зависимостей у meson/ninja - ущербна (*), и что не надо ей потакать.

(*): в основном, потому, что она создана для решения задачи, которую решать не нужно, а именно - чтобы генератор сборочного графа мог жить отдельно от выполнителя этого графа (тут появляется сложная зависимость между этими инструментами, так как зависимости для пересборки появляются не на configure стадии, а в процессе первого выполнения графа).
🤔6👍3🔥3😁1
Будни #bootstrap

Обновился #dbus, со сменой сборки с autohell на #meson.

Обновился и обновился, но вот в dbus.pc теперь есть вот такое:

Name: dbus
Description: Free desktop message bus
Version: 1.16.0
Libs: -L${libdir} -ldbus-1 -pthread
Cflags: -I${includedir}/dbus-1.0 \
-pthread \
-I${libdir}/dbus-1.0/include


Тут важно обратить внимание на -pthread, раньше было лучше его не было.

Все бы ничего, но теперь сборки проектов с meson, которые зависят от dbus, падают вот так вот:

In file included from <built-in>:413:
<command line>:7:9: error: \
macro name must be an identifier
7 | #define -pthread 1


Да, meson вызвал pkg-config, получил хрень в виде -pthread, и сделал из нее -D-pthread=1.

Как я это починил?

Как обычно: 7 бед - 3 раза sed:

https://github.com/pg83/ix/blob/main/pkgs/lib/dbus/ix.sh#L5-L8

Морали не будет 😐
😁83🔥32🐳1
https://github.com/mesonbuild/meson/issues/5024

Мучительный тред про добавление в #meson C++ modules (все еще Open).

Основная решаемая задача - надо как-то распарсить исходники, чтобы понять, в каком они модуле. Но это сложно:

#if __has_feature(frobnitz)
import frobnitz;
#else
import fallback.frobnitz;
#endif


И вторая проблема - а как и когда понять модуль сгенеренного С++ исходника.

Тред - просто сплошная боль и мучения, из серии "я сходил в clang, и они хотят вот это вот сделать так, а msvc не хочет так, а у gcc вообще свой путь".

Кажется, что они пока так и не договорились, какие расширения должны быть у исходников с модулями:

"we need a way to determine whether a C++ source should be treated as a module. VS and Clang use (different) specific extensions, gcc does not"

Понимания о том, когда парсить, как парсить, как на основе информации от компилятора обновлять dep graph, у них тоже пока нет.
😁9😢7🤡6🐳3🌚3🙉1💊1
Будни #bootstrap

https://www.phoronix.com/news/Meson-1.8-Released

Вышел новый #meson, вышел и вышел.

Давно хотелось написать, что #meson - это oss система сборки, от который у меня постоянный butthurt.

Ее автор - классический пример "есть только два мнения по любому предмету - мое, и неправильное".

С каждым новым релизом meson он постоянно ломает какие-то мои use case.

Например, раньше у него был fallback при поиске кодогенераторов - если не получалось найти через pkg-config, то он просто искал в PATH.

Мне это было очень удобно, потому что, когда мне нужно собрать программу с glib, то там есть две части - неопсредственно libglib.a, и, скажем, какой-нить кодоген, типа glib-mkenums (не суть, что это такое).

И эти две части должны быть собраны под разные платформы, в случае кросс-компиляции.

И получается так, что в одном glib.pc должно быть описание как таргетной части (пути к libglib.a), так и хостовой части, а так собрать этот пакет невозможно в принципе.

Ну вот я просто раньше убирал пути до этих программ из glib.pc, и пользовался fallback, про который написал выше.

Однажды это сломалось.

Чтобы оно "как-то" заработало, пришлось в glib.pc нагенерить записей вида:

...
glib-mkenums=glib-mkenums
...

Тем самым, meson получает нужную ему запись, и дальше просто зовет ее, находя в PATH.

Я в курсе, что в meson можно иметь разный PKG_CONFIG_PATH для host и target графов, но это не очень хорошо мне модельно подходит, ну и так никто, кроме meson, не делает.
🤔9👍53🆒2
commit -m "better"
Поэтому получается так, что дистростроители прямо очень сильно не любят Rust:
Продолжаем тему "почему дистростроители не любят Rust"

https://gitlab.archlinux.org/archlinux/packaging/packages/mesa/-/blob/main/PKGBUILD?ref_type=heads#L103-144

Вот так, например, приходится приседать в Arch, чтобы доставить до сраной #meson сборки #mesa (которая, сама по себе, сошла с ума, и решила запилить сборку Rust без cargo, и его механизмов вендоринга) зависимости для компилятора шейдеров #NVK (драйвер для Nvidia vulkan).

Особенно автору всего этого добра доставляет копипастить версии руками, ага.

Мне еще это только предстоит, а я уже ненавижу этот процесс тихой ненавистью.
😁9🤡8🐳5😭4👍3💯2👀1🦄1