如何配置CMake的ExternalProject_Add实现每日仅更新一次?
优化CMake外部项目(如Googletest)的构建时间,避免重复更新检查
我最近在优化项目构建速度时,刚好碰到了和你一样的问题——在顶层CMakeLists.txt里引入googletest这类外部项目后,每次重新编译都要耗15秒左右处理它们,哪怕代码完全没变动,实在头疼。
快速解决:禁用每次构建的更新检查
最直接的办法就是给ExternalProject_Add指令加上UPDATE_COMMAND "",这样CMake会直接跳过更新检查步骤,立刻省下那15秒。示例代码如下:
ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG main UPDATE_COMMAND "" # 完全禁用更新检查 # 你的其他配置(比如CMAKE_ARGS、INSTALL_COMMAND等) )
这个方法立竿见影,但缺点是如果googletest有更新,你得手动去掉这个配置才能拉取最新代码。
理想方案:超过一天自动更新,无需手动修改
如果想要实现「本地克隆超过一天才自动检查更新」的效果,不用来回手动改配置,可以结合CMake的时间函数和git命令来动态控制更新行为:
核心思路是:
- 获取当前时间戳
- 获取本地googletest仓库的最后更新时间戳
- 计算两者的时间差,若超过86400秒(一天),则使用默认的更新逻辑;否则跳过更新检查
具体实现代码如下:
# 获取当前UTC时间戳(单位:秒) string(TIMESTAMP CURRENT_TIMESTAMP "%s" UTC) # 假设googletest的源码目录是${CMAKE_CURRENT_BINARY_DIR}/googletest-src # 获取该仓库最后一次提交的时间戳 execute_process( COMMAND git log -1 --format=%cd --date=raw WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-src OUTPUT_VARIABLE LAST_UPDATE_RAW OUTPUT_STRIP_TRAILING_WHITESPACE ) # 提取git输出中的时间戳部分(格式为"timestamp 时区偏移",取第一个字段) string(REGEX REPLACE " .*" "" LAST_UPDATE_TIMESTAMP ${LAST_UPDATE_RAW}) # 计算时间差,判断是否超过一天 math(EXPR TIME_DIFF "${CURRENT_TIMESTAMP} - ${LAST_UPDATE_TIMESTAMP}") # 动态设置更新命令:不到一天则禁用更新,超过一天则使用默认逻辑 if(TIME_DIFF LESS 86400) set(GTEST_UPDATE_COMMAND "") else() # 不设置UPDATE_COMMAND,让CMake使用默认的更新行为 unset(GTEST_UPDATE_COMMAND) endif() # 引入googletest外部项目 ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG main UPDATE_COMMAND ${GTEST_UPDATE_COMMAND} # 你的其他配置项 )
这样配置后,日常开发时构建速度不会受影响,每隔至少一天CMake会自动检查一次googletest的更新,完美平衡了构建效率和依赖的新鲜度。
内容的提问来源于stack exchange,提问作者dani
相关产品推荐
相关产品推荐

