CMake执行make clean时Qt翻译.ts文件被误删的技术问询
为什么
make clean会删除你的tr.ts? 当你用add_custom_command把tr.ts声明为OUTPUT时,CMake会把这个文件认定为构建过程生成的产物——哪怕它存在于源码目录里。而make clean的核心逻辑就是清理所有CMake标记为“生成出来的”文件,所以你的翻译文件会被误删。
不用禁用自定义清理的解决办法
我给你两个靠谱的方案,优先推荐第一个,符合CMake的最佳实践:
方案1:把翻译文件生成到构建目录(推荐)
虽然你担心源码里的新翻译无法同步,但我们可以调整流程,让构建目录的tr.ts作为工作文件,再加一个自定义目标把更新后的文件同步回源码目录。这样既避免clean误删源码文件,又能顺畅管理翻译更新:
修改你的CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.7) find_package(Qt5LinguistTools REQUIRED) # 把ts文件生成到构建目录,和源码目录彻底隔离 set(TS_BUILD_FILE ${CMAKE_CURRENT_BINARY_DIR}/tr.ts) # 源码目录里的ts作为最终保存的文件 set(TS_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tr.ts) # 生成/更新构建目录的ts文件 add_custom_command(OUTPUT ${TS_BUILD_FILE} COMMAND ${Qt5_LUPDATE_EXECUTABLE} -target-language en ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -ts ${TS_BUILD_FILE} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp COMMENT "Updating translation file in build directory..." ) # 基础目标:更新构建目录的ts add_custom_target(update_ts DEPENDS ${TS_BUILD_FILE}) # 新增同步目标:把构建目录的ts复制回源码目录(需要手动触发,比如执行`make sync_ts`) add_custom_target(sync_ts COMMAND ${CMAKE_COMMAND} -E copy ${TS_BUILD_FILE} ${TS_SOURCE_FILE} DEPENDS ${TS_BUILD_FILE} COMMENT "Syncing translation file to source directory..." )
操作流程变成:
- 执行
make update_ts:在构建目录生成或更新tr.ts,抓取main.cpp里的新翻译字符串 - 当你在构建目录的
tr.ts里完成翻译后,执行make sync_ts,把修改后的文件同步回源码目录保存 make clean只会删除构建目录里的临时产物,源码目录的tr.ts完全安全
方案2:标记源码目录的ts为非生成文件
如果你坚持要在源码目录直接生成tr.ts,可以告诉CMake不要把这个文件当作构建产物,这样make clean就不会碰它了:
修改CMakeLists.txt:
cmake_minimum_required(VERSION 3.7) find_package(Qt5LinguistTools REQUIRED) set(TS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tr.ts) # 关键:标记这个文件不是CMake生成的产物,避免clean删除 set_source_files_properties(${TS_FILE} PROPERTIES GENERATED FALSE) # 自定义命令:只有当ts不存在或者main.cpp更新时,才运行lupdate add_custom_command(OUTPUT ${TS_FILE} COMMAND ${Qt5_LUPDATE_EXECUTABLE} -target-language en main.cpp -ts ${TS_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ) add_custom_target(foo DEPENDS ${TS_FILE})
这个方案的好处是不用改变文件位置,但缺点是源码目录会混入构建生成的文件,不符合CMake“源码与构建分离”的最佳实践,而且如果手动删除了源码里的tr.ts,CMake会自动重新生成它。
补充说明
你之前尝试的set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1)确实只对Makefile生成器有效,而且它的作用是禁止清理自定义目标的输出,但前提是CMake没有把文件标记为GENERATED。如果用方案2配合这个选项,会更保险,但通用性还是不如方案1。
内容的提问来源于stack exchange,提问作者piwi
相关产品推荐
相关产品推荐

