移除编译单元后如何避免执行全量清理编译
CMake首次生成构建配置时,会把所有待编译源文件的路径写入生成的Makefile规则中。你手动删除Spring.cpp、Spring.h之后,旧的构建规则没有同步更新,make仍然按照原有逻辑尝试编译已经不存在的Spring.cpp,就会触发该报错。全量执行cmake ..会重新扫描整个项目的依赖、编译选项、第三方库路径,因此耗时长,用下面的方法可以快速修复,不需要全量重配,也不会删除已编译好的文件触发无意义的全量重编。
直接进入你平时执行make的构建目录,执行以下命令:
# 删除失效的旧编译目标和对应的依赖记录 rm sandbox/CMakeFiles/game.dir/src/components/Spring.cpp.o rm sandbox/CMakeFiles/game.dir/src/components/Spring.cpp.o.d # 正常执行make即可 make
这个操作只会移除已经失效的单个源文件的构建记录,make检测到对应条目缺失后,会自动调用CMake更新和该路径相关的极小部分配置,不会扫描整个项目,也不会影响其他已经编译完成的目标文件。
不需要回到源码目录重新执行cmake ..,直接在当前构建目录执行:
cmake .
注意命令最后是当前目录符号.,不是上级目录..。该操作会基于现有构建缓存做增量配置更新,只会检测文件列表的变动,不会重置所有已缓存的配置检测结果,耗时只有全量重新生成配置的1/10甚至更短,更新完成后再执行make即可。
如果你在CMakeLists.txt中使用file(GLOB)或者file(GLOB_RECURSE)自动递归收集源文件,CMake默认不会自动监听源码目录的文件增删,可以在对应的源文件收集逻辑后添加配置:
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${YOUR_SOURCE_DIR})
将${YOUR_SOURCE_DIR}替换为你实际存放源码的目录,后续增删源文件时,make会自动检测变动更新构建规则,不需要额外手动操作。
注意:不要直接执行
make clean,该命令会删除所有已编译好的目标文件,反而会触发全量重编译,浪费编译时间。
内容的提问来源于stack exchange,提问作者frankelot

