linux - 为什么 Unix Makefiles 的 CMake 生成器会删除文件?
问题描述
我有一个相当复杂的 CMake 配置,其中包含几个execute_process
在配置阶段创建文件的命令。有时在 CMake 配置中进行一些更改后,生成阶段会删除这些文件。我可以重现那个。
我已经检查了这些文件在配置阶段之后是否存在,但在 Makefile 生成之后和实际调用make
.
在某些情况下,这些文件是${CMAKE_COMMAND} -E copy
通过调用脚本创建的,在其他情况下,通过调用${CMAKE_COMMAND} -P
包含configure_file
替换模板中某些占位符的调用的脚本。
这些文件是在源代码树中创建的。他们的目的是为开发人员提供一些初始代码。当开发人员编辑了文件后,它们应该被提交给版本控制并且除非它们丢失,否则不要再次重新创建它们。如果文件丢失,我必须add_custom_command
重新创建文件,但这些不是罪魁祸首。
我知道,您更喜欢一个简单的测试示例,但不幸的是,这并不容易创建,所以我的问题是:
可能是什么原因,我该如何调试?
不幸的是,--trace
选项cmake
不提供有关生成阶段的任何日志数据。
版本
- 操作系统:Ubuntu 16.04
- CMake 3.5.1(属于Ubuntu 16.04)
更新
我已经用当前的主提交(696b2d4)编译了 CMake 本身,并且行为仍然相同。
通过在调试器下运行 CMake,我发现该行
cmSystemTools::RemoveFile(fname);
in 函数cmGlobalGenerator::CheckRuleHashes(std::string const& pfile, std::string const& home)
实际上删除了文件。它是从 调用的cmGlobalGenerator::Generate()
。
解决方案
通过进一步调试(请参阅问题中的更新),我找到了问题的原因。
CMake 的行为
CMake 的全局生成器创建文件${CMAKE_BINARY_DIR}/CMakeFiles/CMakeRuleHashes.txt
。它包含每个带有输出的自定义命令的行。每行包含一个哈希和自定义命令第一个输出的路径。
哈希是在自定义命令的当前二进制目录COMMAND
和add_custom_command
.
在生成时,CMake 会执行cmGlobalGenerator::CheckRuleHashes
以检查哈希是否仍然是最新的。如果哈希不是最新的,则相应的输出文件将被删除,显然是在构建阶段触发自定义命令的重新执行。
我的问题的原因
execute_process
如问题中所述,我在配置期间执行文件创建命令,并add_custom_command
使用相同的文件创建命令调用以触发文件的重新创建,以防文件丢失。
CMakeRuleHashes.txt
因此,CMake 在其中为要创建的文件创建了一个哈希行。
我的一些add_custom_command
调用包含在一个 CMake 文件中,该文件包含CMakeLists.txt
在源的不同子目录中。根据我的实际配置,只有特定的子目录会添加add_subdirectory
.
因此,因为子目录是自定义命令的散列的一部分,所以散列会根据添加的包含自定义命令的子目录而改变。然后更改的哈希会导致输出文件的删除。
结论
我必须重新设计我的 CMake 配置以解决自定义命令对 CMake 二进制目录的依赖性。
调试生成阶段
这可以通过将 CMake 本身编译为Debug
构建类型并在调试器下运行来完成。
推荐阅读
- asp.net-core - Net Core 3.0 文件上传不起作用,但在 Net Core 2.2 中运行良好
- javascript - InversifyJS @multiInject 不起作用,抛出错误“为 serviceIdentifier 找到不明确的匹配”
- python - TensorRT- 不支持的操作 _Fill
- cypress - 赛普拉斯:为什么我需要在每次测试之前运行 cy.wait(0)?
- c# - 如何根据其文本制作按钮的 Onclick?
- plugins - 在刻度中添加符号时出现问题(括号插件)
- unity3d - 如何在我的项目中使用 2d-extras zip 文件?(或任何其他外部统一下载)
- python - 如何更改假设生成的最大测试用例数?
- javascript - 根据显示的单词更改文本的颜色
- javascript - 悬停时我怎么能做很多元素做同样的事情?