CMake/Ninja 试图编译已删除的“.cpp”文件
Posted
技术标签:
【中文标题】CMake/Ninja 试图编译已删除的“.cpp”文件【英文标题】:CMake/Ninja attempting to compile deleted `.cpp` file 【发布时间】:2015-06-20 01:44:02 【问题描述】:我发现,当我使用cmake
和ninja
从我的项目中删除cpp
文件时,如果不先完全删除我的构建目录并从头开始,我就无法轻松编译它。 CMake 和/或 Ninja 显然隐藏了对其编译的所有 cpp
文件的许多引用,即使在重新运行 CMake 之前删除 CMake 缓存也不会删除所有引用。
这是一个已知问题吗?有解决办法吗?我偶尔只是运行rm $(grep -R <filename> <builddir>)
,但这是一个可怕的组合。
编辑:看来我错了,因为我无法复制这个问题。手动重新运行 CMake 似乎总是生成正确的 .cpp
文件列表,即使使用 GLOB
生成源列表。
【问题讨论】:
您能否添加您的CMakeLists.txt
文件的示例?您是否列出了所有源文件,或者您是否提供file(GLOB ...)
?后者是这种行为的一个可能原因。参见 CMake 的文档: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.
@Florian 是的,我做 glob 文件,但我也会在必要时手动重新运行 CMake(当然,每当我删除 CMake 缓存时)。
Issue 0014820: warn users about removing only CMakeCache.txt 声称您还需要删除所有 CMakeFiles 目录。但我假设您没有缓存源文件列表,因此根据我的经验,重新触发 CMake 配置的最可靠方法是触摸项目 CMakeLists.txt 文件之一(例如使用CMake itselfcmake -E touch CMakeLists.txt
)。跨度>
@Florian 最可靠的方式:为什么不cmake <build-dir>
?
【参考方案1】:
把我的 cmets 变成答案
使用file(GLOB ...)
收集您的源文件
是的,在使用file(GLOB ...)
命令收集源文件时,CMake 不会知道新的或已删除的源文件。这是 CMake 的一个已知限制。因此,我已经更改了我的 CMake 项目以单独列出所有源文件。为方便起见,我仍在使用 file(GLOB ...)
命令收集头文件。
引用 CMake 的 file()
命令文档:
我们不建议使用 GLOB 来收集源文件列表 你的源代码树。如果源是时没有 CMakeLists.txt 文件更改 添加或删除然后生成的构建系统不知道何时 要求 CMake 重新生成。
删除CMakeCache.txt
重新触发配置
仅删除 CMakeCache.txt
可能不足以重新触发 CMake 配置。 Issue 0014820: warn users about removing only CMakeCache.txt 声称您还需要删除所有 CMakeFiles
目录。
根据我的经验,重新触发 CMake 配置的最可靠方法是触摸其中一个项目 CMakeLists.txt
文件。
注意:对于ninja
,CMake 添加了一个rebuild_cache
目标,以便再次为您的项目方便地运行 CMake。
从源代码管理更新后重新触发
想一想:如果源文件被删除是因为它们已从您的源代码管理中删除,那么可能有一种解决方法仍然允许您在源文件上使用file(GLOB ...)
。
例如如果您使用 GIT,您可以将以下内容添加到您的主 CMakeLists.txt
:
configure_file($CMAKE_SOURCE_DIR/.git/index $PROJECT_BINARY_DIR/git_index.tmp)
缺点:它会重新触发每个 GIT 操作(更新、提交、...)的配置。
一些参考资料:
run cmake when adding file in eclipse CMake: Correct way to make an arbitrary file trigger【讨论】:
这是很有价值的信息,但我确实说过我会在必要时手动重新运行 CMake;自动触发重新配置并不是我真正想要的。问题是,即使我手动重新运行 CMake,我似乎也看到了不正确的配置。不过,我需要进行更多调查,以仔细检查我是否可以复制该问题。 @KyleStrand 好的,我承认我以前从未遇到过ninja
的此类问题。我在 Windows 上使用 1.6 版。所以我再次检查了 CMake 的 Ninja 生成器,每次再次运行配置时它都会完全重新生成 rules.ninja
和 build.ninja
。但是.ninja_deps
和.ninja_log
文件确实存在。我建议 - 如果你想要一个干净的 ninja
环境 - 你添加类似 if ("$CMAKE_GENERATOR" MATCHES "Ninja")
file(REMOVE "$CMAKE_BINARY_DIR/.ninja_deps")
endif()
到你的主要 CMakeLists.txt
。
这是个好主意。如果我有空闲时间,我会玩这个并报告。
看来我无法重现该问题;重新运行 CMake 似乎会忽略以前的源文件条目。我想我上次遇到这个问题时可能忘记更改#include
声明。现在,我将投票关闭。以上是关于CMake/Ninja 试图编译已删除的“.cpp”文件的主要内容,如果未能解决你的问题,请参考以下文章
C++学习(四四二)cmake ninja build.ninja rules.ninja
CMake / Ninja:当内容未知时递归“清理”输出目录......?