如何在CMakeLists.txt任意位置强制CMake生成Makefile构建文件?
在基于raspberrypi/pico-sdk的CMake项目中,存在一段条件执行逻辑:当myCONDITION等于Something时,调用pico_sdk_init()后,原本通过return()提前退出CMake配置流程,此时Build目录会生成Makefile,可手动执行make pioasmBuild成功构建pioasm.exe。
但去掉return()改用execute_process直接调用构建命令时,会报错Error: could not load cache——因为此时CMake仍处于配置阶段,还未生成Build目录下的Makefile,无法执行构建操作。
需求是:在CMakeLists.txt的该位置,强制CMake基于当前已有配置数据生成可用的构建文件(Makefile),无需提前退出CMake进程,后续仍可继续执行剩余配置代码,且最终CMake配置完成时,构建文件会被正常覆盖更新。
核心思路是在当前CMake配置进程中,启动一个子CMake进程完成临时配置与构建文件生成,再执行目标构建,之后回到原进程继续执行剩余逻辑。具体实现如下:
1. 子进程完成临时配置
显式传递当前进程的关键缓存变量(确保子进程配置与原进程一致),启动子CMake进程完成当前二进制目录的配置,生成可用的Makefile:
execute_process( COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DPICO_SDK_PATH=${PICO_SDK_PATH} # 按需添加项目必需的其他缓存变量,比如交叉编译参数等 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE SUB_CONFIG_RESULT ) # 检查子进程配置是否成功 if(NOT SUB_CONFIG_RESULT EQUAL 0) message(FATAL_ERROR "Failed to configure temporary build env for pioasm") endif()
2. 执行pioasmBuild目标构建
子进程生成Makefile后,即可调用构建命令完成pioasmBuild目标的编译:
execute_process( COMMAND ${CMAKE_COMMAND} --build . --target pioasmBuild WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE PIOASM_BUILD_RESULT ) if(NOT PIOASM_BUILD_RESULT EQUAL 0) message(FATAL_ERROR "Failed to build pioasm") endif()
3. 继续原配置流程
完成pioasmBuild构建后,原CMake进程会继续执行剩余配置代码,最终生成完整的构建文件(会覆盖子进程生成的临时Makefile),不影响后续正常构建流程。
# ... if(myCONDITION STREQUAL "Something") message("*** BEFORE pico_sdk_init() ***") pico_sdk_init() # 临时配置生成构建文件 execute_process( COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DPICO_SDK_PATH=${PICO_SDK_PATH} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE SUB_CONFIG_RESULT ) if(NOT SUB_CONFIG_RESULT EQUAL 0) message(FATAL_ERROR "Temporary config for pioasm failed") endif() # 构建pioasm目标 execute_process( COMMAND ${CMAKE_COMMAND} --build . --target pioasmBuild WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE PIOASM_BUILD_RESULT ) if(NOT PIOASM_BUILD_RESULT EQUAL 0) message(FATAL_ERROR "Building pioasm failed") endif() message("*** pioasm build completed, continuing config ***") # 其他CMake条件代码... endif() # myCONDITION STREQUAL "Something" # ...
内容的提问来源于stack exchange,提问作者sdbbs

