Android NDK CMake编译前后执行自定义命令问题咨询
解决Android NDK CMake中PRE_BUILD时机不符合预期的问题
我明白你的困扰——用TARGET级别的PRE_BUILD自定义命令时,修改源文件的操作总是赶不上编译步骤的时机,这其实是CMake对不同自定义命令时机的设计逻辑导致的。
为什么你的原有配置不生效?
add_custom_command(TARGET ... PRE_BUILD)的执行时机是整个目标(比如你的native-lib库)开始构建之前,但CMake在配置阶段就已经扫描并缓存了源文件的依赖信息。如果你的修改操作只是在目标构建前触发,CMake可能不会把“源文件被修改”这个事件和后续的编译步骤关联起来——要么编译时用的还是修改前的文件,要么并行构建时编译步骤和修改操作同时执行,结果完全不符合预期。
推荐解决方案:用临时文件编译(安全无副作用)
最稳妥的方式是复制原文件到临时位置,修改临时文件后编译它,编译完成后清理临时文件,完全不用改动原文件,也就不需要额外的恢复操作了。示例配置如下:
# 定义原源文件路径 set(ORIGINAL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/native-lib.c) # 定义编译用的临时修改文件(放在构建目录里,不污染源码) set(MODIFIED_SRC ${CMAKE_CURRENT_BINARY_DIR}/native-lib-modified.c) # 自定义命令:生成修改后的临时文件 add_custom_command( OUTPUT ${MODIFIED_SRC} # 这里替换成你的修改脚本/命令,比如调用shell脚本 COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/modify-script.sh ${ORIGINAL_SRC} ${MODIFIED_SRC} # 告诉CMake:原文件变化时重新执行这个命令 DEPENDS ${ORIGINAL_SRC} COMMENT "Preprocessing source file before compilation..." ) # 把临时修改文件作为库的源文件,而不是原文件 add_library(native-lib SHARED ${MODIFIED_SRC}) # 可选:编译完成后清理临时文件 add_custom_command( TARGET native-lib POST_BUILD COMMAND rm -f ${MODIFIED_SRC} COMMENT "Cleaning up temporary modified file..." )
如果你的修改只是简单的字符串替换,甚至可以不用外部脚本,直接用CMake内置命令完成,更跨平台:
file(READ ${ORIGINAL_SRC} SRC_CONTENT) # 替换你需要修改的字符串 string(REPLACE "old_token" "new_token" MODIFIED_CONTENT ${SRC_CONTENT}) file(WRITE ${MODIFIED_SRC} ${MODIFIED_CONTENT})
如果你必须修改原文件(不推荐)
如果因为某些限制只能修改原文件,那需要让CMake明确知道“源文件会被修改,必须在编译前完成修改”。可以通过把原文件标记为自定义命令的输出来实现:
set(SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/native-lib.c) # 自定义命令:修改原文件,输出就是原文件本身(告诉CMake这个命令会修改它) add_custom_command( OUTPUT ${SRC_FILE} COMMAND <你的修改命令> DEPENDS ${SRC_FILE} COMMENT "Modifying original source file..." ) # 构建库,依赖修改后的源文件 add_library(native-lib SHARED ${SRC_FILE}) # 编译完成后恢复原文件 add_custom_command( TARGET native-lib POST_BUILD COMMAND <你的恢复命令> COMMENT "Restoring original source file..." )
⚠️ 注意:这种方式有风险,如果构建中途中断,你的原文件会停留在修改后的状态,所以优先推荐第一种临时文件的方案。
内容的提问来源于stack exchange,提问作者solidak
相关产品推荐
相关产品推荐

