Когда мне нужно повторно свернуться?

После запуска команды cmake один раз для создания системы сборки, когда когда-нибудь я должен заново запустить команду cmake?

Сгенерированные системы сборки могут обнаруживать изменения в связанных файлах CMakeLists.txt и вести себя соответственно. Вы можете увидеть логику для этого в созданных Makefiles. Точные правила для того, когда это произойдет успешно, таинственны для меня.

Когда мне нужно перезапустить cmake? Ответ зависит от используемого генератора?

Это сообщение в блоге (под заголовком: "Вызов CMake несколько раз" ) указывает на путаницу по этой проблеме и заявляет, что ответ на самом деле "никогда", независимо генератора, но я нахожу это удивительным. Это правда?

Ответ 1

Ответ прост: В двоичном формате cmake, конечно, необходимо повторно запускать каждый раз, когда вы вносите изменения в любой параметр сборки, но вам не нужно делать это по дизайну; поэтому "никогда" не является правильным в отношении команд, которые вы должны выполнить.

Цели сборки, созданные cmake, автоматически включают проверки для каждого файла впоследствии [= начиная с основного файла CMakeLists.txt], задействованного или включающего создание текущего набора проектов Makefiles/VS/whatever. При вызове make (при условии, что здесь используется unix), при необходимости автоматически запускается предыдущее выполнение cmake; поэтому ваши сгенерированные проекты включают в себя логику для вызова самого CMake! Поскольку все параметры командной строки изначально переданы (например, cmake -DCMAKE_BUILD_TYPE=RELEASE .. будет сохранен в CMakeCache.txt, вам не нужно повторно указывать какие-либо из них при последующих вызовах, поэтому проекты также могут запускать cmake и знать он по-прежнему делает то, что вы намеревались.

Дополнительная информация: CMake генерирует файлы учета, содержащие все файлы, участвующие в создании Makefile/Project, см., Например, эти образцы содержимого моего файла <binary-dir>/CMakeFiles/Makefile.cmake с использованием файлов MSYS make файлов:

# The top level Makefile was generated from the following files:
set(CMAKE_MAKEFILE_DEPENDS
  "CMakeCache.txt"
  "C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/CMakeCCompiler.cmake.in"
  "C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/RepositoryInfo.txt.in"
  "<my external project bin dir>/release/ep_tmp/IRON-cfgcmd.txt.in" 
  "../CMakeFindModuleWrappers/FindBLAS.cmake"
  "../CMakeFindModuleWrappers/FindLAPACK.cmake"
  "../CMakeLists.txt"
  "../CMakeScripts/CreateLocalConfig.cmake"
  "../Config/Variables.cmake"
  "../Dependencies.cmake"
  "CMakeFiles/3.1.0/CMakeCCompiler.cmake"
  "CMakeFiles/3.1.0/CMakeRCCompiler.cmake")

Любая модификация любого из этих файлов приведет к запуску другого запуска cmake всякий раз, когда вы решите начать сборку цели. Я честно не знаю, как мелкозернистые отслеживания зависимостей идут в CMake, т.е. Если цель будет просто построена, если какие-либо изменения в другом месте не повлияют на целевую компиляцию. Я бы не ожидал этого, так как это может стать довольно беспорядочным, и повторные попытки CMake (правильно использующие возможности Cache) очень быстр в любом случае.

Единственный случай, когда вам нужно повторно запустить cmake, - это когда вы меняете компилятор после запуска project(MyProject); но даже этот случай обрабатывается новыми версиями CMake автоматически (с некоторыми криками: -)).

дополнительный комментарий к комментариям:

Есть случаи, когда вам нужно вручную повторно запустить cmake, и это происходит, когда вы пишете скрипты configure настолько плохо, что cmake не может обнаружить файлы/зависимости, которые вы создаете. Типичным сценарием будет то, что ваш первый запуск cmake создает файлы, используя, например, execute_process, и вы включили бы их с помощью file(GLOB ..). Это BAD-стиль и CMake Docs для файла явно говорят

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

Кстати, этот комментарий также проливает свет на описанное выше объяснение самозапуска сгенерированной системой сборки: -)

"Правильный" способ лечения таких ситуаций, когда вы создаете исходные файлы во время настройки, - это использовать add_custom_command(OUTPUT ...), чтобы CMake "знал" создаваемого файла и правильно отслеживал изменения. Если по какой-либо причине вы не можете/не будете использовать add_custom_command, вы все равно можете сообщить CMake о генерации вашего файла, используя свойство исходного файла GENERATED. Любой исходный файл с этим набором флагов может быть жестко закодирован в целевые исходные файлы, а CMake не будет жаловаться на отсутствие файлов во время настройки (и ожидает, что этот файл будет создан некоторое время во время (первого!) Выполнения cmake.