• CMake教程小结


    CMake教程小结

    简介

    CMake教程通过一个示例项目, 逐步介绍了CMake构建系统的主要功能, 包括:

    1. 生成执行程序
    2. 生成库(使用旧式CMake宏定义方法)
    3. 生成库(使用新式CMake宏定义方法--使用要求)
    4. 基于源代码的安装与测试
    5. 系统检测
    6. 添加自定义命令以及生成文件
    7. 构建安装程序
    8. 将测试结果提交到Kitware的公共指示板
    9. 混合静态和共享(动态)库
    10. 生成器表达式,条件判断
    11. find_package()支持(添加导出配置)
    12. 将调试版和发行版打包在一起(win10试验没有成功)

    注:

    1. 示例项目目录在CMake源代码树的Helpguide utorial目录
    2. 本摘要主要关注CMake使用, 一些关于源代码的更改在请查看CMake教程
    3. CMake教程示例代码,下一步的内容都是上一步的结果

    主要功能摘要

    1. 生成执行程序

    本节示例展示了:

    • 生成执行程序的基本构建系统框架;
    • 将一些CMake属性通过配置文件输出;
    • 如何在目标中添加头文件搜索路径;
    • 常规CMake命令行使用方式

    注: 本节示例初始代码在示例目录的Step1子目录, 成果在Step2子目录

    核心代码

    顶层目录的CMakeLists.txt内容如下:

    # 指定CMake最小版本
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名称及版本号
    project(Tutorial VERSION 1.0)
    
    # 指定C++版本
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # 配置头文件, 将一些CMake属性值保存到源代码中
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    # 生成执行程序
    add_executable(Tutorial tutorial.cxx)
    
    # 将项目输出目录(binary tree)添加到Tutorial目标的头文件搜索路径, 这样才能找到生成的TutorialConfig.h
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
                               )
    

    TutorialConfig.h.in内容如下:

    // 接受CMake配置属性
    #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
    #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
    

    命令行使用示例

    在项目目录下

    $ mkdir build
    $ cd build
    $ cmake ..
    $ cmake --build .
    

    2. 生成库(旧式CMake)

    在上一步的基础上, 本节示例展示了:

    • 生成库;
    • 在项目中添加库;
    • 使用可选项,并将可选项保存到配置文件中;
    • 目标链接库的旧式方法;
    • 目标包含库头文件目录的旧式方法;

    注: 本节示例初始代码在示例目录的Step2子目录, 成果在Step3子目录

    生成库

    1. 创建库目录;
    2. 在库目录CMakeLists.txt中, 添加生成库命令如下:
    # 生成库
    add_library(MathFunctions mysqrt.cxx)
    

    其它核心代码

    项目CMakeLists.txt内容如下:

    # 指定CMake最小版本
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名称及版本号
    project(Tutorial VERSION 1.0)
    
    # 指定C++版本
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # 是否使用自定义数学库可选项
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    
    # 配置头文件, 将一些CMake属性值保存到源代码中
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    # 添加自定义数学库
    if(USE_MYMATH)
      add_subdirectory(MathFunctions)
      list(APPEND EXTRA_LIBS MathFunctions)
      list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
    endif()
    
    # 生成执行程序
    add_executable(Tutorial tutorial.cxx)
    
    # Tutorial目标链接相关库
    target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
    
    # Tutorial目标添加头文件搜索路径(项目生成目录,其它头文件目录)
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
                               ${EXTRA_INCLUDES}
                               )
    

    TutorialConfig.h.in内容如下:

    // 接受CMake配置属性
    #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
    #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
    #cmakedefine USE_MYMATH
    

    3. 生成库(新式CMake)

    在上一步的基础上, 本节示例展示了:

    • 在库中使用INTERFACE;
    • 在项目中添加库;
    • 使用可选项,并将可选项保存到配置文件中;
    • 目标链接库的旧式方法;
    • 目标包含库头文件目录的旧式方法;

    注: 本节示例初始代码在示例目录的Step3子目录, 成果在Step4子目录

    核心代码更改

    库目录CMakeLists.txt内容如下:

    # 生成库
    add_library(MathFunctions mysqrt.cxx)
    
    # 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要
    # 通过INTERFACE可以将头文件搜索路径转递给使用者
    target_include_directories(MathFunctions
              INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
              )
    

    项目CMakeLists.txt删除了EXTRA_INCLUDES相关代码, 变化如下:

    # 指定CMake最小版本
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名称及版本号
    project(Tutorial VERSION 1.0)
    
    # 指定C++版本
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # 是否使用自定义数学库可选项
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    
    # 配置头文件, 将一些CMake属性值保存到源代码中
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    # 添加自定义数学库
    if(USE_MYMATH)
      add_subdirectory(MathFunctions)
      list(APPEND EXTRA_LIBS MathFunctions)
    endif()
    
    # 生成执行程序
    add_executable(Tutorial tutorial.cxx)
    
    # Tutorial目标链接相关库(此代码会使用新式CMake方法传递库属性)
    target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
    
    # Tutorial目标添加头文件搜索路径
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
                               )
    

    4. 基于源代码的安装与测试

    在上一步的基础上, 本节示例展示了:

    • 使用基于源代码的安装规则(install);
    • 使用测试;

    注: 本节示例初始代码在示例目录的Step4子目录, 成果在Step5子目录

    核心代码更改

    库目录CMakeLists.txt变化如下:

    # 生成库
    add_library(MathFunctions mysqrt.cxx)
    
    # 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要
    # 通过INTERFACE可以将头文件搜索路径转递给使用者
    target_include_directories(MathFunctions
              INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
              )
    
    # 安装规则
    install(TARGETS MathFunctions DESTINATION lib)
    install(FILES MathFunctions.h DESTINATION include)
    

    项目CMakeLists.txt新增了安装与测试相关代码, 变化如下:

    # 指定CMake最小版本
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名称及版本号
    project(Tutorial VERSION 1.0)
    
    # 指定C++版本
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # 是否使用自定义数学库可选项
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    
    # 配置头文件, 将一些CMake属性值保存到源代码中
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    # 添加自定义数学库
    if(USE_MYMATH)
      add_subdirectory(MathFunctions)
      list(APPEND EXTRA_LIBS MathFunctions)
    endif()
    
    # 生成执行程序
    add_executable(Tutorial tutorial.cxx)
    
    # Tutorial目标链接相关库(此代码会使用新式CMake方法传递库属性)
    target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
    
    # Tutorial目标添加头文件搜索路径
    target_include_directories(Tutorial PUBLIC
                               "${PROJECT_BINARY_DIR}"
                               )
    
    # 添加安装目标
    install(TARGETS Tutorial DESTINATION bin)
    install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
      DESTINATION include
      )
    
    # 开启测试
    enable_testing()
    
    # 验证Tutorial正常运行
    add_test(NAME Runs COMMAND Tutorial 25)
    
    # 验证Tutorial的使用方法提示
    add_test(NAME Usage COMMAND Tutorial)
    set_tests_properties(Usage
      PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
      )
    
    # 定义函数以简化测试添加
    function(do_test target arg result)
      add_test(NAME Comp${arg} COMMAND ${target} ${arg})
      set_tests_properties(Comp${arg}
        PROPERTIES PASS_REGULAR_EXPRESSION ${result}
        )
    endfunction(do_test)
    
    # 批量添加基于结果的测试
    do_test(Tutorial 4 "4 is 2")
    do_test(Tutorial 9 "9 is 3")
    do_test(Tutorial 5 "5 is 2.236")
    do_test(Tutorial 7 "7 is 2.645")
    do_test(Tutorial 25 "25 is 5")
    do_test(Tutorial -25 "-25 is [-nan|nan|0]")
    do_test(Tutorial 0.0001 "0.0001 is 0.01")
    

    命令行使用示例

    将调试版安装D:Temp2 ttdebug

    $ mkdir build
    $ cd build
    $ cmake ..
    生成并安装调试版
    $ cmake --build .
    $ cmake --install . --prefix D:Temp2	ttdebug --config Debug
    生成并安装发行版
    $ cmake --build . -- config Release
    $ cmake --install . --prefix D:Temp2	ttRelease --config Release
    

    win10 VS2019 测试

    build目录测试应用程序

    $ mkdir build
    $ cd build
    $ cmake ..
    生成并测试调试版
    $ cmake --build .
    $ ctest -C Debug [-vv]
    生成并测试发行版
    $ cmake --build . -- config Release
    $ ctest -C Release [-vv]
    

    5. 系统检测

    在上一步的基础上, 本节示例展示了:

    • CMake系统功能检测, 以判断平台是否支持特定功能;
    • 目标编译定义(宏定义);

    注1: 本节示例初始代码在示例目录的Step5子目录, 成果在Step6子目录
    注2: 在win10下测试失败, 没有发现log,exp函数

    核心代码更改

    库目录CMakeLists.txt变化如下:

    # 生成库
    add_library(MathFunctions mysqrt.cxx)
    
    # 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要
    # 通过INTERFACE可以将头文件搜索路径转递给使用者
    target_include_directories(MathFunctions
              INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
              )
    
    # 检测系统是否支持log,exp函数?
    include(CheckSymbolExists)
    set(CMAKE_REQUIRED_LIBRARIES "m")
    check_symbol_exists(log "math.h" HAVE_LOG)
    check_symbol_exists(exp "math.h" HAVE_EXP)
    
    if(HAVE_LOG AND HAVE_EXP)
      # 目标宏定义
      target_compile_definitions(MathFunctions
                                 PRIVATE "HAVE_LOG" "HAVE_EXP")
    endif()
    
    # 安装规则
    install(TARGETS MathFunctions DESTINATION lib)
    install(FILES MathFunctions.h DESTINATION include)
    

    6. 添加自定义命令以及生成文件

    在上一步的基础上, 本节示例展示了:

    • CMake使用命令;
    • 使用生成文件;

    注: 本节示例初始代码在示例目录的Step6子目录, 成果在Step7子目录

    核心代码更改

    库目录CMakeLists.txt变化如下:

    # 首先生成一个用于产生预定义值表源代码的执行程序
    add_executable(MakeTable MakeTable.cxx)
    
    # 添加自定义命令以产生源代码(依赖于MakeTable目标)
    add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
      COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
      DEPENDS MakeTable
      )
    
    # 生成主库(包含上一步中生成的预定义值表源代码)
    add_library(MathFunctions
                mysqrt.cxx
                ${CMAKE_CURRENT_BINARY_DIR}/Table.h
                )
    
    # 通过INTERFACE向使用者传播头文件搜索路径
    # 通过PRIVATE定义目标内部使用头文件搜索路径
    target_include_directories(MathFunctions
              INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
              PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
              )
    
    # 安装规则
    install(TARGETS MathFunctions DESTINATION lib)
    install(FILES MathFunctions.h DESTINATION include)
    

    7. 构建安装程序

    在上一步的基础上, 本节示例展示了:

    • 制作安装包;

    注1: 本节示例初始代码在示例目录的Step7子目录, 成果在Step8子目录
    注2: 为测试需要, 在win10上, 首先安装NSIS(Nulsoft Install System).

    核心代码更改

    顶层目录CMakeLists.txt末尾添加如下内容即可:

    # 设置安装器
    include(InstallRequiredSystemLibraries)
    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
    set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
    set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
    include(CPack)
    

    命令行使用示例

    在项目目录下

    $ mkdir build
    $ cd build
    $ cmake ..
    $ cmake --build .
    VS generator 注意:目录不能含有中文
    生成发行版安装包(Tutorial-1.0-win64.exe)
    $ cmake --build . --target PACKAGE --config Release
    生成调试版安装包(Tutorial-1.0-win64.exe)
    $ cmake --build . --target PACKAGE --config Debug
    

    8. 将测试结果提交到Kitware的公共指示板

    在上一步的基础上, 本节示例展示了:

    • 将测试结果提交到Kitware的公共指示板;

    注: 本节示例初始代码在示例目录的Step8子目录, 成果在Step9子目录

    核心代码更改

    顶层目录CMakeLists.txt将:

    # enable testing
    enable_testing()
    

    替换为:

    # enable dashboard scripting
    include(CTest)
    

    在顶层目录创建CTestConfig.cmake:

    set(CTEST_PROJECT_NAME "CMakeTutorial")
    set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
    
    set(CTEST_DROP_METHOD "http")
    set(CTEST_DROP_SITE "my.cdash.org")
    set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
    set(CTEST_DROP_SITE_CDASH TRUE)
    

    命令行使用示例

    在项目目录下

    $ mkdir build
    $ cd build
    $ cmake ..
    VS generator 注意:目录不能含有中文
    发布发行版测试结果
    $ ctest [-VV] -C Release -D Experimental
    发布调试版测试结果
    $ ctest [-VV] -C Debug -D Experimental
    

    9. 混合静态和共享库

    在上一步的基础上, 本节示例展示了:

    • 在动态库中使用静态库
    • 使用BUILD_SHARED_LIBS属性设置库默认生成类型(共享/非共享)(默认生成静态库);
    • 使用目标宏定义(target_compile_definitions)设置windows动态库标志(__declspec(dllexport),__declspec(dllimport))
    • 在add_library中控制库生成类型[STATIC | SHARED | MODULE]

    注: 本节示例初始代码在示例目录的Step9子目录, 成果在Step10子目录

    核心代码更改

    顶层CMakeLists.txt的起始部分更改为:

    # 指定CMake最小版本
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名称及版本号
    project(Tutorial VERSION 1.0)
    
    # 指定C++版本
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    
    # 控制动静态库生成目录,这样在windows上不用考虑运行时路径问题
    # we don't need to tinker with the path to run the executable
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
    
    option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
    
    # 配置头文件, 将一些CMake属性值保存到源代码中
    configure_file(TutorialConfig.h.in TutorialConfig.h)
    
    # 添加自定义数学库
    add_subdirectory(MathFunctions)
    
    # 生成执行程序
    add_executable(Tutorial tutorial.cxx)
    target_link_libraries(Tutorial PUBLIC MathFunctions)
    

    MathFunctions/CMakeLists.txt更改如下:

    # 生成运行时需要的动态库
    add_library(MathFunctions MathFunctions.cxx)
    
    # 通过INTERFACE向使用者传播头文件搜索路径
    target_include_directories(MathFunctions
                               INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
                               )
    
    # 是否使用自定义数学库
    option(USE_MYMATH "Use tutorial provided math implementation" ON)
    if(USE_MYMATH)
      # 数学库目标宏定义
      target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
    
      # 首先生成一个用于产生预定义值表源代码的执行程序
      add_executable(MakeTable MakeTable.cxx)
    
      # 添加自定义命令以产生源代码(依赖于MakeTable目标)
      add_custom_command(
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
        COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
        DEPENDS MakeTable
        )
    
      # 生成仅进行sqrt计算的静态库
      add_library(SqrtLibrary STATIC
                  mysqrt.cxx
                  ${CMAKE_CURRENT_BINARY_DIR}/Table.h
                  )
    
      # 通过PRIVATE定义目标内部使用头文件搜索路径
      # Table.h文件生成在${CMAKE_CURRENT_BINARY_DIR}中
      target_include_directories(SqrtLibrary PRIVATE
                                 ${CMAKE_CURRENT_BINARY_DIR}
                                 )
    
      # 设置SqrtLibrary目标属性: 如果默认生成共享库, 需要将PIC(POSITION_INDEPENDENT_CODE)设置为True
      set_target_properties(SqrtLibrary PROPERTIES
                            POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
                            )
    
      # 将数学库链接到自定义sqrt库
      target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
    endif()
    
    # 定义目标宏用于在windows上设置动态库标志declspec(dllexport)
    target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
    
    # 安装规则
    install(TARGETS MathFunctions DESTINATION lib)
    install(FILES MathFunctions.h DESTINATION include)
    

    MathFunctions/MathFunctions.h使用dll导出(dll export)定义:

    #if defined(_WIN32)
    #  if defined(EXPORTING_MYMATH)
    #    define DECLSPEC __declspec(dllexport)
    #  else
    #    define DECLSPEC __declspec(dllimport)
    #  endif
    #else // non windows
    #  define DECLSPEC
    #endif
    
    namespace mathfunctions {
    double DECLSPEC sqrt(double x);
    }
    

    其它对C++代码的修改见CMake教程

    命令行使用示例

    在项目目录下

    $ mkdir build
    $ cd build
    $ cmake ..
    $ cmake --build .
    
      Checking Build System
      Building Custom Rule E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
      MakeTable.cxx
      MakeTable.vcxproj -> E:HelpOtherCMakeCMake_Tutorialguide	utorialStep10uildDebugMakeTable.exe
      Generating Table.h
      Building Custom Rule E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
      mysqrt.cxx
      SqrtLibrary.vcxproj -> E:HelpOtherCMakeCMake_Tutorialguide	utorialStep10uildDebugSqrtLibrary.lib
      Building Custom Rule E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
      MathFunctions.cxx
        正在创建库 E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/build/Debug/MathFunctions.lib 和对象 E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/St
      ep10/build/Debug/MathFunctions.exp
      MathFunctions.vcxproj -> E:HelpOtherCMakeCMake_Tutorialguide	utorialStep10uildDebugMathFunctions.dll
      Building Custom Rule E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/CMakeLists.txt
      tutorial.cxx
      Tutorial.vcxproj -> E:HelpOtherCMakeCMake_Tutorialguide	utorialStep10uildDebugTutorial.exe
      Building Custom Rule E:/Help/Other/CMake/CMake_Tutorial/guide/tutorial/Step10/CMakeLists.txt
    

    10. 生成器表达式,条件判断

    在上一步的基础上, 本节示例展示了:

    • 在构建过程中计算生成器表达式值,以生成特定于每个构建配置的信息
    • 生成器表达式有三类: 逻辑表达式、信息表达式和输出表达式(Logical, Informational, and Output expressions)
    • 逻辑表达式: $<0:...>的结果是空字符串,$<1:...>的结果是“...”的内容。它们也可以嵌套。
    • 生成器表达式通常用来按需添加编译标志
    • 使用INTERFACE目标在目标间传递属性

    注: 本节示例初始代码在示例目录的Step10子目录, 成果在Step11子目录

    核心代码更改

    顶层CMakeLists.txt的相应部分:

    # specify the C++ standard
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED True)
    

    更改为:

    add_library(tutorial_compiler_flags INTERFACE)
    target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
    
    # 通过BUILD_INTERFACE生成器表达式添加编译器警告标志
    set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
    set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
    target_compile_options(tutorial_compiler_flags INTERFACE
      "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
      "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
    )
    

    库目录CMakeLists.txt目标链接库代码:

    target_link_libraries(MakeTable[SqrtLibrary|MathFunctions] PRIVATE[PUBLIC] tutorial_compiler_flags)
    

    11. 添加导出配置,以支持find_package

    在上一步的基础上, 本节示例展示了:

    • 如何让其他项目方便地使用本项目
    • install(TARGETS)中使用EXPORT关键字, 它用于将目标从安装树导入到另一个项目
    • 生成MathFunctionsConfig.cmake, 以让find_package()命令可以找到本项目
    • 显式安装生成的MathFunctionsTargets.cmake

    注: 本节示例初始代码在示例目录的Step11子目录, 成果在Step12子目录

    核心代码更改

    MathFunctions/CMakeLists.txt中增加EXPORT:

    # 根据项目内与安装方式包含不同的头文件目录
    target_include_directories(MathFunctions
                               INTERFACE
                                $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
                                $<INSTALL_INTERFACE:include>
                               )
    
    # 此处省略其他代码...
    
    # 安装规则
    install(TARGETS MathFunctions tutorial_compiler_flags
            DESTINATION lib
            EXPORT MathFunctionsTargets)
    install(FILES MathFunctions.h DESTINATION include)
    

    在顶层目录中添加Config.cmake.in, 用来生成MathFunctionsTargets.cmake:

    @PACKAGE_INIT@
    
    include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
    

    顶层CMakeLists.txt,为了正确配置和安装MathFunctionsTargets.cmake, 添加以下内容:

    install(EXPORT MathFunctionsTargets
      FILE MathFunctionsTargets.cmake
      DESTINATION lib/cmake/MathFunctions
    )
    
    include(CMakePackageConfigHelpers)
    # generate the config file that is includes the exports
    configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
      "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
      INSTALL_DESTINATION "lib/cmake/example"
      NO_SET_AND_CHECK_MACRO
      NO_CHECK_REQUIRED_COMPONENTS_MACRO
      )
    # generate the version file for the config file
    write_basic_package_version_file(
      "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
      VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
      COMPATIBILITY AnyNewerVersion
    )
    
    # install the configuration file
    install(FILES
      ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
      DESTINATION lib/cmake/MathFunctions
      )
    

    到这里,这是一个可以在项目安装或打包以后重定位的CMake配置。 如果需要项目在一个构建目录中使用,在顶层CMakeLists.txt的结尾添加以下内容:

    export(EXPORT MathFunctionsTargets
      FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
    )
    

    通过这个导出调用,我们现在生成一个Targets.cmake,使得在构建目录中配置生成的MathFunctionsConfig.cmake可以被其他项目使用,而不需要安装它。
    此处未试验, 不理解

    12. 将调试版和发行版打包在一起

    在上一步的基础上, 本节示例展示了:

    • 为调试版文件设置后缀: 非执行程序目标会根据CMAKE_DEBUG_POSTFIX生成它的_POSTFIX
    • 执行程序目录的DEBUG_POSTFIX需要手工设置

    注1: 本节示例初始代码在示例目录的Step12子目录, 成果在Complete子目录
    注2: 本节打包工作在win10上没有成功

    核心代码更改

    顶层CMakeLists.txt中更改:

    # 设置非可执行程序目标的调试后缀
    set(CMAKE_DEBUG_POSTFIX d)
    ...
    # 设置可执行程序目标的调试后缀
    set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
    
  • 相关阅读:
    移动端touch与click区别--移动端开发整理笔记(五)
    移动端适配(rem & viewport)--移动端开发整理笔记(四)
    移动端事件(touchstart、touchmove、touchend)--移动端开发整理笔记(三)
    Flex弹性盒模型(新老版本完整)--移动端开发整理笔记(二)
    meta设置与去除默认样式--移动端开发整理笔记(一)
    react native ios 上架
    react16 路由按需加载、路由权限配置
    mpvue 页面预加载,新增preLoad生命周期
    mpvue 星星打分组件
    mpvue 签字组件
  • 原文地址:https://www.cnblogs.com/yaoyu126/p/12859051.html
Copyright © 2020-2023  润新知