如何在每次调用特定make目标时通过命令行更新CMake变量?
实现每次执行
make package时动态更新版本号的CMake方案 要解决execute_process仅在配置阶段执行、版本号硬编码的问题,核心思路是把版本号的生成逻辑从CMake配置阶段延迟到make package的执行阶段,以下是两种实用方案:
方案一:通过版本文件动态传递版本号
利用自定义目标在打包前生成包含最新版本信息的文件,让CPACK从该文件读取版本号,确保每次打包都用最新值。
步骤1:编写版本生成脚本
在项目根目录创建GenerateVersion.cmake脚本,负责获取当前日期并写入版本文件:
execute_process( COMMAND date +'%Y-%m-%d' OUTPUT_VARIABLE CURRENT_DATE OUTPUT_STRIP_TRAILING_WHITESPACE # 去除输出末尾的换行符 ) file(WRITE "${CMAKE_BINARY_DIR}/version.txt" "${CURRENT_DATE}")
步骤2:修改主CMakeLists.txt配置
# 初始生成版本文件(第一次执行cmake时确保文件存在) if(NOT EXISTS "${CMAKE_BINARY_DIR}/version.txt") execute_process( COMMAND ${CMAKE_COMMAND} -P "${CMAKE_SOURCE_DIR}/GenerateVersion.cmake" ) endif() # 从版本文件读取版本号 file(READ "${CMAKE_BINARY_DIR}/version.txt" CPACK_PACKAGE_VERSION_MAJOR) # 创建自定义目标:每次执行时重新生成版本文件 add_custom_target(generate_version COMMAND ${CMAKE_COMMAND} -P "${CMAKE_SOURCE_DIR}/GenerateVersion.cmake" BYPRODUCTS "${CMAKE_BINARY_DIR}/version.txt" # 告诉CMake文件会被更新 ) # 让package目标依赖generate_version,确保打包前先更新版本 add_dependencies(package generate_version) INCLUDE(CPack)
这样每次执行make package时,会先运行generate_version目标更新version.txt,CPACK读取最新的版本号后再生成deb包。
方案二:自定义package目标直接传递版本变量
绕过默认的CPack package目标,自己实现打包逻辑,在执行CPack前动态获取版本号并传递。
步骤1:编写CPack执行脚本
创建RunCPack.cmake脚本,负责加载CPack并使用传递进来的版本号打包:
# 接收外部传递的版本变量 if(NOT DEFINED CPACK_PACKAGE_VERSION_MAJOR) message(FATAL_ERROR "CPACK_PACKAGE_VERSION_MAJOR is not set") endif() INCLUDE(CPack) # 执行CPack的完整打包流程 cpack_configure(DEFAULT) cpack_generate(DEFAULT) cpack_install(DEFAULT)
步骤2:修改主CMakeLists.txt配置
# 不直接INCLUDE(CPack),避免生成默认的package目标 # INCLUDE(CPack) # 自定义package目标:先获取最新版本,再调用CPack脚本 add_custom_target(package COMMAND ${CMAKE_COMMAND} -E env CURRENT_VERSION=$(date +'%Y-%m-%d') ${CMAKE_COMMAND} -DCPACK_PACKAGE_VERSION_MAJOR="$ENV{CURRENT_VERSION}" -P "${CMAKE_SOURCE_DIR}/RunCPack.cmake" COMMENT "Generating package with version: $ENV{CURRENT_VERSION}" )
这个方案直接在打包时通过环境变量传递最新版本号给CPack脚本,无需中间文件,逻辑更直接。
注意事项
- 方案一中,
BYPRODUCTS关键字是CMake 3.2+才支持的,如果使用旧版本,可以用ADD_DEPENDENCIES配合CMAKE_CURRENT_BINARY_DIR的文件依赖替代。 - 两种方案都可以扩展到其他外部程序生成版本号的场景,比如从Git提交记录生成版本字符串,只需要修改
GenerateVersion.cmake或date命令为对应的Git命令即可。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

