commit -m "better"
2.96K subscribers
868 photos
105 videos
3 files
2.07K links
just random thoughts
Download Telegram
https://twitter.com/nicuveo/status/1469963644775682049

Красивое, просто показываю.

———
https://www.phoronix.com/scan.php?page=article&item=bsd-linux-eo2021&num=4

Не люблю perf тесты, которые делаю не сам. Вот zstd на FreeBSD - это что? Так же не бывает, что cpu intensive задача на разных OS в 10 раз отличалась.

———
https://github.com/NixOS/nixpkgs/issues/136926 - сломана кросс-сборка #Mesa.

https://habr.com/ru/post/591979/ - про основы кросс-компиляции в разных OSS системах сборки. Спойлер - Meson OK, #autohell и CMake - жесть.

Представление о 6 действиях, как собрать cross-gcc https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/

Про CMake скажу отдельно - у него разных способов контролировать пути поиска тех или иных артефактов штук 10, разных, странных - поштырьте по ссылкам(https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_PREFIX_PATH.html#cmake-system-prefix-path).

Насколько я понимаю, для Mix это нормальное дело. Я строю Nix так, что он всегда кросс-компилирует, даже когда host == target. Это приводит к следующему:

1) Собрать программу полностью в debug/asan/msan/etc - плевое дело. Пользователи интерпрайзных систем сборки к этому привыкли, для OSS это внове.

2) Несколько необычный режим сборки промежуточных артефактов - каждый таргет может быть собран в 3 режимах - lib, bin, data. Нужно это потому, что разные артефакты нужны под host и target платформы, а еще библиотека может зависеть сама от себя, но от своих данных(это достаточно странно, но больше никак не сделать возможность удаления .a файлов, оставляя данные для них(кстати, вот как раз с динамической сборкой это проще - никого не удивляет, что .so живет рядом с share/)).

https://github.com/pg83/mix/blob/main/pkgs/lib/wayland/protocols/mix.sh - вот прекрасный пример, программа может зависеть от библиотеки lib/wayland, от бинарников из lib/wayland, и во время работы ей тоже нужны бинарники из lib/wayland. Если посчитать, то это 3 разных таргета в случае кросс-сборки. В случае host == target часть можно пооптимизировать, но я пока не занимался.
#cross #cmake В CMake нет кросс-компиляции. Видимо, ее было сложно добавить постфактум(ну, не знаю, не глобальную переменную с набором environment завести, а сделать два экземпляра класса - для target, и для host). Вообще, добавить кросс-компиляцию в систему, которая для этого не дизайнилась изначально, сложно.

Ну и что же делать? Вот, вместо того, чтобы таки запилить кросс-компиляцию, товарищи запилили страничку, на которой, на голубом глазу, утверждают, что кросс-компиляция в CMake есть!

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html

Конечно есть! Только вам надо 1 раз прогнать cmake, собрать все провалившиеся вызовы TRY_RUN, записать их предполагаемые результаты в файлик, и прогнать это говно еще раз!

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#using-compile-checks

Вдумчивый читатель спросит - а как в сборке запустить собранный host бинарь? А точно так же! Собираешь бинарь отдельно(твои проблемы, как), и подсовываешь его в cmake!

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#running-executables-built-in-the-project

Так же несколько раз по тексту эти господа прозрачно намекают на wine, qemu, и прочие достижения прогресса, чтобы TRY_RUN таки работал.

Я подумал, что это какая-то outdated хрень, но вот, пжалста, инструкции по кросс-сборке #LLVM:

https://bcain-llvm.readthedocs.io/projects/llvm/en/latest/HowToCrossCompileLLVM

-DLLVM_TABLEGEN=<path-to-host-bin>/llvm-tblgen
-DCLANG_TABLEGEN=<path-to-host-bin>/clang-tblgen

Удобные переменные, чтобы передать путь к заранее предсобранным бинарничкам, чтобы CMake не перенапрягся. Вообще, удивительно, что у программы, которая облегчила кросс-компиляцию в 100500 раз, такая отстойная кросс-компилирующая сборка.

