cmake vs autotools vs всё остальное
Модератор: Модераторы разделов
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
cmake vs autotools vs всё остальное
Выбираю систему сборки для небольшого проекта.
Сначала попробовал autotools, сейчас пробую cmake.
autotools
Плюсы:
1. Для сборки проекта не требует установки (все необходимые сборочные файлы - скрипты и пр. - уже есть в тарболе)
2. Позволяет указать в Makefile.am инструкции, которые будет включены в Makefile "как есть"
3. Позволяет разделить исходные файлы по категориям (исполняемые файлы, данные, man-страницы и пр.)
4. Умеет make dist и make distcheck (что весьма полезно), позволяет указать какие файлы будут включены в тарбол
5. Можно вызвать configure из отдельного каталога и производить сборку в нём
Минусы:
1. Не кросс-платформенный.
2. Сложно поддаётся расширению (довольно невнятный синтаксис m4).
3. Порой бывает сложно настроить проверку наличия библиотек (даёт ложные срабатывания).
cmake
Плюсы:
1. Кросс-платформенный "из коробки".
2. Имеет относительно простой (хотя и не вполне удобный) синтаксис.
3. Расширяемый - можно писать свои функции и модули (на мой взгляд проще, чем в autotools).
4. Можно производить сборку в отдельном каталоге (обычно build).
5. Есть Ctest - можно создавать тесты (не знаю, есть ли подобное в autotools).
Минусы:
1. Для сборки проекта требуется наличие cmake.
2. Регистронезависимый синтаксис (могут быть сюрпризы при переносе между платформами).
3. Нет аналогов dist-целей. В частности, нет make dist. Есть CPack, но это нечто иное.
4. Нет простого способа добавить инструкции в Makefile "как есть". По крайней мере, я не нашёл. Есть, конечно, add_custom_command и add_custom_target, но это опять же, нечто иное.
Казалось бы, выбор очевиден - кросс-платформенность решает, но...
Возможно, есть другие варианты. В обсуждениях на просторах Сети упоминались bazel, waf, scons, meson, buckaroo, build2.
Из которых bazel отпадает по причине зависимости от java (это уже как-то совсем чересчур), waf, scons, meson отпадают по причине моей аллергии на python.
Про buckaroo я понял, что это нечто большее, чем просто система сборки, а про build2 вообще ничего не понял.
Цель данной темы: обсудить системы сборки.
Возможно, что в процессе обсуждения найдутся способы устранить/сгладить пункты 3 и 4 из списка минусов Cmake (возможно, я что-то не так понял или упустил).
А может быть, подскажут ещё какой-то инструмент, о котором я не знаю.
Понимаю, что тема холиварная, но всё-таки...
прошу высказываться.
Сначала попробовал autotools, сейчас пробую cmake.
autotools
Плюсы:
1. Для сборки проекта не требует установки (все необходимые сборочные файлы - скрипты и пр. - уже есть в тарболе)
2. Позволяет указать в Makefile.am инструкции, которые будет включены в Makefile "как есть"
3. Позволяет разделить исходные файлы по категориям (исполняемые файлы, данные, man-страницы и пр.)
4. Умеет make dist и make distcheck (что весьма полезно), позволяет указать какие файлы будут включены в тарбол
5. Можно вызвать configure из отдельного каталога и производить сборку в нём
Минусы:
1. Не кросс-платформенный.
2. Сложно поддаётся расширению (довольно невнятный синтаксис m4).
3. Порой бывает сложно настроить проверку наличия библиотек (даёт ложные срабатывания).
cmake
Плюсы:
1. Кросс-платформенный "из коробки".
2. Имеет относительно простой (хотя и не вполне удобный) синтаксис.
3. Расширяемый - можно писать свои функции и модули (на мой взгляд проще, чем в autotools).
4. Можно производить сборку в отдельном каталоге (обычно build).
5. Есть Ctest - можно создавать тесты (не знаю, есть ли подобное в autotools).
Минусы:
1. Для сборки проекта требуется наличие cmake.
2. Регистронезависимый синтаксис (могут быть сюрпризы при переносе между платформами).
3. Нет аналогов dist-целей. В частности, нет make dist. Есть CPack, но это нечто иное.
4. Нет простого способа добавить инструкции в Makefile "как есть". По крайней мере, я не нашёл. Есть, конечно, add_custom_command и add_custom_target, но это опять же, нечто иное.
Казалось бы, выбор очевиден - кросс-платформенность решает, но...
Возможно, есть другие варианты. В обсуждениях на просторах Сети упоминались bazel, waf, scons, meson, buckaroo, build2.
Из которых bazel отпадает по причине зависимости от java (это уже как-то совсем чересчур), waf, scons, meson отпадают по причине моей аллергии на python.
Про buckaroo я понял, что это нечто большее, чем просто система сборки, а про build2 вообще ничего не понял.
Цель данной темы: обсудить системы сборки.
Возможно, что в процессе обсуждения найдутся способы устранить/сгладить пункты 3 и 4 из списка минусов Cmake (возможно, я что-то не так понял или упустил).
А может быть, подскажут ещё какой-то инструмент, о котором я не знаю.
Понимаю, что тема холиварная, но всё-таки...
прошу высказываться.
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
Это не преимущество, а недостаток. При использовании любой другой сборочной системы архив исходников можно получить посредством git archive (подставьте аналогичную команду для своей VCS, если пользуетесь другой), но в случае с autocrap он будет неработоспособен.
Это в autocrap можно (если разработчик не накосячил), а в cmake — нужно. Впрочем, я в любом случае рекомендую так делать.
Конечно, нет. Потому что cmake далеко не всегда генерирует Makefile. Но если Вам нужна переносимость, напрямую вставлять команды всё равно нельзя.
Я с выбором давно определился. autocrap мне глубоко противен самим принципом своей работы: напихать прямо в дерево исходников кучу скриптов, по объёму, как правило, сильно превосходящую объём собственно кода проекта, и потом этими скриптами нагенерировать кучу других скриптов, из которых долго и мучительно запускать друг друга, чтобы собрать hello world. К тому же там возникают большие сложности при сборке библиотек, которые зависят от других библиотек, потому что предназначенный для этой цели libtool исключительно крив. А главное — autocrap тяжёл в освоении, что при отсутствии существенных преимуществ делает его крайне неудачным выбором для начинающих. Там разложено много граблей, аккуратно пройти между которыми мало кто способен.
У cmake, действительно, не самый красивый синтаксис, зато он простой как лопата, и учить по ходу дела дополнительные языки (m4, shell, make) не придётся.
Даже не слышал про такие. Имел несчастье работать с boost.build (aka bjam) — не рекомендую. В принципе он чем-то похож на cmake, но у него упоротый синтаксис и беда с документацией, а главное — катастрофически не хватает модулей.Hephaestus писал: ↑11.05.2019 13:22Про buckaroo я понял, что это нечто большее, чем просто система сборки, а про build2 вообще ничего не понял
P. S. В качестве одного из критериев оценки сборочной системы рекомендую смотреть на её пригодность для кросс-компиляции. Даже если он и не нужна, это поможет понять степень зрелости продукта. Например, waf таким образом сразу можно исключить из рассмотрения (Вы пробовали кросс-компилировать самбу? Я пробовал…).
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
Re: cmake vs autotools vs всё остальное
Ну, не знаю. Не вижу ничего плохого в том, чтобы выполнить make distcheck,
и тогда будет проверена возможность сборки, а затем создан тарбол с исходниками,
причём именно с файлами, необходимыми для сборки, а не просто каталог в архиве, как в случае с CPack.
Не понял. Почему неработоспособен?Bizdelnick писал: ↑11.05.2019 14:12При использовании любой другой сборочной системы архив исходников можно получить посредством git archive, но в случае с autocrap он будет неработоспособен.
Сейчас проверил - вроде работает.
Единственная проблема - git-archive не включает в архив неотслеживаемые файлы. Так это вполне нормально.
Нужно лишь создать коммит с нужными файлами и всё будет работать.
Поскольку для autotools я включал в Makefile.am некоторые команды, я подумал, что и в случае с cmake это может понадобиться.Bizdelnick писал: ↑11.05.2019 14:12Конечно, нет. Потому что cmake далеко не всегда генерирует Makefile. Но если Вам нужна переносимость, напрямую вставлять команды всё равно нельзя.
Возможно, я просто не с той стороны подошёл к задаче. Надо будет пересмотреть.
Да, это чувствуется. Весьма нелестное прозвище Вы дали этому инструменту (если только я правильно перевёл на русский).
Причём используете исключительно это название. Ну, хорошо хоть в этом посте Вы развёрнуто изложили своё мнение - хоть понятно стало, в чём дело.
Я не понял, cmake простой или синтаксис простой?Bizdelnick писал: ↑11.05.2019 14:12У cmake, действительно, не самый красивый синтаксис, зато он простой как лопата
На мой взгляд, cmake далеко не так прост, да и синтаксис довольно развестистый.
Впрочем, файлы CMakeLists.txt я написал за пару вечеров и получил вполне работающую сборку.
С autotools в своё время я возился гораздо дольше.
Это да. Зато нужно иметь на собирающей машине cmake вполне определенной версии.Bizdelnick писал: ↑11.05.2019 14:12учить по ходу дела дополнительные языки (m4, shell, make) не придётся
В обсуждениях как один из критичных недостатков cmake указывают то, что могут поломать совместимость.
Вот, например,
Аналитик с ЛОРа писал(а): Нормально, всё нормально с cmake. Что не нормально так это то что за год они могут полностью поломать совместимость и назначение/смысл переменных и методов, пару раз.
С другой стороны, между Meson и cmake, я всё равно выберу cmake.Аналитик с ЛОРа писал(а): От CMake сегодня многие отказываются и переходят на Meson, потому что понимают что CMake — та ещё параша. Неочевидная. Кривоработающая. Не соблюдающая свои же задекларированные возможности.
Ваш выбор - cmake, правильно понимаю?
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
CPack-то тут каким боком? Он вообще для другого. А файлы, необходимые для сборки, и так все на месте.Hephaestus писал: ↑12.05.2019 00:05причём именно с файлами, необходимыми для сборки, а не просто каталог в архиве, как в случае с CPack.
Неработоспособен, потому что туда надо ещё напихать вагон скриптов и сгенерировать пачку файлов (то бишь дёрнуть autoconf, automake, libtoolize, что там ещё…). Держать их в гите нельзя, потому что при чекауте файлы получат рандомные таймстемпы, и хотя всё и будет на месте, make всё равно может решить, что что-то надо перегенерировать.
Это не я. Его многие так называют. См. https://varnish-cache.org/docs/2.1/phk/autocrap.html
Синтаксис. Есть команды, есть переменные — и всё. Даже условные конструкции по синтаксису неотличимы от команд (коими и являются, в общем-то). Всё это довольно непривычно, но зато не надо думать, где какую скобку поставить, какой разделитель использовать, какие символы экранировать и т. п.
Ну обратная совместимость там весьма неплохая, так что всё-таки не ниже определённой. А вот в autoconf и automake совместимость периодически ломают. Хотя там это проблемы не пользователя, а исключительно разработчика.Hephaestus писал: ↑12.05.2019 00:05Зато нужно иметь на собирающей машине cmake вполне определенной версии.
Ни разу не сталкивался. Если у чего-то меняется поведение, то, во-первых, это не происходит внезапно, во-вторых, старое можно вернуть через policy. В моём понимании это не значит «полностью поломать совместимость».Hephaestus писал: ↑12.05.2019 00:05за год они могут полностью поломать совместимость и назначение/смысл переменных и методов, пару раз.
Из autotools и cmake — да, однозначно. Питонов и жаб я тоже недолюбливаю.
P. S. CMake тоже далеко не идеал, есть у него свои заморочки. См. например cmake - взять значение переменной из окружения, если есть — я тогда так и не нашёл решения.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
Re: cmake vs autotools vs всё остальное
Когда в обсуждениях поднимается тема миграции с autotools на cmake,
в числе прочего спрашивают про аналог make dist в cmake.
В ответ рекомендуют CPack. Дескать, прямо вот make dist нет, но есть CPack,
который может сотворить тарбол с исходниками. И он таки может.
Отчего же?
По cmake .. && cmake --build . --target package_sourcehttps://cmake.org/cmake/help/latest/module/CPack.html писал(а): Inclusion of the CPack module adds two new build targets, package and package_source, which build the binary and source installers respectively.
создается вполне себе тарбол с исходниками, даже имя файла в формате program-version.tar.gz
И всё это рулится в том же CMakeLists.txt
Только вот пихает он в тарбол всё дерево исходников без разбору, приходится отфильтровывать через CPACK_SOURCE_IGNORE_FILES.
У autotools с этим несколько точнее: make dist включает исходники, плюс файлы, помеченные как dist.
Был бы у CPack "белый список" - цены б ему не было.
Это сложный вопрос, в статьях по autotools упоминалось, какие файлы нужно включать в СКВ, а какие нет. Общее правило: включаются исходные файлы, генерируемые не включаются.Bizdelnick писал: ↑12.05.2019 00:49Неработоспособен, потому что туда надо ещё напихать вагон скриптов и сгенерировать пачку файлов (то бишь дёрнуть autoconf, automake, libtoolize, что там ещё…). Держать их в гите нельзя, потому что при чекауте файлы получат рандомные таймстемпы, и хотя всё и будет на месте, make всё равно может решить, что что-то надо перегенерировать.
Точнее сейчас не скажу - не помню. Когда вчера проверял, включил в коммит всё, что создалось после aclocal && automake && autoconf. Не уверен, что всё нужно было включать (и симлинки смущают), но в целом, думаю, это вполне можно организовать. Другое дело, что это на порядок сложнее, чем cmake, у которого кроме CMakeLists.txt в дереве исходников ничего и нет.
А вообще, я согласен, что держать в дереве исходников всякие скрипты и прочие сопутствующие файлы - не самая хорошая идея. Уж хоть бы в отдельном каталоге это всё было что ли...
В этом смысле cmake получается значительно аккуратней, но обратная сторона этой аккуратности - присутствие cmake на собирающей машине.
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
Хм, это я упустил из виду. Он мне больше интересен в плане package.Hephaestus писал: ↑12.05.2019 12:08По cmake .. && cmake --build . --target package_sourcehttps://cmake.org/cmake/help/latest/module/CPack.html писал(а): Inclusion of the CPack module adds two new build targets, package and package_source, which build the binary and source installers respectively.
создается вполне себе тарбол с исходниками, даже имя файла в формате program-version.tar.gz
И всё это рулится в том же CMakeLists.txt
Добавлено (12:34):
А что у Вас там такого, что приходится отфильтровывать? Может, ему там в принципе не место?Hephaestus писал: ↑12.05.2019 12:08Только вот пихает он в тарбол всё дерево исходников без разбору, приходится отфильтровывать через CPACK_SOURCE_IGNORE_FILES.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
Это неправильно. Ничего из создаваемого этими командами в VCS включать не надо. Иначе, как я писал выше, после чекаута может отказаться, что configure.ac новее configure и/или aclocal.m4, или Makefile.am новее Makefile.in. В итоге configure отработает нормально, а вот make решит, что надо все эти файлы перегенерировать, и попытается это сделать (насколько успешно — зависит от наличия на сборочной машине упомянутых утилит и их версий).Hephaestus писал: ↑12.05.2019 12:08в статьях по autotools упоминалось, какие файлы нужно включать в СКВ, а какие нет. Общее правило: включаются исходные файлы, генерируемые не включаются.
Точнее сейчас не скажу - не помню. Когда вчера проверял, включил в коммит всё, что создалось после aclocal && automake && autoconf. Не уверен, что всё нужно было включать (и симлинки смущают), но в целом, думаю, это вполне можно организовать.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
Re: cmake vs autotools vs всё остальное
Каталог .git например. Каталоги build. Любые временные файлы/каталоги (которые не отслеживаются и впоследствии будут удалены git clean). Все файлы, перечисленные в .gitignore (и сам файл .gitignore, кстати).Bizdelnick писал: ↑12.05.2019 12:34А что у Вас там такого, что приходится отфильтровывать? Может, ему там в принципе не место?
Аналогично обстоит дело с файлами других СКВ. В документации CPack есть даже пример шаблона на эту тему:
В этом смысле git archive, конечно, проще, но с другой стороны, получается, что создание тарбола (как таковое) зависит от СКВ, хотя в cmake, казалось бы, есть нужный инструмент.CPACK_SOURCE_IGNORE_FILES
Pattern of files in the source tree that won’t be packaged when building a source package. This is a list of regular expression patterns (that must be properly escaped), e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
Ну это таки решается git archive. Касательно build — нет никакого стандарта, по которому сборочный каталог должен называться именно так. Чтобы он не мешался, его вообще можно делать вне дерева исходников.Hephaestus писал: ↑12.05.2019 13:00Каталог .git например. Каталоги build. Любые временные файлы/каталоги (которые не отслеживаются и впоследствии будут удалены git clean). Все файлы, перечисленные в .gitignore (и сам файл .gitignore, кстати).
Да хоть просто tar'ом его делайте, исключив дотфайлы по маске. Не понимаю, какое это вообще имеет отношение к сборочной системе. В autocrap добавили только для того, чтобы не забыть запихнуть в архив всю нагенерированную помойку, и при этом не засунуть что-то лишнее (типа Makefile, config.log и прочего). Там эта задача в принципе не решаема другим путём.Hephaestus писал: ↑12.05.2019 13:00В этом смысле git archive, конечно, проще, но с другой стороны, получается, что создание тарбола (как таковое) зависит от СКВ, хотя в cmake, казалось бы, есть нужный инструмент.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
Re: cmake vs autotools vs всё остальное
Сборочная система "знает" что из каких файлов создаётся. Где исходники, где хедеры, где скрипты, а где данные. Поэтому вполне логично, что именно сборочная система создает "сборочный" же тарбол.Bizdelnick писал: ↑12.05.2019 13:12Не понимаю, какое это вообще имеет отношение к сборочной системе.
Кроме того, на мой взгляд,
make distcheck сделать просто удобнее, чем git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz 1.4.0.
Возможно. Однако, получилась вполне полезная штука (make distcheck).Bizdelnick писал: ↑12.05.2019 13:12В autocrap добавили только для того, чтобы не забыть запихнуть в архив всю нагенерированную помойку, и при этом не засунуть что-то лишнее (типа Makefile, config.log и прочего).
Там сначала производится сборка и только в случае успеха сборки создаётся тарбол.
Рациональное зерно в этом есть, согласитесь.
Самое забавное, что cmake .. && cmake --build . --target package_source по большому счету, делает то же самое, что и configure && make distcheck, то есть конфигурирует, собирает и упаковывает.
Только вот ориентируется cmake почему-то не на те файлы, которые нужно включить в архив (что было бы логично и эти файлы уже известны - они указаны в CMakeLists.txt и участвуют в сборке), а на те, которые нужно исключить (а это совсем другие файлы и их список ещё нужно составить). Мало того, что заполнение CPACK_SOURCE_IGNORE_FILES - это лишняя работа, так оно ещё и не даёт нужного эффекта - этот список нужно всё время держать на контроле, так как любой новый/случайный файл в дереве должен быть классифицирован.
- Bizdelnick
- Модератор
- Сообщения: 20793
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: cmake vs autotools vs всё остальное
Эту команду не обязательно руками вводить. Всякие мордочки, от cgit до github, позволяют выкачать правильно сделанный тарбол, просто жмакнув по ссылке. Лишь бы тег стоял. Например:Hephaestus писал: ↑12.05.2019 14:12на мой взгляд,
make distcheck сделать просто удобнее, чем git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz 1.4.0.
https://git.mikhirev.ru/make_pcre/refs/
https://gitlab.com/make_pcre/make_pcre/tags
https://github.com/mikhirev/make_pcre/releases
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: cmake vs autotools vs всё остальное
Cmake кажется красивее.
Единственное после генерации Makefile, в процессе сборки тяжелее отлавливать ошибки, как правило информативнее тут будет запускать сборку в одном потоке, а это медленнее.
Вроде генерация ninja будет и быстрее и информативнее, при использовании много-поточности. Это из личных наблюдений.
А если посмотреть во что может генерировать cmake - ключик -G, то cmake кажется очень удачным решением.
Единственное после генерации Makefile, в процессе сборки тяжелее отлавливать ошибки, как правило информативнее тут будет запускать сборку в одном потоке, а это медленнее.
Вроде генерация ninja будет и быстрее и информативнее, при использовании много-поточности. Это из личных наблюдений.
А если посмотреть во что может генерировать cmake - ключик -G, то cmake кажется очень удачным решением.