CMake生成的目标文件时间早于编译时间的原因与解决方法
构建产物时间早于构建操作时间的成因与解决方法
可能的成因
- 文件系统时间不同步:如果构建目录在NFS这类远程挂载的文件系统上,服务器和本地客户端时间没对齐(比如服务器时间比客户端慢),产物文件的时间戳会用服务器的,自然比本地构建操作的时间早。
- 拷贝/安装时继承旧时间:CMake的
install命令或者自定义的cp -p操作默认会保留源文件的时间戳。要是源文件是之前构建的旧文件,新生成的产物就会带着旧时间。 - 系统时间突然回退:构建过程中NTP同步把系统时间从错误的未来时间调回正常时间,这时候生成的产物时间就是调整后的正确时间,看起来比构建开始的时间早。
- 编译缓存复用旧时间:用
ccache这类缓存工具的话,命中缓存时会直接复用之前生成的目标文件,时间戳还是首次生成的时间,自然早于本次构建时间。
解决办法
- 对齐时间同步:
- 检查本地系统时间,确保
chronyd(SLES 15 SP1默认NTP服务)正常运行,修改/etc/chrony.conf里的makestep参数,让时间平滑调整,避免大幅跳变。 - 如果用了远程挂载的文件系统,确认服务器和客户端时间完全同步。
- 检查本地系统时间,确保
- 修改CMake的拷贝/安装规则:
- 用
install命令时加--no-preserve=timestamps参数,不保留源文件时间:install(TARGETS your_target DESTINATION bin COMMAND install --no-preserve=timestamps $<TARGET_FILE:your_target> ${CMAKE_INSTALL_PREFIX}/bin/ ) - 自定义拷贝逻辑时,别用
cp -p,直接用普通cp。
- 用
- 强制更新产物时间:
- 在CMake目标里加Post-build命令,构建完直接更新产物的时间戳:
add_custom_command(TARGET your_target POST_BUILD COMMAND touch $<TARGET_FILE:your_target> COMMAND touch $<TARGET_OBJECTS:your_target> # 如果需要更新.o文件的时间 )
- 在CMake目标里加Post-build命令,构建完直接更新产物的时间戳:
- 调整缓存工具设置:
- 用
ccache的话,设置CCACHE_TIMESTAMP=1环境变量,让缓存返回文件时更新时间戳;或者直接在CMake里禁用ccache:set(CMAKE_CXX_COMPILER_LAUNCHER "") set(CMAKE_C_COMPILER_LAUNCHER "")
- 用
- Make参数调整:
- 构建时给Make加
--no-touch参数,禁止它通过touch操作更新目标时间(只有当Make的默认touch逻辑引发问题时才用):cmake --build . -- -j$(nproc) --no-touch
- 构建时给Make加
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