"Cross-compiling is fully supported by CMake, ranging from cross-compiling from Linux to Windows; cross-compiling for supercomputers, through to cross-compiling for small embedded devices without an operating system (OS)."

Феерические долбоебы.

———
Ну и вот вам еще душераздирающих историй. У меня тут свалилась сборка glslang, компилятора шейдеров от Khronos Group. Эти негодяи попросту поменяли файл по релизной ссылке:

Было:

https://github.com/KhronosGroup/glslang/
archive/refs/tags/master-tot.tar.gz
f51c4b12ac0c8f9dee2067dc207a4fca

Стало:

md5sum master-tot.tar.gz 
71c7f379d1d73eebdce3fd05c7727af4
master-tot.tar.gz

Не, по ссылке(и по предыдущему опыту взаимодействия) было понятно, что ссылка не жилец, но все же. Кстати, к тому, что по github commit id данные часто приезжают с другим md5, я уже давно привык, это какое-то общее место.
Собирал тут boost. Люди, которые меня хорошо знают, удивятся - я же известный boost hater. #gold

Не себе, для дела. Boost требуется для сборки Inkscape, а Inkscape нужен для рендера иконок в теме Adwaita(это, кстати, та еще кольцевая зависимость, потому что иконки требуются для gtk, а gtk нужен для сборки inkscape, ну да ладно). #svg

Для этого пришлось бутстрепнуть B2, оно же бывший bjam. Удивительно, но в ней нет поддержки кросс-компиляции, хотя, конечно, авторы утверждают обратное.

Давайте я поясню, что я имею в виду, когда говорю, что система сборки поддерживает кросс компиляцию: #cross #cmake

* Возможность указать компилятор и cflags - это НЕ поддержка кросс-компиляции, потому что без "раздвоения" сборочного графа это приводит к невозможности собирать проекты, которым требуется строить host тулзы во время сборки(если host != target). cmake, bjam - отличные представители.

* Кросс-компиляция начального уровня - когда сборочная система знает про HOSTCC, TARGETCC, и позволяет описать разные части сборочного графа используя разные *CC. Например, make, ninja(без надстроек над ними), autoconf.

* Кросс-компиляция второго уровня - когда можно для таргета сборки указать, host он, или target, а далее сборочная система сама правильно подставит HOSTCC, TARGETCC. meson - прекрасный представитель.

* "Высшая" кросс-компиляция - когда любым таргетом можно оперировать как в контексте host, так и target. Все будет сделано прозрачно для пользователя. ya, bazel(buck? честно, не знаю так глубоко). Кстати, Mix тоже(с поправкой на то, что не все таргеты в OSS принципиально можно кросс-компилировать).

Теперь к B2/BJAM:

* https://www.bfgroup.xyz/b2/manual/release/index.html#bbv2.tasks.crosscompile - нет разделения на target/host вообще.

* https://github.com/bfgroup/b2/blob/main/bootstrap.sh#L26 - позорище, facepalm, запуск свежесобранной target тулзы для инсталляции ея же.
👍1
Вернусь к вчерашней ссылке про static vs. dynamic.

https://lobste.rs/s/adr60v/single_binary_executable_packages#c_xoxpbs

1) Там подняли интересные темы про статическую линковку в Rust и Go.

