如何通过CMake实现获取C++静态库Mercurial变更集的函数
实现多静态库Mercurial版本汇总函数的方案
核心逻辑
通过CMake在构建流程中自动生成包含get_libs_versions()的源文件:每个静态库的Mercurial变更集在CMake配置阶段提取,汇总后写入生成的C++代码,最终编译成可被使用者调用的模块。
1. 单个库的变更集提取
在每个静态库的CMakeLists.txt中添加以下逻辑,提取当前库代码目录的Mercurial变更集,并传递到顶层作用域:
find_package(Hg QUIET) if(HG_FOUND) execute_process( COMMAND ${HG_EXECUTABLE} id -i WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE ${PROJECT_NAME}_CHANGESET OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() set(${PROJECT_NAME}_CHANGESET ${${PROJECT_NAME}_CHANGESET} PARENT_SCOPE)
2. 汇总变更集并生成代码
第一步:创建代码模板文件
在项目根目录创建version_info.in.cpp模板:
#include <string> std::string get_libs_versions() { std::string versions; @VERSION_ENTRIES@ return versions; }
第二步:顶层CMake配置生成代码
在项目顶层CMakeLists.txt中,收集所有库的变更集,替换模板中的占位符,生成最终的源文件:
# 替换为你实际的静态库名称列表 set(LIBRARY_LIST lib1 lib2) # 拼接版本信息的代码片段 set(VERSION_ENTRIES "") foreach(LIB_NAME IN LISTS LIBRARY_LIST) if(DEFINED ${LIB_NAME}_CHANGESET) string(APPEND VERSION_ENTRIES "versions += \"${LIB_NAME}_changeset=${${LIB_NAME}_CHANGESET}\\n\\n\";") else() string(APPEND VERSION_ENTRIES "versions += \"${LIB_NAME}_changeset=unknown\\n\\n\";") endif() endforeach() # 生成目标源文件 configure_file( ${CMAKE_SOURCE_DIR}/version_info.in.cpp ${CMAKE_BINARY_DIR}/generated/version_info.cpp @ONLY ) # 将生成的代码编译为静态库,供使用者链接 add_library(version_info STATIC ${CMAKE_BINARY_DIR}/generated/version_info.cpp) # 暴露头文件目录,确保使用者能找到声明 target_include_directories(version_info PUBLIC ${CMAKE_SOURCE_DIR}/include)
3. 提供函数声明头文件
在include目录下创建version_info.h:
#pragma once #include <string> std::string get_libs_versions();
4. 使用者调用示例
使用者只需包含头文件,链接version_info库后即可调用:
#include "version_info.h" #include <iostream> int main() { std::cout << get_libs_versions() << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者ilya
相关产品推荐
相关产品推荐

