Что: 401c0f635a1cdfb01068a48a4cdf40791d3db458
Когда: 2020-11-14 16:17:10+03:00
Темы: redo
Замена autoutils redo системой https://redo.readthedocs.io/en/latest/cookbook/redoconf-simple/ В моей C программе всё усложняется конфигурация сборки: есть опциональные библиотеки, есть выбор методов/библиотек, появилась зависимость между некоторыми переменными конфигурации. Если выбран метод использования криптографии из библиотеки YYY, а не XXX, то всякие XXX_CFLAGS=${XXX_CFLAGS:-`$PKG_CONFIG --cflags xxx`} исполняться не должны. Их можно просто закомментировать, но это ручной труд. Добавлять массу if-ов в сам конфиг (который обычный shell файл) -- тоже плохо, хотя в нём уже есть hardcoded вещи типа добавления -pthread если включено использование pthread mutex-ов. Плюс пользователю нужно явно задавать pkgconf/pkg-config команду например, хотя она может быть определена сама. Некоторые команды (plantuml, dmalloc) опциональны. В общем или существенно усложнять простой config, который выглядит просто как какой-то .ini файл, либо... что-то придумывать. Определение команд, определение наличия библиотек (у меня опциональные libtai, dmalloc, libtap например) -- всё это отдельные изолированные друг от друга задачи. Между ними могут быть зависимости, как например $CRYPTO_CFLAGS зависит от флагов конкретно выбранной криптобиблиотеки. Раньше config содержал вереницу переменных внутри которых были вызовы pkgconf, которые запускались все последовательно. Всё это (отдельные задачи, зависимости между ними) явно задача для системы сборки! Я помнил что в apenwarr/redo реализации есть redoconf -- штука которая как-раз для замены ./configure ада, в которой можно набросать отдельными файлами всякие детекторы. Я по сути взял из неё идеи, но саму использовать не стал. Во-первых, там намёки на GNU Make. Во-вторых, она банально просто где-то падала и не работала у меня -- что-то не так в shell-скриптах. В-третьих, это полноценный такой framework, с кучей библиотечных shell функций и обёрток -- требующий и изучения и уже не такой и прекрасный как redo, не привязанный к языкам или чему-то подобному. В-четвёртых, там очень много делается через создание shell файлов с соответствующими костылями для всякого escape-а данных. В-пятых, там подход заточен чтобы делать один большой и жирный compile скрипт, содержащий все CFLAGS/LDFLAGS/LDLIBS для сборки целей. Я же у себя для каждой конкретной .o-цели явно задаю и управляю какие конкретно опции и флаги передаются -- чтобы лучше понимать что от чего зависит. Но основную идею я заимствовал. Если программа использует $CC, то можно сделать вот такой детектор, который учитывает и переменные окружения: $ cat conf/cmd/cc.do echo "${CC:-`command -v cc`}" можно добавить зависимость от цели учитывающей изменение переменных окружения (0676a1348e8ffe14a7840c8699d3afdc6857e24c) и учитывать не поменялось ли значение самой цели: $ cat conf/cmd/cc.do redo-ifchange ../vars . ../vars echo "${CC:-`command -v cc`}" > $3 command -v redo-stamp > /dev/null || exit 0 redo-stamp < $3 проверка наличия redo-stamp чтобы работало под реализациями без этой команды -- всё будет работать, просто изменение переменных окружения не заставит пересобираться (если системы не основаны на хэшах, конечно же). Программа которой нужна cc команда: redo-ifchange ../conf/cmd/cc read CC < ../conf/cmd/cc $CC ... Сделать более сложные цели для определения команд, возможно с выводом в stderr о том что команда не найдена и будет использоваться пустышка -- тривиально. Раньше у меня всё глобально зависело в целом от конфига и переменных окружения (его касающиеся). Теперь команды сборки документации зависят только от cmd/makeinfo, cmd/plantuml (который подставит пустышку, с предупреждением, если настоящий не найден) и изменение cmd/cc не повлияет на пересборку документации. Плюс для сборки некоторые .o файлов нужны знания о PCSC библиотеке, добываемые через pkgconf. Для других .o файлов нужен LibreSSL, тоже через pkgconf. Обе .o зависят от разных conf/flags/{crypto,pcsc} флагов и поэтому вызовы pkgconf-а могут быть распараллелены. Определение наличия и работоспособности libtai библиотеки делается через сборку (прямо внутри conf/flags/tai) временного файла с C кодом, но знание о $TAI_*FLAGS нужно только при сборке log.o файла -- пока он дожидается сборки и проверки наличия libtai, множество других целей уже успеет собраться, так как они не зависят от conf/flags/tai. Многие .o зависят от криптографических библиотек. Но им без разницы какая именно библиотека будет использована. Поэтому я использую общие $CRYPTO_*FLAGS, значение которых зависит от выбранного метода криптографии: $ cat conf/flags/crypto redo-ifchange ../methods . ../methods src=crypto.$CRYPTO_METHOD redo-ifchange $src cat $src а сама значение флагов для CRYPTO_METHOD=SSL (для примера): $ cat conf/flags/crypto.ssl redo-ifchange ../../config ../cmd/pkg-config . ../../config read PKG_CONFIG < ../cmd/pkg-config cat > $3 <<EOF ${SSL_CFLAGS:-`$PKG_CONFIG --cflags libcrypto`} ${SSL_LDFLAGS:-`$PKG_CONFIG --libs-only-L libcrypto`} ${SSL_LDLIBS:-`$PKG_CONFIG --libs-only-l libcrypto`} EOF command -v redo-stamp > /dev/null || exit 0 redo-stamp < $3 тут и зависимость от конкретной pkg-config реализации и возможность переопределения SSL_* и выхлоп просто в виде трёх строчек в файл. Библиотеке которой надо использовать CRYPTO_*: redo-ifchange ../conf/flags/crypto read CRYPTO_CFLAGS < ../conf/flags/crypto # или { read X ; read X ; read CRYPTO_LDLIBS ; } < ../conf/flags/crypto Подход с read-ом мне люб тем, что не надо париться с экранированием и генерированием валидного shell-кода. Изначально у меня был lib.rc с библиотечными shell функциями, но под конец полностью исчез. В итоге, что я получил?
Сгенерирован: SGBlog 0.34.0