2) СЯУ, что в Rust нет кросс-компиляции. Ну, точнее, есть, по модели CMake(#cross #cmake на сайте написано, что есть, а cargo таки оперирует одним графом). Я это еще заприметил, когда только начал им пользоваться, но у меня не хватало уверенности, чтобы об этом сказать.

———
https://codeberg.org/dnkl/fuzzel/pulls/53

Автор #foot классный. Я как-то писал про проблему первого кадра в sway, так вот, коллега тоже обратил на нее внимание, и даже предложил решение.

———
https://rtpg.co/2022/02/13/your-own-sudo.html

Товарищи, если кто-то в вашей окружности решит написать sudo на python, пристрелите его.

* питон загружает много модулей
* авторам so-шек обычно нет выхода, кроме как заполучать параметры для себя через env
* man secure_getenv, и связанные с загрузкой so #suid-ными бинарями CVE.

———
https://gankra.github.io/blah/text-hates-you/
https://rastertragedy.com/RTRCh0.htm

Классные тексты про text rendering и text shaping.

Вообще, хочу сказать, что то, что эмодзи решили погрузить в шрифты - это, конечно, леденящий душу пиздец и layer violation, который до сих пор аукается. Почитайте, как разные люди решают задачу рендеринга эмодзи, это прекрасно.

Кстати, про шрифты - связка Inter + IBM Plex мне нравится даже больше, чем набор шрифтов в macOS.
Ненавижу #cmake.

Это самая худшая система сборки ever.

* Она не умеет в кросс-компиляцию, писал об этом неоднократно #cross

* Фактически, cmake - это интерпретируемый язык с смесью синтаксиса qbasic и cobol, на которой можно как-то написать кривую и косую систему сборки, потому что язык turing complete.

Сложность скриптов на cmake ограничивается только всратостью самого языка, и ничем более.

У разработчиков QT, видимо, было очень много времени на то, чтобы разобраться с cmake, и сделать все самым ненатуральным возможным образом.

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

https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html, вот она

Ее поведение можно переопределить 10 разными способами, например

https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_PREFIX_PATH.html#variable:CMAKE_SYSTEM_PREFIX_PATH

https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_IGNORE_PATH.html#variable:CMAKE_SYSTEM_IGNORE_PATH

find_package() в cmake содержит в себе 10 настроек для этих 10 переменных, https://cmake.org/cmake/help/latest/command/find_package.html#command:find_package - искать по "NO_CMAKE_".

Каждая из которых каким-то нетривиально-всратым образом меняет семантику find_package.

Долбоебы из QT решили, что и этого им мало:

* они переопределили поведение по умолчанию, чтобы либы из QT не искались в CMAKE_PREFIX_PATH

* Они завели себе переменную QT_ADDITIONAL_PACKAGES_PREFIX_PATH, на замену CMAKE_PREFIX_PATH

* Они завели себе переменную, выключенную по умолчанию, которая возвращает поведение к "нормальному"(насколько это возможно в cmake вообще) - QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES

Я НЕНАВИЖУ, когда у программистов заканчивается работа, и они начинают маяться хуйтой.

———
Хозяйке на заметку.

Я потихоньку профилирую свой Linux, ищу, что и где плохо лежит происходит не так, как мне нравится, и починяю.

Вот, возможно, пригодится.

#foot по умолчанию запускает ncpu threads для параллельного рендеринга.

Но мы-то знаем, что дисперсия времен ответов от большого числа источников(иными словами, барьер на синхронизацию событий "мы все сделали!") штука опасная, и может быть большой. Например, потому что #scheduler в Linux - говно. Тем более, если запускать по 16 render threads. Ну и памяти под стеки они жрут прилично.

TL;DR - если убрать вообще все worker threads, и оставить только main, скорость рендеринга не меняется никак(проверяем с помощью cat на большой файл, с ansi escape codes)

Тащемта, понятно, откуда там взялся многопоток - автор foot, очевидно, испытывает комплекс перед #alacritty, и ему нужно были эти эфемерные 10% ради собственного спокойствия.

А вам я рекомендую ставить workers=0 в конфиге, работает так же, памяти жрет меньше.
🔥10👍3😁2🤔1
Обновлял libwebp, минорная версия.

Судя по всему, webp начала зависеть от библиотеки с тредами, или эту зависимость просто явно прописали, или случилась какая-то дичь, это же #cmake.

Это не то чтобы очень важно, но в экспортных cmake файлах появилась вот такая запись:

"set_target_properties(WebP::webp PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "Threads::Threads"
)"

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

