cmake - 我应该什么时候重新运行 cmake?

标签 cmake

运行 cmake 后命令一次生成构建系统,如果有的话,我应该重新运行cmake命令?

生成的构建系统可以检测到相关 CMakeLists.txt 中的更改。文件并做出相应的行为。您可以在生成的 Makefile 中看到这样做的逻辑。什么时候会成功发生的确切规则对我来说很神秘。

我什么时候应该重新运行cmake ?答案是否取决于所使用的发电机?

This blog post (在标题下:“多次调用 CMake”)指出了对这个问题的困惑,并指出答案实际上是“从不”,无论生成器如何,但我发现这令人惊讶。这是真的吗?

最佳答案

答案很简单:cmake每次更改任何build设置时,二进制文件当然需要重新运行,但您不需要按设计这样做;因此,对于您必须发出的命令,“从不”是正确的。

由 cmake 创建的构建目标自动包括对每个文件的检查 [=从主 CMakeLists.txt 文件开始] 涉及或包括生成当前的 Makefiles/VS 项目集/其他。调用 make 时(假设这里是 unix)这会自动触发 cmake 的先前执行。如有必要;因此您生成的项目包含调用 cmake 本身的逻辑!由于最初传递的所有命令行参数(例如 cmake -DCMAKE_BUILD_TYPE=RELEASE .. 将存储在 CMakeCache.txt 中,您无需在后续调用中重新指定任何参数,这就是为什么项目也可以运行 cmake 并知道它仍然按照您的意图进行。

更多细节:
CMake 生成簿记文件,其中包含 Makefile/Project 生成中涉及的所有文件,参见例如我的 <binary-dir>/CMakeFiles/Makefile.cmake 的这些示例内容使用 MSYS 生成文件的文件:

# 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 的情况是在启动 project(MyProject) 后更改编译器时;但即使这种情况现在也由较新的 CMake 版本自动处理(有些大喊大叫:-))。

回应评论的附加评论:

在某些情况下,您需要手动重新运行 cmake,也就是说,每当您编写配置脚本时,cmake 可能无法检测到您正在创建的文件/依赖项。一个典型的场景是您的第一次 cmake 运行使用例如创建文件。 execute_process然后您将使用 file(GLOB ..) 包含它们.这是糟糕的风格和 CMake Docs for file明确地说

Note: We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.



顺便说一句,此评论还阐明了生成的构建系统进行的上述自我调用:-)

处理在配置期间创建源文件的这种情况的“正确”方法是使用 add_custom_command(OUTPUT ...) ,以便 CMake 能够“感知”正在生成的文件并正确跟踪更改。如果由于某种原因您不能/不会使用 add_custom_command ,您仍然可以使用源文件属性 GENERATED 让 CMake 知道您的文件生成。 .任何带有此标志集的源文件都可以硬编码到目标源文件中,并且 CMake 不会在配置时提示缺少文件(并希望在(第一次!)cmake 运行期间生成该文件。

关于cmake - 我应该什么时候重新运行 cmake?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28250081/

相关文章:

c++ - 构建 OpenCV 时出现 CMake 错误 - CMakeLists 不匹配

c++ - cmake - find_library - 自定义库位置

cmake DEFINED 似乎无法识别变量

cmake - CMake中库之间的重叠依赖关系

c++ - 如何使用 brew 在 OS X Lion 上安装 OpenCV

cmake - 带有特殊字符的 custom_command ECHO

c++ - CGAL 覆盖 CMAKE_BUILD_TYPE=Debug

c++ - CMAKE/代码组织

c++ - Travis CI C++ 构建成功但 travis 以 1 退出并且未通过测试

linker - Cmake基本库链接问题