CMake/Ninja 试图编译已删除的 `.cpp` 文件

2021-12-26 00:00:00 cmake c++ ninja

我发现当我使用 cmakeninja 从我的项目中删除 cpp 文件时,我无法轻松编译它首先完全删除我的构建目录并从头开始.CMake 和/或 Ninja 显然会删除对其编译的所有 cpp 文件的大量引用,即使在重新运行 CMake 之前删除 CMake 缓存也不会删除所有引用.

I've found that when I delete cpp files from my project using cmake and ninja, I can't easily compile it without first completely deleting my build directory and starting from scratch. CMake and/or Ninja apparently squirrels away a number of references to all the cpp files that it compiles, even deleting the CMake cache before re-running CMake doesn't remove all the references.

这是一个已知问题吗?有解决办法吗?我偶尔会运行 rm $(grep -R <filename> <builddir>),但这是一个糟糕的麻烦.

Is this a known issue? Is there a solution? I've occasionally just run rm $(grep -R <filename> <builddir>), but that's a terrible kludge.

看来我错了,因为我无法复制这个问题.手动重新运行 CMake 似乎总是生成正确的 .cpp 文件列表,甚至使用 GLOB 生成源列表.

It appears I was mistaken, as I have not been able to duplicate this problem. Manually re-running CMake appears to always generate the correct list of .cpp files, even using GLOB to generate lists of sources.

推荐答案

将我的评论变成答案

是的,在使用 file(GLOB ...) 命令收集源文件时,CMake 不会知道新的或删除的源文件.这是 CMake 的一个已知限制.正是因为这个,我已经更改了我的 CMake 项目以单独列出所有源文件.为方便起见,我仍然使用 file(GLOB ...) 命令收集我的头文件.

Yes, CMake won't know about new or deleted source files when collecting your source files with the file(GLOB ...) command. This is a known restriction with CMake. I've changed my CMake project(s) to list all source files individually exactly because of this. Out of convenience I'm still collecting my header files with the file(GLOB ...) command.

引用 CMake 的 file() 命令文档:

Quoting from CMake's file() command documentation:

我们不建议使用 GLOB 从以下位置收集源文件列表你的源代码树.如果在源文件中没有 CMakeLists.txt 文件更改添加或删除然后生成的构建系统不知道何时要求 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.

删除CMakeCache.txt以重新触发配置

仅删除 CMakeCache.txt 可能不足以重新触发 CMake 配置.问题 0014820:警告用户只删除您需要的 CMakeCache.txt 声明还要删除所有 CMakeFiles 目录.

Deleting CMakeCache.txt to retrigger Configuration

Just deleting CMakeCache.txt may not be enough to retrigger the CMake configuration. Issue 0014820: warn users about removing only CMakeCache.txt claims you need also to delete all CMakeFiles directories.

根据我的经验,重新触发 CMake 配置的最可靠方法是访问项目 CMakeLists.txt 文件之一.

From my experience the most reliable way to retrigger the CMake configuration is to touch one of the projects CMakeLists.txt files.

注意:对于 ninja,CMake 添加了一个 rebuild_cache 目标,以便于再次为您的项目运行 CMake.

Note: For ninja CMake adds a rebuild_cache target for conveniently running CMake for your project again.

一个想法:如果删除源文件是因为它们已从源代码管理中删除,那么可能有一种解决方法仍然允许您在源文件上使用 file(GLOB ...).

Just one thought: if the deletion of source files happens because they were removed from your source control there maybe a workaround that still allows you to use file(GLOB ...) on your source files.

例如如果您使用 GIT,您可以将以下内容添加到您的主要 CMakeLists.txt:

E.g. if you use GIT you could add the following to your main CMakeLists.txt:

configure_file(${CMAKE_SOURCE_DIR}/.git/index ${PROJECT_BINARY_DIR}/git_index.tmp) 

缺点:它会重新触发每个 GIT 操作(更新、提交、...)的配置.

Disadvantage: It would retrigger configuration which each GIT operation (update, commit, ...).

一些参考资料:

  • 在eclipse中添加文件时运行cmake
  • CMake:触发任意文件的正确方法

相关文章