"- Found OpenSSL: /ix/store/3YPdIxQVL9oMNgXL-lib-openssl-3/lib/libcrypto.a (found version "3.0.3")
-- Found WrapOpenSSLHeaders: /ix/store/3YPdIxQVL9oMNgXL-lib-openssl-3/include (found version "3.0.3")
CMake Error at /ix/store/BSYeU5Bd9S8IYSLe-lib-qt-6-base/lib/cmake/Qt6/QtPublicTargetHelpers.cmake:257 (set_property):
Attempt to promote imported target "Threads::Threads" to global scope (by
setting IMPORTED_GLOBAL) which is not built in this directory.
Call Stack (most recent call first):
/ix/store/BSYeU5Bd9S8IYSLe-lib-qt-6-base/lib/cmake/Qt6/QtPublicWalkLibsHelpers.cmake:252 (__qt_internal_promote_target_to_global)
/ix/store/BSYeU5Bd9S8IYSLe-lib-qt-6-base/lib/cmake/Qt6/QtPublicWalkLibsHelpers.cmake:225 (__qt_internal_walk_libs)
/ix/store/BSYeU5Bd9S8IYSLe-lib-qt-6-base/lib/cmake/Qt6/QtFindPackageHelpers.cmake:12 (__qt_internal_walk_libs)
/ix/store/BSYeU5Bd9S8IYSLe-lib-qt-6-base/lib/cmake/Qt6/QtFindPackageHelpers.cmake:181 (qt_find_package_promote_targets_to_global_scope)
src/imageformats/configure.cmake:19 (qt_find_package)
src/plugins/imageformats/CMakeLists.txt:9 (include)"

cmake - это треш, угар, и содомия, а сборочные скрипты QT для cmake - это треш в квадрате.

Что значит это сообщение об ошибке, я не понял, починил по рабоче-крестьянски: https://git.sr.ht/~pg/ix/tree/main/item/pkgs/lib/webp/ix.sh#L17-19

Кстати, с cmake сборка webp и так не сильно дружила, экспортные файлы она клала куда-то не туда: https://git.sr.ht/~pg/ix/tree/main/item/pkgs/lib/webp/ix.sh#L14-16
🔥5🌭4🌚1
https://www.opennet.ru/opennews/art.shtml?num=57847 #ball_lick

Тут вот пишут, что вышла новая версия #qt, и я хочу сказать, что сборка QT, после ее перехода на cmake - это леденящий душу пиздец.

Связано это с:

* #cmake сам по себе говно, в нем нет кросс-компиляции. А в QT есть, поэтому им пришлось написать соответствующий слой поверх cmake самим. #cross

* QT решили задачу по переходу, в том числе, оттранслировав большое число проектных файлов автоматом. Для этого им пришлось наговнякать большой runtime поверх макросов cmake, который имплементировал нужную им модель, в которую они и погрузили свои сборочные файлы. https://github.com/qt/qtwayland/blob/dev/src/qtwaylandscanner/CMakeLists.txt#L4

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

К чему этот rant?

https://github.com/pg83/ix/blob/main/pkgs/die/c/qt.sh#L16 - мне пришлось добавить пятый флажок в набор флажков, отвечающих за то, что нужно собрать тулзы, и, желательно, только их.

Реально, там полный набор - от "ну пожалуйста", до "мамой клянусь, они мне точно нужны".

А еще они зачем-то добавили факт о том, что пакет собран кросс-компиляцией, в метаинформацию этого пакета. https://github.com/pg83/ix/blob/main/pkgs/lib/qt/6/base/ix.sh#L45 (я ее вырезал, конечно)

Это вообще какая-то дичь, которую я для себя никак не могу объяснить:

* Их сборка начала ломаться, если этот флаг разный у разных пакетов. Схера ли? build tools могут быть собраны в режиме host == target, а либы - уже в режиме кросс-компиляции, это вполне валидный сценарий.

* А как же воспроизводимость? Пакет должен быть идентичный, неважно, в каком окружении он собран. А тут налицо факт, что пакеты, собранные кросс-компиляцией, будут отличаться.
🤡8👍3🍌2😱1
Будни #bootstrap, #bootstrap_science

