• CMake


    1.什么是CMake?

    • 是一种跨平台Make工具。
    • 写一个CMakeList.txt与平台无关的文件来定制整个编译流程。
    • 然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。
    • CMake是Qt6的默认构建系统,之前是qmake。

    2.流程

    1. 写CMake配置文件CMakeList.txt。
    2. 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(ccmake 和 cmake 的区别在于前者提供了一个交互式的界面)。其中, PATH 是 CMakeLists.txt 所在的目录。
    3. 使用make命令进行编译。

    2.1 写好源文件

    2.2 编写CMakeList.txt文件

    • 需要将CMakeList.txt保存在与源文件同个目录下
    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名和版本号
    project(Tutorial)
    
    # 生成可执行文件
    add_executable(Demo main.c)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    语法由命令、注释和空格组成,其中命令是不区分大小写的。符号 # 后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。

    1. cmake_minimum_required:指定运行此配置文件所需的 CMake 的最低版本;
    2. project:参数值是 Demo1,该命令表示项目的名称是 Demo1 。
    3. add_executable:将名为 main.cc 的源文件编译成一个名称为 Demo 的可执行文件。

    2.3 编译

    • 执行cmake .,得到Makefile。
    • 执行make命令编译得到源码的可执行文件。

    2.4 同一个文件夹下多个源文件的编译

    比如一个文件夹下有main.c,function.c,和function.h可以这样写

    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名
    project(Tutorial)
    
    # 生成可执行文件
    add_executable(Tutorial main.c function.c)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当一个文件夹下的源文件很多时,使用aux_source_directory 命令,将指定目录下的所有源文件名存到指定的变量名。

    # <dir> 文件夹路径;<variable>变量名
    aux_source_directory(<dir> <variable>)
    
    • 1
    • 2
    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名
    project(Tutorial)
    
    # 查找当前目录下所有源文件名,并将其存储到	DIR_CURR中
    aux_source_directory(. DIR_CURR)
    
    # 生成可执行文件
    add_executable(Tutorial ${DIR_CURR})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.5 多个文件夹下有多个源文件

    如当前目录下为main.c,当前目录下有目录fun,fun目录有文件function.c,function.h。

    这种情况下需要将fun文件夹下的源文件编译成为静态库,再由main.c调用。

    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名
    project(Tutorial)
    
    # 查找当前目录下所有源文件名,并将其存储到	DIR_CURR中
    aux_source_directory(. DIR_CURR)
    
    # 添加子目录fun,同时将子目录下的CMakeLists.txt文件执行
    add_subdirectory(fun)
    
    # 生成可执行文件
    add_executable(Tutorial ${DIR_CURR})
    
    # 添加链接库,指明可执行文件 main 需要连接一个名为 function 的链接库
    target_link_libraries(Tutorial function)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    子目录fun下的CMakeLists.txt文件内容:

    # 查找当前目录下所有源文件名,并将其存储到	DIR_CURR中
    aux_source_directory(. DIR_FUN)
    
    # 生成链接库,将 fun 目录中的源文件编译为静态链接库。
    add_library(function ${DIR_FUN})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.cmake:configure_file指令

    configure_file 指令通过读取输入文件中的内容,将 CMakeLists.txt 文件中的变量转变为 C/C++ 中可识别的宏定义,然后存入另一个文件中。

    configure_file(<input> <output>
                   [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
                    FILE_PERMISSIONS <permissions>...]
                   [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
                   [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    输入文件input为xxx-config.h.in,输出文件output为xxx-config.h,@ONLY:在 文件中只使用 @VAR@ 的方式获取变量值,不适用 ${VAR} 的方式;

    3.1 xxx-config.in语法

    1. 判断变量VAR是否定义
    
    #cmakedefine VAR
    
    • 1
    • 2

    如果 CMakeLists.txt 文件中,定义了变量 VAR,那么在转化出来的文件中就会存在 #define VAR 的语句。否则,在文件中就会显示 /*undef VAR*/。然后,在源码中使用 #ifdef 语句进行使用——#ifdef VAR。

    2. 判断选项是否开启
    #cmakedefine01 VAR
    
    • 1

    CMakelists.txt 中的 option(VAR …) 用于开关操作,并且可以使用 cmake -DVAR=ON/OFF … 修改其变量值。上述指令根据 CMakeLists.txt 中 VAR 的值为 ON 或 OFF,将其转换为 #define VAR 1 或 #define VAR 0。然后在源码中使用 #if 进行引用——#if VAR。

    3. 获取变量值
    #cmakedefine VAR @VAR@#cmakedefine VAR ${VAR}#define SELF_DEFINE_MACRO_NAME @VAR@
    
    • 1
    • 2
    • 3
    • 4
    • 5

    CMakeLists.txt 文件中,变量 VAR 多用于定义某些信息,比如版本号,作者,项目描述,调试等级等。然后在源码中输出这些值到固定位置,起到提示的作用。

    如果想要在命令行中修改通过 set() 自定义变量的值,那么需要在定义变量时指定 CACHE 参数。比如:

    set(DEBUG_LDEVL 1 CACHE STRING "set debug level")
    
    • 1

    便可以使用cmake -DDEBUG_LEVEL=4修改它的值。

    • 使用 configure_file() 可以省去很多的类似 add_compile_options() 指令。只需在 CMakeLists.txt 文件中定义变量,然后再 xxx-config.h.in 文件中使用 #cmakedefine 进行引用即可。

    4. set命令

    set命令可以设置普通变量、缓存条目、环境变量

    set(<variable> <value>... [PARENT_SCOPE]) #设置普通变量
     
    set(<variable> <value>... CACHE <type> <docstring> [FORCE]) #设置缓存条目
     
    set(ENV{<variable>} [<value>]) #设置环境变量
    
    • 1
    • 2
    • 3
    • 4
    • 5

    …表示可以给变量设置0个或者多个值,当设置多个值时(大于2个),多个值会通过分号连接符连接成一个真实的值赋值给变量,当设置0个值时,实际上是把变量变为未设置状态,相当于调用unset命令。

    4.1 设置变量为一个指定的普通值

    1. 单个值:
    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名
    project(Tutorial)
    
    set (var dd)
    
    message (">>> value = ${var}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    输出:

    >>> value = dd
    
    • 1
    1. 指定多个值和空:
    # 写明版本号
    cmake_minimum_required(VERSION 3.10)
    
    # 设置项目名
    project(Tutorial)
    
    set (var dd ee ff)
    
    message (">>> value = ${var}")
    
    set (var1)
    
    message (">>> value = ${var1}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    >>> value = dd;ee;ff
    >>> value =
    
    • 1
    • 2
    1. set使用选项PARENT_SCOPE,则变量的作用域只能传递到调用它的函数。
    • 调用一个使用set的函数,选项PARENT_SCOPE将变量传递到上一层调用函数
    # CMakeLists.txt
    cmake_minimum_required (VERSION 3.10.2)
    project (set_test)
     
    function (test_fn arg1)
        set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        message (">>> in function, value = ${normal_var_in_fn}")
    endfunction (test_fn)
     
    function (test_fn_parent arg1)
        test_fn (${arg1})
        message (">>> in parent function, value = ${normal_var_in_fn}")
    endfunction (test_fn_parent)
     
    test_fn_parent (hello)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输出

    >>> in function, value = 
    >>> in parent function, value = hello
    
    • 1
    • 2
    • 函数内使用PARENT_SCOPE定义变量,函数外使用该变量,找不到变量的定义
    # CMakeLists.txt
     
    cmake_minimum_required (VERSION 3.10.2)
     
    project (set_test)
     
    function (test_fn arg1)
        set (normal_var_fn ${arg1} PARENT_SCOPE)
        message (">>> in function, value = ${normal_var_fn}")
    endfunction (test_fn)
     
    test_fn(hello)
    message (">>> in directory, value = ${normal_var_fn}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出

    >>> in function, value =
    >>> in directory, value = 
    
    • 1
    • 2
    • 函数内先使用set,再使用带PARENT_SCOPE定义:选项PARENT_SCOPE定义的变量作用域在上一层函数,当前函数的变量必须使用不带选项PARENT_SCOPE定义。
    # CMakeLists.txt
     
    cmake_minimum_required (VERSION 3.10.2)
     
    project (set_test)
     
    function (test_fn arg1)
        set (normal_var_in_fn hello)
        set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        message (">>> in function, value = ${normal_var_in_fn}")
    endfunction (test_fn)
     
    test_fn (hello)
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出

    >>> in function, value = hello
    
    • 1

    4.2. 设置缓存条目

    相当于一个全局变量,在同一个CMake工程中都可以用到

    set(<variable> <value>... CACHE <type> <docstring> [FORCE])
    
    • 1

    将缓存条目variable设置为值…,除非用户进行设置或使用了选项FORCE,默认情况下缓存条目的值不会被覆盖。缓存条目可以通过CMAKE的GUI界面的add entry按钮来增加。

    缓存条目的主要有以下几类:

    • BOOL:布尔值ON/OFF,CMAKE的GUI界面对此类缓存条目会提供一个复选框。
    • FILEPATH:文件路径,CMAKE的GUI界面对此类缓存条目会提供一个文件选择框。
    • PATH:目录路径,CMAKE的GUI界面对此类缓存条目会提供一个目录选择框。
    • STRING / STRINGS:文本行,CMAKE的GUI界面对此类缓存条目会提供一个文本框(对应STRING)或下拉选择框(对应STRINGS)。
    • INTERNAL:文本行,但是只用于内部,不对外呈现。主要用于运行过程中存储变量,因此使用该type意味着使用FORCE。

    缓存条目的几个注意事项
    1)如果变量先前未定义或者使用了FORCE选项,则缓存条目会直接被赋值。
    2)可以在使用cmake构建的使用通过-D选项来给缓存条目赋值,这样CMakeLists.txt内的set命令只会为缓存条目添加类型。
    3)如果变量类型是目录或者文件路径,通过-D选项传入的若只是相对路径,那么set会给这个相对路径前添加当前的工作目录以变成绝对路径(如果已经是绝对路径则不会处理)。

    # CMakeLists.txt
    cmake_minimum_required (VERSION 3.10.2)
    project (set_test)
     
    set (cache_entry_val ON OFF CACHE BOOL "choose ON to enable")
    message (">>> value = ${cache_entry_val}")
     
    set (cache_entry_val2 ON CACHE BOOL "choose ON to enable" FORCE)
    message (">>> value2 = ${cache_entry_val2}")
     
    set (cache_entry_val3 ON)
    set (cache_entry_val3 OFF CACHE BOOL "choose ON to enable")
    message (">>> value3 = ${cache_entry_val3}")
     
    set (cache_entry_input OFF CACHE BOOL "choose ON to enable")
    message (">>> value4 = ${cache_entry_input}")
     
    set (mypath "test" CACHE FILEPATH "choose a file path")
    message (">>> value5 = ${mypath}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    打印

    >>> value = ON;OFF
    >>> value2 = ON
    >>> value3 = OFF
    >>> value4 = OFF
    >>> value5 = test
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.3. 设置环境变量

    set(ENV{<variable>} [<value>])
    
    • 1

    命令含义:将环境变量设置为值(注意没有…),接着使用$ENV{}会得到新的值。cmake中的环境变量可以参考:环境变量。

    环境变量设置的几个注意事项

    • 1)该命令设置的环境变量只在当前的cmake进程生效,既不会影响调用者的环境变量,也不会影响系统环境变量。
    • 2)如果值为空或者ENV{}后没有参数,则该命令会清除掉当前环境变量的值。
    • 3)后的参数会被忽略。
    # CMakeLists.txt
    cmake_minimum_required (VERSION 3.10.2)
    project (set_test)
     
    message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
     
    set (ENV{CMAKE_PREFIX_PATH} "/test/sub")
    message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
     
    set (ENV{CMAKE_PREFIX_PATH})
    message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
     
    set (ENV{CMAKE_PREFIX_PATH} "/test/top/") 
    message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
     
    set (ENV{CMAKE_PREFIX_PATH} "") 
    message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    打印

    >>> value = 
    >>> value = /test/sub
    >>> value = 
    >>> value = /test/top/
    >>> value = 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5. Option命令

    CMake中的option用于控制编译流程,相当于C语言中的宏条件编译。

    5.1 格式

    option(<variable> "" [value])
    
    • 1
    • variable:定义选项名称
    • help_text:说明选项的含义
    • value:定义选项默认状态,一般是OFF或者ON,除去ON之外,其他所有值都为认为是OFF。

    可以在执行CMake时,在命令里面直接改选项值

    $cmake  .. -D<variable>=OFF
    
    • 1

    CMake执行完后,选项的值会保存到CMakeCache.txt中。

    5.2 与add_definitions搭配在C中使用

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0)
    project(test)
    
    option(USE_NEW_METHOD "option for debug" OFF)
    if(USE_NEW_METHOD)
        add_definitions(-DUSE_NEW_METHOD)
    endif()
     
    add_executable(test main.cpp)
     
    install(TARGETS test RUNTIME DESTINATION bin)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    main.cpp

    #include 
    #include 
     
    //#define USE_NEW_METHOD //不用在这里再开关此行代码了
     
    int main(int argc, char **argv) {
        std::cout << "Hello, world!" << std::endl;
        
    #ifdef USE_NEW_METHOD
        std::cout << "USE NEW METHOD " << std::endl;
    #else
        std::cout << "USE DEFAULT METHOD" << std::endl;
    #endif
        
        std::cout << "END" << std::endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    指令:cmake -DUSE_NEW_METHOD=ON ...

    通过命令行指令,将USE_NEW_METHOD变量置为ON,使得CMakeLists.txt中USE_NEW_METHOD变量开启,从而通过add_definitions函数在C程序中添加定义USE_NEW_METHOD。

    对于同一选项,子项目值遵循主项目的定义。也就是说子项目会被主项目覆盖

    5.3 添加库

    现在我们将向项目中添加一个库,这个库包含计算数字平方根的实现,可执行文件使用这个库,而不是编译器提供的标准平方根函数。

    我们把库放在名为 MathFunctions 的子目录中。此目录包含头文件 MathFunctions.h 和源文件 mysqrt.cpp。源文件有一个名为 mysqrt 的函数,它提供了与编译器的 sqrt 函数类似的功能,MathFunctions.h 则是该函数的声明。

    在 MathFunctions 目录下创建一个 CMakeLists.txt 文件,并添加以下一行:

    add_library(MathFunctions mysqrt.cpp)
    
    • 1

    CMake 中的 target 有可执行文件和库文件,分别使用 add_executable 和 add_library 命令生成,除了指定生成的可执行文件名/库文件名,还需要指定相关的源文件。

    此时文件结构为:

    step3/
        build/
        MathFunctions/
            CMakeLists.txt
            MathFunctions.h
            mysqrt.cpp
        CMakeLists.txt
        tutorial.cpp
        TutorialConfig.h.in
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    为了使用 MathFunctions 这个库,我们将在根目录 CMakeLists.txt 文件中添加一个 add_subdirectory(MathFunctions) 命令指定库所在子目录,该子目录下应包含 CMakeLists.txt 文件和代码文件。

    可执行文件要使用库文件,需要能够找到库文件和对应的头文件,可以分别通过 target_link_libraries 和 target_include_directories 来指定。

    使用 target_link_libraries 将新的库文件添加到可执行文件中,使用 target_include_directories 将 MathFunctions 添加为头文件目录,添加到 Tutorial 目标上,以便 mysqrt.h 可以被找到。

    根目录 CMakeLists.txt 的最后几行如下所示:

    
    # add the MathFunctions library
    add_subdirectory(MathFunctions)
    
    # add the executable
    add_executable(${PROJECT_NAME} tutorial.cpp)
    
    target_link_libraries(${PROJECT_NAME} PUBLIC MathFunctions)
    
    # add the binary tree to the search path for include files
    # so that we will find TutorialConfig.h
    target_include_directories(${PROJECT_NAME} PUBLIC
                               ${PROJECT_BINARY_DIR}
                               ${PROJECT_SOURCE_DIR}/MathFunctions
                               )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    MathFunctions 库就算添加完成了,接下来就是在主函数使用该库中的函数,先在 tutorial.cpp 文件中添加头文件:

    #include "MathFunctions.h"
    
    • 1

    然后可以使用mysqrt函数

    const double outputValue = mysqrt(inputValue);
    
    • 1

    6. 自定义编译选项

    样例代码

    可以将标准库下的一些库定义为自己写的同名库

    7.安装

    7.1 定制安装规则

    在子目录 fun/CMakeList.txt文件里添加:

    install (TARGETS function DESTINATION bin)
    install (FILES function.h DESTINATION include)
    
    • 1
    • 2

    在根目录的CMakeList.txt的末尾添加:

    install (TARGETS Main DESTINATION bin)
    install (FILES "${PROJECT_BINARY_DIR}/config.h"
             DESTINATION include)
    
    • 1
    • 2
    • 3

    通过上面的定制,生成的 Main文件和 function 函数库 libfunction.o 文件将会被复制到 /usr/local/bin 中,而 function.h 和生成的 config.h 文件则会被复制到 /usr/local/include 中。我们可以验证一下(顺带一提的是,这里的 /usr/local/ 是默认安装到的根目录,可以通过修改 CMAKE_INSTALL_PREFIX 变量的值来指定这些文件应该拷贝到哪个根目录)。

    7.2 测试

    CMake 提供了一个称为 CTest 的测试工具。我们要做的只是在项目根目录的 CMakeLists 文件中调用一系列的 add_test 命令。

    enable_testing()
    
    # 测试程序是否成功运行
    add_test (test_run Demo 5 2)
    
    # 测试帮助信息是否可以正常提示
    add_test (test_usage Demo)
    set_tests_properties (test_usage
      PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent")
    
    # 测试 5 的平方
    add_test (test_5_2 Demo 5 2)
    
    set_tests_properties (test_5_2
     PROPERTIES PASS_REGULAR_EXPRESSION "is 25")
    
    # 测试 105 次方
    add_test (test_10_5 Demo 10 5)
    
    set_tests_properties (test_10_5
     PROPERTIES PASS_REGULAR_EXPRESSION "is 100000")
    
    # 测试 210 次方
    add_test (test_2_10 Demo 2 10)
    
    set_tests_properties (test_2_10
     PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    7.3 添加版本号

    一般在project命令后加上这两行

    # 主版本号
    set (Demo_VERSION_MAJOR 1) 
    # 副版本号
    set (Demo_VERSION_MINOR 0)
    
    • 1
    • 2
    • 3
    • 4

    在config.h.in中预定义,以便在代码中获取版本信息。

    #define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
    #define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
    
    
    • 1
    • 2
    • 3

    在主函数中输出版本号

    作者:Linux嵌入式
    链接:https://zhuanlan.zhihu.com/p/534439206
    来源:知乎
    
    #include 
    #include 
    #include 
    #include "config.h"
    #include "math/MathFunctions.h"
    
    int main(int argc, char *argv[])
    {
        if (argc < 3){
            // print version info
            printf("%s Version %d.%d\n",
                argv[0],
                Demo_VERSION_MAJOR,
                Demo_VERSION_MINOR);
            printf("Usage: %s base exponent \n", argv[0]);
            return 1;
        }
        double base = atof(argv[1]);
        int exponent = atoi(argv[2]);
        
    #if defined (HAVE_POW)
        printf("Now we use the standard library. \n");
        double result = pow(base, exponent);
    #else
        printf("Now we use our own Math library. \n");
        double result = power(base, exponent);
    #endif
        
        printf("%g ^ %d is %g\n", base, exponent, result);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    7.4 生成安装包

    配置生成各种平台上的安装包,包括二进制安装包和源码安装包。为了完成这个任务,我们需要用到 CPack ,它同样也是由 CMake 提供的一个工具,专门用于打包。首先在顶层的 CMakeLists.txt 文件尾部添加下面几行:

    # 构建一个 CPack 安装包
    # 导入InstallRequiredSystemLibraries,以便之后导入CPack模块
    include (InstallRequiredSystemLibraries)
    # 设置版权
    set (CPACK_RESOURCE_FILE_LICENSE
      "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
    # 设置主版本号
    set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
    # 设置副版本号
    set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
    include (CPack)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行cpack命令

    # 生成二进制安装包
    $cpack -C CPackConfig.cmake
    # 生成源码安装包
    $cpack -C CPackSourceConfig.cmake
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    之后生成3个不同格式的二进制文件
    执行其中一个,就可以生成安装界面

    参考:知乎-Linux嵌入式 : https://zhuanlan.zhihu.com/p/534439206
    set函数:https://blog.csdn.net/sinat_31608641/article/details/123101969

    https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzg4ODAxMzE2OA%3D%3D%26mid%3D2247484983%26idx%3D1%26sn%3Daf9760f5960492190efeb040596702ad%26chksm%3Dcf80ee28f8f7673e49c7f4cf8a71e248b283545492a1c231b4535db14d6b1738f3746c58982b%26token%3D391208598%26lang%3Dzh_CN%23rd

  • 相关阅读:
    【教3妹学算法-每日1题】使数组中所有元素都等于零
    第44节——redux store
    MATLAB中ilu函数用法
    AI加速(八)| 循环展开Unrooling——你肯定能学会的程序加速方法
    Ajax axios JSON Fastjson
    四化智造MES(WEB)与金蝶云星空对接集成原材料/标准件采购查询(待采购)连通采购订单新增(其他采购订单行关闭-TEST)
    Mysql 45讲学习笔记(二十四)MYSQL主从一致
    更简洁的参数校验,使用 SpringBoot Validation 对参数进行校验
    spark:商品热门品类TOP10统计(案例)
    mysql学习使用
  • 原文地址:https://blog.csdn.net/qq_37431083/article/details/125885308