运行cmake
命令一次以生成构建系统后,是否应该重新运行cmake
命令?
生成的构建系统可以检测关联的CMakeLists.txt
文件中的更改并相应地执行操作。您可以在生成的Makefile中看到这样做的逻辑。成功实现这一目标的确切规则对我来说是神秘的。
我什么时候应该重新运行cmake
?答案是否取决于使用的发电机?
This blog post(在标题下:“多次调用CMake”)指出了对这个问题的困惑,并指出答案实际上是“从不”,无论发生器如何,但我发现这令人惊讶。这是真的吗?
答案 0 :(得分:20)
答案很简单:
当然,cmake
二进制文件需要在每次更改任何构建设置时重新运行,但你不需要按设计进行;因此,“永远”对于你必须发出的命令是正确的。
cmake 创建的构建目标会自动包含对每个文件的检查[=从主CMakeLists.txt文件开始]涉及或包括生成当前Makefiles / VS项目集等等。在调用make
时(假设在此处使用unix),如果需要,这将自动触发先前执行cmake
;所以你生成的项目包含调用cmake本身的逻辑!由于最初传递的所有命令行参数(例如cmake -DCMAKE_BUILD_TYPE=RELEASE ..
将存储在CMakeCache.txt
中,因此您无需在后续调用中重新指定任何这些参数,这就是项目也可以运行的原因{ {1}}并且知道它仍然按照你的意图行事。
更多细节:
CMake生成包含Makefile / Project生成中涉及的所有文件的簿记文件,例如,这些使用MSYS makefile的cmake
文件的示例内容:
<binary-dir>/CMakeFiles/Makefile.cmake
对于任何这些文件的任何修改都会在您选择开始构建目标时触发另一个cmake运行。老实说,我不知道这些依赖关系跟踪在CMake中是多么精细,即如果目标只是在其他地方的任何更改不会影响目标的编译时构建。我不会指望它,因为这可能会很快变得混乱,并且重复CMake运行(正确使用缓存功能)反正非常快。
您需要重新运行# 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,这就是每当您编写配置脚本时,cmake都无法检测到您正在创建的文件/依赖项。典型情况是您的第一次cmake运行使用例如project(MyProject)
然后您将使用execute_process
包含它们。这是BAD风格,CMake Docs for file明确说出
注意:我们不建议使用GLOB从源树中收集源文件列表。如果在添加或删除源时没有更改CMakeLists.txt文件,则生成的构建系统无法知道何时要求CMake重新生成。
顺便说一句,这条评论也阐明了生成的构建系统对上述自我调用的解释: - )
处理在配置时创建源文件的这种情况的“正确”方法是使用file(GLOB ..)
,以便CMake“了解”正在生成的文件并正确跟踪更改。如果由于某种原因您不能/不会使用add_custom_command(OUTPUT ...)
,您仍然可以使用源文件属性GENERATED让CMake知道您的文件生成。设置了此标志的任何源文件都可以硬编码到目标源文件中,并且CMake不会在配置时抱怨丢失文件(并且期望在(第一次!)cmake运行期间生成此文件。
答案 1 :(得分:1)
查看该主题以从debian / changelog文件中读取版本信息(生成阶段),我遇到了在修改debian / changelog时应触发cmake执行的主题。因此,我需要将debian / changelog添加到CMAKE_MAKEFILE_DEPENDS。
就我而言,debian / changelog是通过execute_process读取的。不幸的是,Execute_process无法将已处理的文件添加到CMAKE_MAKEFILE_DEPENDS。但是我发现运行configure_file可以做到。实际上,我确实在execute_process中缺少诸如DEPENDENCIES之类的东西。
但是,由于我需要根据自己的需要配置debian / changelog文件,因此解决方案对我来说是隐含的。
我实际上也在configure_file的官方文档中找到了有关此问题的提示:
“如果输入文件被修改,则构建系统将重新运行CMake以重新配置文件并再次生成构建系统。”
因此,使用configure_file应该可以安全地触发cmake的重新运行。
从用户角度来看,我希望其他命令也可以扩展CMAKE_MAKEFILE_DEPENDS。例如。 execute_process(按需),但也要执行file(READ)(隐含地像configure_file)。也许还有其他。每个读取的文件可能会影响生成阶段。另外,最好是使用一条命令来扩展依赖项列表(对于cmake开发人员,可能会出现提示)。