Вчера я рассказал про сборку #qt, конкретно, про:

* набор (неортогональных) флагов, которые чуть по разному решают в qt задачу принудительной сборки бинарников в host-target режиме

* про то, что они написали поверх #cmake свой слой кросс-компиляции

* про то, что их система сборки сравнима с "Войной и Миром" Толстого(как по актуальному размеру, так и по уровню графомании)

Сегодня про то, как оно сломалось при обновлении до qt 6.4, и как я "ловко" и "изящно" это обошел.

Есть такой проект - https://github.com/qt/qtdeclarative, и он жестко отказался собираться после обновления. С ошибками конфигурации где-то в недрах своих cmake хелперов, без внятной диагностики(это, кстати, отдельная боль в cmake).

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

С симптомом круговой зависимости, что, мол, какой-то файл зависит от цели, которой нужен какой-то собранный бинарник(с говорящим названием qmltoolregistrar), который зависит от этого же файла. Скажем, вот тут - https://github.com/qt/qtdeclarative/blob/dev/src/qml/Qt6QmlMacros.cmake#L2494

Я копался в этом часа 3, но починить так и не смог, из-за размеров этой махины.

В итоге дорожку к результату я "протоптал" так - если там нет актуальной круговой зависимости, и она только в шизанутой системе сборки от qt, то давайте ее "разорвем" - соберем проект по частям.

Как это было сделано?

* Удаляем из сборочных файлов круговую зависимость. https://github.com/pg83/ix/blob/main/pkgs/bld/qt/6/tools/qml/1/ix.sh#L13 После этого получается битый makefile, но его достаточно, чтобы осуществить первые этапы сборки.

* https://github.com/pg83/ix/blob/main/pkgs/bld/qt/6/tools/qml/1/ix.sh#L4 - собираем все, что собирается этим битым makefile, и устанавливаем в качестве сборочного результата

* Повторяем эти шаги, постепенно увеличивая число собирающихся таргетов, и используя предыдущие результаты как host тулзы - https://github.com/pg83/ix/blob/main/pkgs/bld/qt/6/tools/qml/2/ix.sh#L14

Мне понадобилось 2 шага - https://github.com/pg83/ix/tree/main/pkgs/bld/qt/6/tools/qml, результат второго шага вполне достаточен, чтобы им собрать полноценный пакет - https://github.com/pg83/ix/blob/main/pkgs/bld/qt/6/tools/qml/ix.sh#L12.

Я не рассказал про всякие мелочи, типа ручного релоцирования из build в output директории получившихся cmake файлов, чтобы дальнейшие шаги сборки могли их подхватить - https://github.com/pg83/ix/blob/main/pkgs/bld/qt/6/tools/qml/1/ix.sh#L21

Звучит это все довольно страшно, но сборку эти 2 дополнительные стадии почти не замедлили, потому что в них собирается процентов 5 от всего набора исходников этого пакета.
😁5🤮5👏3❤‍🔥11👍1💩1🐳1🌚1🍌1
commit -m "better"
Ненавижу #cmake. Это самая худшая система сборки ever. * Она не умеет в кросс-компиляцию, писал об этом неоднократно #cross * Фактически, cmake - это интерпретируемый язык с смесью синтаксиса qbasic и cobol, на которой можно как-то написать кривую и косую…
Я несколько раз писал, что в #cmake нет кросс-компиляции.

До недавнего времени я знал одно исключение из этого правила - это сборочные файлы #qt, они там, по сути, написали на cmake самопальный слой кросс-компиляции, благо cmake turing complete, и грубой силой там можно написать все, что угодно.

Вот, коллеги показали второе исключение из этого правила - https://github.com/ClickHouse/ClickHouse/blob/master/contrib/protobuf-cmake/CMakeLists.txt#L252

