Pull to refresh

Comments 18

Первое что я говорю тем кто в команде начинается знакомиться с CMake — выучить правила для variable expansion.
1) Двойные кавычки позволяют превратить список в строку (разделенную символом ";")
2) Подстановку переменной любого типа не в контексте строковой константы — превращает ее автоматически в список всегда. символы ";" исчезают.
Второе, что следует запомнить, что практически все API — все эти if-ы, foreach и прочие add_target — работают со списком строк. т.е. как бы vector<string>
соответственно, можно делать штуки вроде
if (${some_long_condition})
и отсюда приходит понимание почему иногда выдает ошибку код
if (${foo} STREQUAL "bar")
— если foo неопределена (или пуста), условие превратится в список из двух строк «STREQUAL» и «bar».
Поэтому третье что следует понять при чтении документации, когда допустимо значение, когда строка, а когда и то, и то (и это в документации обычно явно отражено фразами вроде «string or variable»)
Напишите статью-гайд для новичков со своим видением.
Простите, я Вашу статью нисколько не хотел принизить, просто хотел дополнить теми вещами, с которыми прежде всего (по моему опыту) сталкиваются новички.
Ой!)
Я думаю, люди все равно читают первые комментарии к статье, так что, пожалуй просто продолжу комментировать существующие, чтобы не плодить сущности =)
Ваши замечания я описал в разделе «Аргументы», спасибо за содержательные комментарии.
Для отладки я бы так же посоветовал упомянуть помимо message, замечательные флаги --trace и --trace-expand, они позволяют вывести каждую выполненную команду именно в том порядке, как они были выполнены интерпретатором. Так же они помогают понять «узкие места» в коде, которые тормозят выполнение, косвенно, конечно.
Макросы аналогичны функциям за тем исключением, что они не имеют собственной области видимости

я бы СРАЗУ упомянул еще про одну особенности, что они буквально работают как макросы в препроцессоре C — т.е. если в макросе вставить return(), то произойдет выход из родительской функции, вызвавшей макрос.
В связи с тем, что родительские переменные можно выставлять через SET(… PARENT_SCOPE), я бы лично не советовал использовать макросы в большинстве случаев. Вызов функций в cmake достаточно дешевая операция, по сравнению со многими командами.
Спасибо за комментрий, ваши замечания я описал в статье.
На самом деле, все переменные по умолчанию считаются глобальными (доступ к ним есть везде)

Есть одно исключение из этого правила — при вызове add_subdirectory — все включенное в дочернем CMakeLists.txt не просочится наружу (я о переменных). В то время как include() такой особенности не имеет.

Здравствуйте. Спасибо за комментарии, ваши замечания будут учтены, по возможности, в следущей статье)

С точки зрения стиля кодирования я бы вообще не рекомендовал где-то сильно рассчитывать на глобальность переменных, т.к. может быть такая ситуация:
— Написал вспомогательный cmake-файл, в нем поменял CMAKE_CXX_FLAGS, например. Функций в нем нет.
— Потом спустя какое-то время, пишется функция, и в ней включается этот файл. Сюрприз-сюрприз, после выхода из функции CMAKE_CXX_FLAGS останутся прежними.
Поэтому rule of thumb я бы сформулировал «не используйте запись в глобальные переменные cmake для передачи информации между частями скрипта».
В случаях, когда это позарез надо, использовать явно set(… CACHE… "" FORCE)
Пришлось столкнуться с Смаке при сборке FLTK. Насторожило три вещи:

  1. Отказалась работать на Windows — демки FLTK не собираются из-за какого то глюка спавна только что собранного .exe с путаницей прямого/обратного разделителя пути. Кроссплатформа под вопросом
  2. Добавить тулчейн в систему сборки сложно. Внутренности скриптов Смейка — адский ад
  3. Генерируемые мейкфайлы весьма изобретательны и практически нечитаемы. Разобрать проблемы вышеуказанных пунктов — отдельная проблема

Итого осталось впечатление сырости.
1. Ну это претензии к конкретному проекту — с любым проектом может быть такое что сборка под Windows находится в сыром/полуподдерживаемом состоянии, не только с CMake. Даже с предельно выскокоуровневым qbs в исходниках qtc периодически были коммиты «починка сборки под win», хотя там разработчики активно на всех платформах сидят.
2. полностью поддерживаю. Вся внутренняя кухня cmake — что скрипты, что исходники — адовый ад.
3. Генерируемый код на то и есть таковой, чтобы его не нужно было читать глазками) Впрочем, по своему опыту могу сказать — я почти всегда использую генератор Ninja — там в 1 файле Rules складываются, в основном — все параметры. Вполне очень наглядно и читаемо, попробуйте. Я пока отлаживал свою систему распределённой сборки, а также вспомогательные утилиты (типа msbuild2ninja) очень активно использовал раскуривание генерируемого cmake ninja-файла, все вполне наглядно.

Про сырость — впечатление обманчивое, т.к. cmake используется очень давно в куче продакшн систем, и в целом хорошо себя зарекомендовал — хорошая стабильность в плане регрессий, хорошая совместимость (люди последовательно мигрировавшие с какого-нибудь 2.8.11 до 3.12 меня поймут). Он попахивающий, если лезть внутрь, но не сырой)
Думаю, для option стоило ещё добавить ссылку на cmake -LH, который выводит список опций из кеша (-L) и их описание (-LH).

А то минут 30 копался, как из CMakeLists.txt по-человечески достать description для option.
Only those users with full accounts are able to leave comments. Log in, please.