Есть ли способ выполнить атомную сборку CMake?

Я рассматриваю возможность переопределения нашей системы сборки (в настоящее время основанной на GNU Make) в CMake.

Отказ от ответственности: это скорее теоретический и "лучший опыт". Я не знаю CMake в глубину. Также, пожалуйста, не стесняйтесь перенести вопрос на программистов, если он больше по теме.

Насколько я понимаю, стандартный рабочий процесс для CMake -

cmake .
make

Я подозреваю, что могут быть проблемы с десинхронизацией файлов CMake и Make файлов.

Итак, во время обычного процесса разработки вы должны запустить make, чтобы избежать ненужных перестроек CMakeCache и Makefiles и, как правило, сделать процесс более прямым. Но тогда, если вы добавите, скажем, новый исходный файл в CMakeLists и запустите make, он будет использовать старые CMakeCache и Makefiles и не будет автоматически обновлять их. Я думаю, что это может вызвать серьезные проблемы при использовании в масштабе, поскольку, если что-то не строится так, как должно, вам нужно попытаться выполнить make clean, тогда, если это не поможет, вам нужно будет удалить CMakeCache и восстановить все (вручную!).

Если я не прав о чем-то из вышеперечисленного, пожалуйста, поправьте меня.

Я хотел бы просто сделать

awesome-cmake

и обновить все, что необходимо для обновления и сборки проекта.

Итак, вопрос: есть ли способ сделать "атомную сборку" с CMake так, чтобы он отслеживал всю необходимую информацию и абстрагировал использование make?

Ответ 1

Я думаю, у вас здесь пара неправильных идей:

Я подозреваю, что могут быть проблемы с де-синхронизацией файлов CMake и Makefiles.

В конечном счете, CMake все о создании правильных файлов Makefile (или файлов решений Visual Studio или файлов проектов XCode или что-то еще). Если вы не модифицируете созданный Makefile вручную, между CMake и Makefile не может возникнуть проблема синхронизации, поскольку CMake генерирует Makefile.


Но тогда, если вы добавите, скажем, новый исходный файл в CMakeLists и запустите make, он будет использовать старые CMakeCache и Makefiles и не будет автоматически регенерировать их.

На самом деле верно обратное: если вы измените CMakeLists.txt(например, добавив новый источник, изменив флаг компилятора, добавив новую зависимость), тогда запуск make приведет к повторному запуску CMake автоматически. CMake будет читать в своих ранее кэшированных значениях (включая любые аргументы командной строки, ранее заданные CMake) и генерировать обновленный Makefile.


в случае, если что-то не строится так, как должно, вам нужно попытаться выполнить make clean, тогда, если это не поможет, вам нужно удалить CMakeCache и восстановить все (вручную!).

Да, это будет довольно нормальный рабочий процесс, если что-то пошло не так. Однако, что-то не так часто бывает в моем опыте.


Итак, вопрос: есть ли способ сделать "атомную сборку" с CMake так, чтобы он отслеживал всю необходимую информацию и абстрагировал от использования make?

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

Остерегайтесь здесь использования file(GLOB ...) или аналогичного сгенерировать список исходных файлов. Из документов:

Мы не рекомендуем использовать GLOB для сбора списка исходных файлов из исходного дерева. Если файл CMakeLists.txt не изменяется при добавлении или удалении источника, сгенерированная система сборки не может знать, когда следует запросить регенерировать CMake.

Другими словами, если вы используете file(GLOB ...) для сбора списка источников, вам нужно привыкнуть перезапускать CMake после добавления/удаления файла из исходного дерева; запуск make не приведет к повторному запуску CMake в этой ситуации.

Ответ 2

Стандартный рабочий процесс для CMake - это исходная компоновка

mkdir build
cd build
cmake ..
make