Тут "очень изящно" вызывается рекурсивный cmake + make на прикопанную папочку с protoc во время configure этапа. И, к моменту поиска protoc в системе, он уже готов.

У меня, конечно, двойственное к этому отношение.

С одной стороны, коллеги свою задачу(воспроизводимая сборка на поддерживаемых платформах) решили.

С другой, понятно, что дистростроители с такого вешаются, когда нужно сделать де-#vendor.

С точки зрения upstream, конечно, сборки от дистрибутивов, после ручного де-#vendor, не являются воспроизводимыми, и, наверняка, их не поддерживают (по вполне понятным причинам).
🤔6👍4🔥2
https://www.kitware.com/import-cmake-c20-modules/

А вот, например, текст от Kitware, про поддержку модулей в cmake.

Про то, как они пропихивали динамические зависимости в разные там ninja/clang/gcc.

Если честно, когда я прочел про то, что они запилили свой форк ninja в 2015 году, для поддержки модулей в fortran, и смогли его смержить в upstream только недавно, после появления модулей в C++, я заплакал кровавыми слезами, и дальше читать не стал.

#cmake
🤔5🤡3🤣2😐1
https://gist.github.com/pg83/aabbfa4e0850f3616857d9acaaf841c8

А вот вам еще одна всратая ошибка сборки, из-за криворуких атворов #cmake.

Что тут произошло?

Я в каждую папку с готовыми артефактами кладу файлик touch, как символ того, что эта папка готова.

А авторы #cmake решили, что они будут искать бинари не только в папках CMAKE_PREFIX_PATH/bin, а еще и в самих CMAKE_PREFIX_PATH. И вот сборка webkitgtk нашла такой файлик в качестве команды touch - https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/CMakeLists.txt#L159

Знаете, вот это вот ощущение, когда одни криворукие программисты начинают воркэраундить код для других криворуких программистов (одни не сумели осилить передать правильный PREFIX, другие не рабобрались, и стали искать везде)?

Вот это вот оно, да.
🙈9🔥4👍3💩1🤣1
https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%9B%D0%B8%D0%BD%D1%83%D1%81%D0%B0

Вот есть 3 популярные в open source системы сборки - cmake, meson, #autohell.

И во всех трех есть определенные проблемы с #cross-компиляцией:

* В #cmake ее просто нет. Много раз писал и буду писать, что она у него совершенно фейковая, для отчета горе-программистов, которые ее делали, перед начальством.

* GNU #autohell содержит зачатки кросс-компиляции (умеет искать host compiler, например), но дальше ты сам по себе - фактически, нужно руками писать все сборочные правила для host сборок, без всякой на то помощи. Искать host библиотеки через pkg-config? Боже упаси, это же просто космос!

* meson наиболее продвинут в этом отношении, но и в нем есть свои проблемы. Например, очень странный способ указывать host/target тулзы, через материализованный файл, с не очень понятным синтаксисом.

