You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

CMake构建阶段如何读取Python脚本返回的变量?

解决方案

核心问题是混淆了CMake的配置阶段构建阶段execute_process()是在配置阶段执行的,此时elf文件还未生成,必然报错。要实现构建后触发脚本并处理返回值,按以下步骤操作:

1. 构建阶段触发Python脚本并保存返回值

add_custom_target创建依赖elf目标的自定义任务,在构建阶段执行Python脚本,并将返回值写入临时文件(构建阶段无法直接将值传递给CMake变量)。

修改CMakeLists.txt

# 假设${elf_target}是生成elf文件的目标
add_custom_target(run_py_script ALL
  DEPENDS ${elf_target}
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/py_script.py $<TARGET_FILE:${elf_target}>
  COMMAND ${CMAKE_COMMAND} -E echo "$?" > ${CMAKE_CURRENT_BINARY_DIR}/script_ret_val.txt
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
  • DEPENDS ${elf_target}:确保脚本在elf文件生成后才执行
  • $<TARGET_FILE:${elf_target}>:自动获取生成的elf文件绝对路径,避免路径错误
  • echo "$?":将Python脚本的退出码(shell中$?表示前一命令的返回值)写入临时文件script_ret_val.txt

2. 读取返回值并打印对应消息

由于CMake配置阶段早于构建阶段,要处理构建阶段生成的返回值,有两种实现方式:

方式一:构建完成后立即打印结果

扩展add_custom_target,在写入返回值文件后调用CMake脚本读取并打印:

add_custom_target(run_py_script ALL
  DEPENDS ${elf_target}
  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/py_script.py $<TARGET_FILE:${elf_target}>
  COMMAND ${CMAKE_COMMAND} -E echo "$?" > ${CMAKE_CURRENT_BINARY_DIR}/script_ret_val.txt
  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/check_ret_val.cmake
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

创建check_ret_val.cmake脚本:

file(READ script_ret_val.txt ret_val)
string(STRIP "${ret_val}" ret_val) # 去除换行符

if(ret_val EQUAL 0)
  message(STATUS "Python脚本执行结果: Pass.")
else()
  message(STATUS "Python脚本执行结果: Fail.")
endif()

方式二:配置阶段读取上次构建结果

如果想在每次CMake配置时显示上次构建的脚本结果,在CMakeLists.txt中添加:

# 检查返回值文件是否存在
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/script_ret_val.txt)
  file(READ ${CMAKE_CURRENT_BINARY_DIR}/script_ret_val.txt ret_val)
  string(STRIP "${ret_val}" ret_val)
  if(ret_val EQUAL 0)
    message(STATUS "上次Python脚本执行结果: Pass.")
  else()
    message(STATUS "上次Python脚本执行结果: Fail.")
  endif()
else()
  message(STATUS "尚未执行Python脚本.")
endif()

替换原有错误代码

删除你原来的py_script()函数调用和file.cmake文件,改用上述方案即可解决问题。

关键注意事项

  • 始终用$<TARGET_FILE:${elf_target}>获取elf文件绝对路径,避免相对路径引发的文件找不到问题
  • 通过临时文件传递构建阶段的返回值到CMake脚本,这是跨阶段传递数据的可靠方式
  • 严格区分配置阶段和构建阶段的执行时机,不要在配置阶段执行依赖构建产物的逻辑

内容的提问来源于stack exchange,提问作者user30740237

火山引擎 最新活动