在CMake配置时建立程序

时间:2017-01-26 14:53:32

标签: cmake

有没有办法在配置时让CMake构建并运行C ++程序(例如,当你运行cmake .时),但是只有在它尚未构建的情况下?

例如,假设我有一个程序(用C ++编写),它为我的主程序生成版本信息,我想在主程序CMakeLists.txt中使用该版本信息。

我相信您可以通过让主CMakeLists.txt执行cmake作为子流程来实现这一点,但这看起来并不干净。是否有一个更好的官员'方式是什么?

编辑 This基本上是同一个问题,看起来似乎并不是一个很好的方法。

1 个答案:

答案 0 :(得分:2)

我同意评论,在这种情况下,解决您的根本问题可能比直接回答您的问题更容易。这是我如何从git获取分支/版本信息并将其放入我的程序中:

我在支持Windows和几种linux变体的代码库上使用此方法。

创建一个CMake宏以从git中提取信息:

# Get the current Git commit hash
macro(git_information BRANCH_VAR COMMIT_VAR COMMIT_VAR_SHORT)

    # Get the branch name
    execute_process(
    COMMAND git rev-parse --abbrev-ref HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE ${BRANCH_VAR}
    OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    MESSAGE(STATUS "GIT: Current branch -> ${${BRANCH_VAR}}")

    # Retrigger configuration process each time config file changes
    get_filename_component(_cfg_name "${CMAKE_SOURCE_DIR}/.git/refs/heads/${BRANCH}" NAME)
    configure_file("${CMAKE_SOURCE_DIR}/.git/refs/heads/${BRANCH}" "${_cfg_name}.tmp")
    set_source_files_properties(${_cfg_name}.tmp PROPERTIES GENERATED true)

    # Get the head commit
    execute_process(
    COMMAND git rev-parse HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE ${COMMIT_VAR}
    OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    MESSAGE(STATUS "GIT: Current commit -> ${${COMMIT_VAR}}")

    # Get the short version of the head commit
    execute_process(
    COMMAND git rev-parse --short HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE ${COMMIT_VAR_SHORT}
    OUTPUT_STRIP_TRAILING_WHITESPACE
    )

endmacro()

然后在顶级CMakeLists.txt中调用宏:

find_package(Git)
if(GIT_FOUND)
    git_information(BRANCH GIT_COMMIT GIT_COMMIT_SHORT)
ELSE()
    # as a fallback, use the directory name as the branch name
    GET_FILENAME_COMPONENT(BRANCH ${CMAKE_CURRENT_SOURCE_DIR} NAME)
ENDIF()

要真正将信息输入程序,我会使用configure_file(如果您不熟悉,请参阅documentation):

configure_file(include/version.h.in version.h @ONLY NEWLINE_STYLE LF)

并且该文件看起来像这样:

#include <string>

namespace myProg
{
    static const std::string BRANCH("@BRANCH@");
    static const std::string GIT_COMMIT("@GIT_COMMIT@");
    static const std::string GIT_COMMIT_SHORT("@GIT_COMMIT_SHORT@");
}

你可以想象,通过使用适当的git命令添加额外的execute_process块,宏也可用于从git中提取标记或描述性信息。