При этом, ни одна из этих систем не является cross-native (#cross_native)!

(я сам изобрел этот термин, не ищите)

Что это значит?

Это значит, что кросс-компиляция туда добавлена постфактум, и не является родной. То есть, по умолчанию, предполагается, что ты можешь запустить любую свежесобранную тулзу, а чтобы было "не так", разработчики конкретной сборки должны знать, что бывает кросс-компиляция, и специально для этого присесть (повторю, meson в этом помогает, autohell не мешает, cmake мешает активно).

При чем тут закон Линуса?

А при том, что, несмотря на это, меньше всего проблем с кросс-компиляцией мне доставляют проекты на #autohell, просто потому, что они старые, потому, что их успело облизать огромное число человек, и кому-то уже было НАДА запилить в этих проектах кросс-компиляцию.

Как я предлагаю поступать с кросс-компиляцией в open source?

Я советую:

* Или писать весь код, который надо запустить на host системе, на интерпретируемом языке, типа python.

* Или разбивать свои проекты на библиотеки и программы в разные проекты на github (или в разные папочки одного проекта, но с возможностью собрать по отдельности все составляющие части), и сопрягать их мета-сборкой, типа nix/ix/guix.
🔥4🤔4👍2👌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
commit -m "better"
Продолжаю рассказ про #MinGW #windows Пожалуй, самая дичайшая дичь, с которой я столкнулся, это то, что #GNU #autohell позволяет настроить расширение для собранной статической библиотеки. Настройка эта доступна не тому, кто запускает готовый configure,…
Продолжаю рассказ про странности платформы #MinGW.

На этот раз про сборку под нее через #cmake.

Я очень (ну, реально, ОЧЕНЬ, минут 15) долго искал, как этот target называется в cmake. Указать что-то человекопонятное, типа MinGW, MinGW32, MinGW64, приводило к тому, что cmake жаловался на то, что не знает такой платформы. Вот примерно с такими ошибками - https://discourse.cmake.org/t/system-is-unknown-to-cmake-create-platform-mingw64-nt-10-0-19044/4734

В инторнетах полно разного рода советов, как компилировать под mingw - предлагается использовать target MSYS/MSYS2. Но это не совсем то же самое - это не только mingw, но и еще какой-то тулинг вокруг, и все ломалось самым всратым образом.

Кто-то раздает феерические советы типа "а заведите себе сами такую платформу" - https://discourse.cmake.org/t/system-is-unknown-to-cmake-create-platform-mingw64-nt-10-0-19044/4734

Кто-то реально создает такие дескрипторы платформы для cmake - https://gist.github.com/peterspackman/8cf73f7f12ba270aa8192d6911972fe8

Вот из одного такого я и понял всю мякотку, всю глубинную суть - https://gist.github.com/peterspackman/8cf73f7f12ba270aa8192d6911972fe8#file-mingw-w64-x86_64-cmake-L9

mingw, с точки зрения cmake, это "Windows".

О как! Если указать такую target platform, то все начинает более-менее компилироваться, как надо.

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

За исключением одной мааааленькой, но важной, проблемы - довольно много сборочных скриптов полагает, что "Windows" == "MSVC" (довольно спорное, хотя и понятное, предположение), и начинает хреначить под эту платформу флаги компиляции "как для msvc" - https://github.com/lloyd/yajl/blob/master/CMakeLists.txt#L46

Короче, сборка под mingw под cmake доставляет, и без пердолинга патчинга некоторых сборочных файлов там не обойтись.
😁8🔥5👍3😢3🥱1🐳1
Будни #bootstrap, #cmake #rant

После обновления на новую версию leptonica стал падать cmake configure у проекта tesseract:

-- Configuring done (1.5s)
CMake Error at /ix/store/RvksJ51kmglEFEW1-lib-leptonica/lib/cmake/leptonica/LeptonicaTargets.cmake:61 (set_target_properties):
The link interface of target "leptonica" contains:

WebP::webp

but the target was not found. Possible reasons include:

* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.


Тут написано, что, мол, найденная leptonica зависит от WebP, но WebP не может быть найдена.

Раскопки привели вот к такому сниппету cmake кода, который был автоматически сгенерен cmake-ом в недрах кода, который он строит для каждого установленного таргета, для поиска его зависимостей:

include(CMakeFindDependencyMacro)
if ()
find_dependency(OpenJPEG CONFIG)
endif()
if ()
find_dependency(WebP 0.5.0 CONFIG)
endif()


Вот этот вот if () - это как? Это в каком таком ЯП может вычислиться, и выдать какой-то результат?

Если заменить это на if (TRUE), то configure проходит корректно, конечно.
😁7🤔6👍3🔥2🐳1
Вышел-таки релиз смака 4.0!
Авторы решились поднять мажор, чтобы подсветить изменения в обратной совместимости и аккуратно выпилить старьё времён версии 2.8.ххх, старее, и вверх до версии 3.5 - старые политики, некоторые кривые вещи, устаревшие ещё с начала 10-х годов, хотя, по изменениям релиз минорный (до февраля это был ещё релиз 3.32, жалко, что красивой цифры 3.33 мы так и не увидели).
Для поддержки сборки проектов, которые собирались на последних версиях (3.31, 3.30 и некоторых раньше) добавили переменную окружения для мейнтейнеров старья CMAKE_MINIMUM_POLICY_VERSION
, и ей надо задать версию 3.5, чтобы старые проекты не ругались на старые политики сборки, которые были удалены. Авторы смака вместе с мейнтейнерами некоторых дистров (дебиан, Федора) помогли починить кое-где сборку.
Если у вас проект, у которого стоит cmake_minimum_required(VERSION 3.4) и ниже - пора обновиться, желательно на 3.10. (у проектов, у которых нет этой команды вверху, лучше добавить эту команду, чтобы правильно применять политики обратной совместимости).
Помимо этого, там:
- в рамках тикета нашли багу в LLVM, в его поддержке модулей c++20 для clang/libc++ (Там глава Kitware зачинил багу);
- Продолжают внедрять и стабилизировать CPS - декларативный формат для внешних зависимостей, которые потом будут цепляться через find_package(libmeow COMPONENTS paws)
- Улучшают инструментацию сборки/конфигурирования проекта (активности примерно начались с версии 3.18, когда добавили простую возможность профилирования этапа конфигурации проекта), теперь можно будет получить более детальную информацию о том, что именно подтормаживает при процессе конфигурации/сборки проектов. Формат данных - flame-graph, включить в своем проекте можно через флаги --profiling-output=<filename> --profiling-format=google-trace, например: cmake -S . -B build --profiling-output=configure-profile.json --profiling-format=google-trace. Полученный JSON можно скормить служебной странице хромиумоподобных браузеров about:profiling, в случае с Firefox - на profiler.firefox.com. Также такие файлы понимают некоторые IDE, типа Qt Creator, vscode и пр.

В четвертой версии эту вещь расширили (на сборку, линковку, кастом-шаги), написали документацию, и сделали возможность задавать свои хуки на измерения, общаться через CMake File API (используется IDE-шками для сбора ВСЕЙ метаинфы о проекте, о таргетах, исходниках и пр.). Новая фича спрятана под волшебным идентификатором CMAKE_EXPERIMENTAL_INSTRUMENTATION. Такие идентификаторы описаны тут (там и про CPS, и про find_package() с CPS, и про import std, который все ещё не достаточно стабильный, и авторы CMake ходят фиксят/репортят баги в апстримах). Эта тема будет интересна для авторов IDE, для девопсов и тех, кому хочется найти узкие места сборки как локально, так и на CI/CD, и я, возможно, сделаю по этой теме отдельную заметочку;
- потихоньку улучшается дока по CMake , поэтому рекомендую периодически ее посматривать - авторы за релиз обычно много всяких полезных уточнений делают/принимают от волонтеров
- на мобильных устройствах теперь левая колонка со ссылками спрятана в "бутерброд"-кнопку контекстного меню;
- старые генераторы для MSVC, которые принимали в своем имени битность архитектуры (вида "Visual Studio 2015 64") были дропнуты в пользу флага -A <arch-name>
- Теперь можно экспортировать журнал конфигурирования проекта в формат SARIF через флаг --sarif-output=<file>
- Началась работа над генерацией SPDX SBOM
- Пачка прочих изменений (384 мерж-реквестов было слито, и там сотни файлов и тысячи строк были дропнуты после удаления старых вещей)
- также там был влит мой "фермерский" MR с фиксом кодировки текста ошибки, который можно получать через функцию FormatMessage(), там неверно интерпретировалась строка как юникод (haha, classic).

Другие изменения (а я рассказал только про удаленные вещи и про интересные экспериментальные фичи) можно глянуть в списке изменений тут: https://cmake.org/cmake/help/v4.0/release/4.0.html

#длиннопостик #смак #cmake #cpp #cxxmodules #profiling #build

v1.1.1-2025-03-09-0046

#длиннопостик@AlexFailsChannel
👍75🤡3🔥1