CMake(一)

2023-05-16

CMake(一)

简述

在之前的文章中介绍了 qmake的使用。相比qmake,CMake稍微复杂一点,它使用CMakeList.txt文件来定制整个编译流程。同时,CMake会根据CMakeList.txt以及开发平台生成对应的Makefile和工程文件。很多开源库都采用了CMake作为项目的系统架构,是一个使用很广泛的工具,作为一个程序员是必须要了解和学习的。文章末尾提供的Demo的下载。

CMakeLists.txt demo 一步步,由浅入深

Demo1 编译单个源文件

Demo1文件目录:

Demo1

main.cc
hello.cpp
CMakeLists.txt
build //在这里生成编译结果

hello.cpp

#include <stdio.h>
int main(int argc, char *argv[])
{
	printf("hello world\n");
	return 0;
}

CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (HelloWorld)

# 指定生成目标
add_executable(helloworld hello.cpp)

在源文件目录下新建build目录,为了把编译信息和源文件分离,确保系统安装CMake 并且配置好,关于安装CMake将会在其它文章补充。
camek .. //会生成Makefile
make //生成可执行文件 helloworld
./helloworld //打印出 “hello world”
一个单个源文件CMake demo完成。
注意:CMakeLists.txt所有用的命令都是小写,其实CMakeLists.txt支持命令大写,小写,或大小写混搭。 #为指令注释符号

Demo2 多个源文件

Demo2文件目录:

Demo2

main.cc
MathFunctions.h
MathFunctions.cc
CMakeLists.txt
build //在这里生成编译结果

MathFunctions.h

#ifndef POWER_H
#define POWER_H

extern double power(double base, int exponent);

#endif

MathFunctions.cc

/**
 * power - Calculate the power of number.
 * @param base: Base value.
 * @param exponent: Exponent value.
 *
 * @return base raised to the power exponent.
 */
double power(double base, int exponent)
{
    int result = base;
    int i;

    if (exponent == 0) {
        return 1;
    }
    
    for(i = 1; i < exponent; ++i){
        result = result * base;
    }

    return result;
}

main.cc

#include <stdio.h>
#include <stdlib.h>
#include "MathFunctions.h"

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

CMakeLists.txt
这里CMakeLists.txt有两种写法

  1. 将源文件使用命令 add_executable(helloworld hello.cpp)一个个添加进去,这样源文件一多,效率非常低。
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 指定生成目标
add_executable(Demo main.cc MathFunctions.cc)
  1. 当然,我们可以使用命令aux_source_directory(<dir> <variable>) 将制定目录里的所有源文件都存放到指定变量中,对上面CMakeLists.txt做如下改动。
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 查找目录下的所有源文件 . 代表是当前目录
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})

准备工作就绪,编译
cd build
camek .. //会生成Makefile
make //生成可执行文件 helloworld
./demo 3 4 //打印出 “3 ^ 4 is 81”

Demo3 多个目录多个源文件

Demo3 [目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
CMakeLists.txt
build [目录] //在这里生成编译结果
多目录多源文件有两种方式:

  1. Demo3-1 使用指令aux_source_directory(<dir> <variable>)添加到变量中,并使用指令add_executable(<name>, [source1] [source2 ...]) 添加多个Source,用来构建可执行文件。
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo3)

# 查找目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
aux_source_directory(./math DIR_SRCS_Math)

# 添加 math 子目录
add_subdirectory(math)

# 指定生成目标
add_executable(Demo ${DIR_SRCS} ${DIR_SRCS_Math})
  1. Demo3-2 采用静态库,或者动态库的方式,这里举例静态库。
    如果是多目录,则每个目录下面都需要有一个CMakeLists.txt,其本质是其它目录下的源文件编译成静态连接库,链接到主工程目录, 又或者将非主工程目录下的源文件编译成一个动态链接库,用于其他工程的调用。 这里采用的是静态链接库的方法。
    Demo3CMakeLists.txt,对比起Demo2中的CMakeLists.txt有如下修改
  • 添加 add_subdirectory(math) 命令,将math目录加入项目
  • 添加 target_link_libraries(Demo MathFunctions) 指明可执行文件 main 需要连接一个名为 MathFunctions 的链接库, 这个库来源于math目录下的CMakeLists.txt,由其生成。其中在add_library(MathFunctions ${DIR_LIB_SRCS}) 将math 目录中的源文件编译为静态链接库,并且命名为MathFunctions

Demo3目录下的CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo3)

# 查找目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 添加 math 子目录
add_subdirectory(math)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})

# 添加链接库
target_link_libraries(Demo MathFunctions)

math目录下的CMakeLists.txt

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)

# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${DIR_LIB_SRCS})

准备工作就绪,编译
cd build
camek .. //会生成Makefile
make //生成可执行文件 helloworld
./demo 3 4 //打印出 “3 ^ 4 is 81”
注意: 在math目录下,可以看到多出了一个静态链接库:libMathFunctions.a 在编译的时候已经链接到可执行文件中。

Demo4 编译选项

编译选项:指的是根据用户的环境和需求选择最合适的编译方案,Demo4实现是否将MathFunctions 库设为一个可选的库,让用户在CMake时选择是否使用这个MathFunctions 库。
Demo4文件目录:

Demo4[目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
config.h.in
CMakeLists.txt
build [目录] //在这里生成编译结果

Demo4的目录文件中多了一个config.h.in`的文件,其内容如下:

#cmakedefine USE_MYMATH

这个文件在CMakeLists.txt 处理下会生成config.h, 用其中的预定义变量来控制代码生成。

下面用具体的例子来说明, 新的CMakeLists.txt内容如下所示。

  • option (USE_MYMATH "Use provided math implementation" ON)这个命令就是在CMake时,让用户选,是否选用MathFunctions 库,当为“ON”时,执行if(USE_MYMATH),判断为真,顺序执行if后面的内容。

CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo4)

# 设置工程包含当前目录,非必须
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
	   "Use provided math implementation" ON)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否加入 MathFunctions 库
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)
  #使用变量EXTRA_LIBS收集所有可供选择的库文件,进而将他们链接到可执行文件中
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable (Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

修改 main.cc文件

#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifdef USE_MYMATH
  #include <MathFunctions.h>
#else
  #include <math.h>
#endif


int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }

    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);

#ifdef USE_MYMATH
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#else
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#endif
    
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

准备工作就绪,编译
cd build
为了
ccamek .. 进入到编译选项中,如图所示
在这里插入图片描述

根据上图的选项,用键盘上下移动选项,并且将 USER_MYMATH设置为ON, 根据提示,按 c完成配置,再按g键生成Makefile并且推出,这里同时生成config.h 文件
·config.h 内容如下,生成了一个预编译宏,用于判断是否使用MathFunctions

#define USE_MYMATH

make //生成可执行文件 demo
./demo 3 4 //打印出 “3 ^ 4 is 81”

Demo5 安装和测试

Demo5文件目录:

Demo5[目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
config.h.in
CMakeLists.txt
build [目录] //在这里生成编译结果

  1. 安装:本质是将输出的目标文件(库或可执行文件),以及相关的头文件复制到指定的目录中。在CMake中用指定的规则实现,在生成的Makefile文件里包含的 install的功能,只要执行make install就可以实现安装功能。

修改 Demo5[目录] ,添加以下命令

Demo5[目录]

CMakeLists.txt

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

修改 math [目录]的CMakeLists.txt 添加以下命令

Demo5[目录

math [目录]

CMakeLists.txt

# 指定 MathFunctions 库的安装路径
install (TARGETS MathFunctions DESTINATION lib)
install (FILES MathFunctions.h DESTINATION include)

以上添加的命令会使得: demo以及libMathFunctions.a文件本安装到/usr/lacal/bin 目录中,而MathFunctions.h 头文件则被安装到/usr/lacal/include中。/usr/lacal/这个是默认安装目录,CMAKE_INSTALL_PREFIX 变量来指定安装目录

完整的CMakeLists.txt 如下:

Demo5\CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo5)

set (CMAKE_INCLUDE_CURRENT_DIR ON)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )
 
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
	   "Use provided math implementation" ON)

# 是否加入 MathFunctions 库
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

Demo5\math\CMakeLists.txt

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)

# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${DIR_LIB_SRCS})

# 指定 MathFunctions 库的安装路径
install (TARGETS MathFunctions DESTINATION lib)
install (FILES MathFunctions.h DESTINATION include)

准备工作就绪,编译
cd build
ccamek .. 设置USER_MYMATH ON
c 配置
g 生成并退出
make install
在这里插入图片描述

  • 测试:顾名思义,对项目进行内测。 CMake提供了CTest的测试的工具,使用add_test

修改 Demo5[目录] ,添加以下命令
以上添加的4个测试:

  1. 测试帮助信息是否可以正常提示
  2. 测试 5 的平方
  3. 测试 10 的 5 次方
  4. 测试 2 的 10 次方

Demo5[目录]

CMakeLists.txt

# 启用测试
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")

# 测试 10 的 5 次方
# add_test (test_10_5 Demo 10 5)

# set_tests_properties (test_10_5
#  PROPERTIES PASS_REGULAR_EXPRESSION "is 100000")

# 测试 2 的 10 次方
# add_test (test_2_10 Demo 2 10)

# set_tests_properties (test_2_10
#  PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")

上面是将测试内容一条一条的加入,这样测试内容多就显得繁琐了。因此,继续在下面引文简化测试命令:

# 定义一个宏,用来简化测试工作
macro (do_test arg1 arg2 result)
  add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
  set_tests_properties (test_${arg1}_${arg2}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)

# 利用 do_test 宏,测试一系列数据
do_test (5 2 "is 25")
do_test (10 5 "is 100000")
do_test (2 10 "is 1024")

运行结果:

guo@guo:~/share/CMake/Demo5/build$ make test
Running tests...
Test project /home/guo/share/CMake/Demo5/build
    Start 1: test_run
1/5 Test #1: test_run .........................   Passed    0.00 sec
    Start 2: test_usage
2/5 Test #2: test_usage .......................   Passed    0.00 sec
    Start 3: test_5_2
3/5 Test #3: test_5_2 .........................   Passed    0.00 sec
    Start 4: test_10_5
4/5 Test #4: test_10_5 ........................   Passed    0.00 sec
    Start 5: test_2_10
5/5 Test #5: test_2_10 ........................   Passed    0.00 sec


Demo6 根据平台来判断是否调用系统函数,或者自定义函数

Demo6文件目录:

Demo6[目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
config.h.in
CMakeLists.txt
build [目录] //在这里生成编译结果
CMake是以跨平台工具, 有些项目以可跨平台作为设计初衷,同一个功能在不同平台上,不一定有对应的系统函数可以调用,因此部分函数调用需要自己实现。于是就有通过检查环境来判断系统是否支持某个函数调用。这里例举pow函数。

预定义宏变量

修改config.h.in文件

// does the platform provide pow function?
#cmakedefine HAVE_POW

修改最顶层目录的 CMakeLists.txt文件

  1. 添加 CheckFunctionExists
  2. 调用 check_function_exists命令测试连接器是否能在链接阶段找到 pow函数
# 检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)

完整的 CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo6)

set (CMAKE_INCLUDE_CURRENT_DIR ON)

# 检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否加入 MathFunctions 库
if (NOT HAVE_POW)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (NOT HAVE_POW)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

# 启用测试
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")

# 定义一个宏,用来简化测试工作
macro (do_test arg1 arg2 result)
  add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
  set_tests_properties (test_${arg1}_${arg2}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
 
# 利用 do_test 宏,测试一系列数据
do_test (5 2 "is 25")
do_test (10 5 "is 100000")
do_test (2 10 "is 1024")

  1. 修改main.cc 文件
#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifdef HAVE_POW
  #include <math.h>
#else
  #include <MathFunctions.h>
#endif

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    
#ifdef 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;
}

Demo7 添加项目版本管理

Demo7文件目录:

Demo7[目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
config.h.in
CMakeLists.txt
build [目录] //在这里生成编译结果

每一个项目都需要一个版本号,通过版本号可以记录每个项目版本升级内容,版本间的兼容性等信息。

预定义宏变量

修改config.h.in文件, 定义主版本号和次版本号变量, 这两个变量将在CMakeLists.txt中赋值

// the configured options and settings for Tutorial
#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@

// does the platform provide pow function?
#cmakedefine HAVE_POW

修改CMakeLists.txt文件

修改顶层CMakeLists.txt文件, 在project命令之后添加两条set`命令,用于为版本号赋值。 这里只写添加的部分代码:

#设置主版本号
set (Demo_VERSION_MAJOR 1)
#设置次版本号
set (Demo_VERSION_MINOR 0)

修改 main.cc文件

#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifdef HAVE_POW
  #include <math.h>
#else
  #include <MathFunctions.h>
#endif

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]);
    
#ifdef 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;
}

Demo8 CPack 制作安装包

Demo8文件目录:

Demo8[目录]

main.cc
math [目录]

MathFunctions.h
MathFunctions.cc
CMakeLists.txt
config.h.in
CMakeLists.txt
build [目录] //在这里生成编译结果

CPack是CMake里的一个打包工具, 它可以通过配置生成各个平台上的安装包,其中包括二进制安装包和源码安装包。
这里只修改顶层目录的CMakeLists.txt,在文件最后添加如下内容:

  • 导入InstallRequiredSystemLibraries模块
  • 设置CPack变量:版权,版本信息等
  • 导入CPack模块
# 构建一个 CPack 安装包
#导入InstallRequiredSystemLibraries模块
include (InstallRequiredSystemLibraries)
#设置License文件
set (CPACK_RESOURCE_FILE_LICENSE
  "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
#设置CPack主版本号
set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
#设置CPack次版本号
set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
#导入CPack模块
include (CPack)
  1. 进入 build目录,执行cmake …
  2. 执行cpack -C CPackConfig.cmake 命令生成二进制安装包

guo@guo:~/share/CMake/Demo8/build$ sudo cpack -C CPackConfig.cmake
CPack: Create package using STGZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/guo/share/CMake/Demo8/build/Demo8-1.0.1-Linux.sh generated.
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/guo/share/CMake/Demo8/build/Demo8-1.0.1-Linux.tar.gz generated.
CPack: Create package using TZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/guo/share/CMake/Demo8/build/Demo8-1.0.1-Linux.tar.Z generated.

如上出结果可以看出: 在build目录下生成三个格式的二进制安装包

  • Demo8-1.0.1-Linux.sh
  • Demo8-1.0.1-Linux.tar.gz
  • Demo8-1.0.1-Linux.tar.Z
  1. 执行Demo8-1.0.1-Linux.sh 这安装包 ,使用命令:sh Demo8-1.0.1-Linux.sh
guo@guo:~/share/CMake/Demo8/build$ sh Demo8-1.0.1-Linux.sh
Demo8 Installer Version: 1.0.1, Copyright (c) Humanity
This is a self-extracting archive.
The archive will be extracted to: /home/guo/share/CMake/Demo8/build

If you want to stop extracting, please press <ctrl-C>.
The MIT License (MIT)

Copyright (c) 2013 Joseph Pan(http://hahack.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Do you accept the license? [yN]:
y
By default the Demo8 will be installed in:
  "/home/guo/share/CMake/Demo8/build/Demo8-1.0.1-Linux"
Do you want to include the subdirectory Demo8-1.0.1-Linux?
Saying no will install in: "/home/guo/share/CMake/Demo8/build" [Yn]:
y

Using target directory: /home/guo/share/CMake/Demo8/build/Demo8-1.0.1-Linux
Extracting, please wait...

Unpacking finished successfully

安装完成后,运行结果

guo@guo:~/share/CMake/Demo8/build$ ./Demo8-1.0.1-Linux/bin/Demo 3 4
Now we use our own Math library.
3 ^ 4 is 81

这里附上文章中Demo的源码

CMake Demo.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake(一) 的相关文章

随机推荐

  • win10下安装kubernets

    win10下安装docker for windows后 xff0c 新版是有一个kubernets选项 xff0c 选择启动后 xff0c 一直报 kubernets is starting 的错误 xff0c 原因是 xff0c kube
  • 嵌入式工程师的自我修养

    文章目录 前言一 认知的四个阶段1 不知不知2 知道不知3 知道己知3 1 软硬件3 2 网络3 3 安全技术 xff08 换成你自己的领域 xff09 3 4 真正知道的三个阶段3 4 1 会用3 4 2 了解怎么实现3 4 3 明白为什
  • 利用uORB机制实现数据在不同进程中通信

    uORB实际上是一种设计模式中的观察者模式 xff0c 用于实现一种一对多的依赖关系 xff0c 让多个观察者 xff08 Observer xff09 同时监听某一主题对象 xff08 Subject xff09 当这个主题对象 xff0
  • Android-注解篇

    1 什么是注解 从JDK 5 开始 xff0c Java 增加了注解 xff0c 注解是代码里的特殊标记 xff0c 这些标记可以在编译 类加载 运 行时被读取 xff0c 并执行相应的处理 通过使用注解 xff0c 开发人员可以在不改变原
  • 新品BCM6755A1KFEBG/MT7921LE/MT7921AU WiFi芯片

    博通在WiFi市场具有相当的实力 在WiFi6上有下面这几个解决方案 xff1a 型号 xff1a BCM6755 BCM6755A1KFEBG 类型 xff1a 四核1 5GHz CPU 封装 xff1a BGA 批次 xff1a 新 B
  • Ubuntu : GPG签名验证错误 解决之道sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 6DFBCBAE

    Ubuntu GPG签名验证错误 解决之道 转载 sudo apt key adv keyserver keyserver ubuntu com recv keys Key Where key 61 61 the gpg key id Th
  • T265深度图像输出

    1 T265深度图像输出 1 1 环境依赖 T265摄像头python3pip3opencv pythonpyrealsense2 1 2 安装运行环境 安装秘钥 span class token function sudo span ap
  • Linux版本号串记录(ubuntu系列)

    Linux version 4 4 0 112 generic buildd 64 lgw01 amd64 010 gcc version 5 4 0 20160609 Ubuntu 5 4 0 6ubuntu1 16 04 5 135 U
  • 死锁的四个必要条件

    死锁 在高并发中是一个常见的名词 产生的四个必要条件如下 xff1a 互斥条件 xff1a 一个资源同一时间能且只能被一个线程访问 xff1b 不可掠夺 xff1a 当资源被一个线程占用时 xff0c 其他线程不可抢夺该资源 xff1b 请
  • Sphinx index.rst

    假设我们有两个文本file1 rst和file2 rst他们的内容如下 file1 rst span class hljs header file1 title1 61 61 61 61 61 61 61 61 61 61 61 61 sp
  • Git - 图形化界面操作

    目录 1 新建仓库 2 代码提交 3 代码回滚 4 新建分支 5 合并分支 6 重置合并 7 分支变基 8 分支优选 Git 的图形化界面操作 xff0c 使用 Idea 进行演示 1 新建仓库 对于一个代码仓库 Create Git re
  • CMakeLists

    1 指定 cmake 的最小版本 cmake minimum required VERSION 3 4 1 2 设置项目名称 xff0c 它会引入两个变量 demo BINARY DIR 和 demo SOURCE DIR xff0c 同时
  • 七步实现STM32MP157多核协同工作(Cortex-A7与Cortex-M4通信)

    写在前面 xff1a STM32MP157是ST进军Linux的首款微处理器 xff0c 采用MCU 43 MPU的组合 xff0c 集成两颗主频微800MHz的Cortex A7应用处理器内核 xff08 支持开源linux操作系统 xf
  • 【实战】STM32 FreeRTOS移植系列教程4:FreeRTOS 软件定时器

    写在前面 xff1a 本文章为 STM32MP157开发教程之FreeRTOS操作系统篇 系列中的一篇 xff0c 笔者使用的开发平台为华清远见FS MP1A开发板 xff08 STM32MP157开发板 xff09 stm32mp157是
  • 【实战】STM32 FreeRTOS移植系列教程5:FreeRTOS消息队列

    写在前面 xff1a 本文章为 STM32MP157开发教程之FreeRTOS操作系统篇 系列中的一篇 xff0c 笔者使用的开发平台为华清远见FS MP1A开发板 xff08 STM32MP157开发板 xff09 stm32mp157是
  • 学习嵌入式linux为什么推荐stm32mp157开发板?

    stm32mp157是ST推出的一款双A7 43 M4多核异构处理器 xff0c 既可以学习linux xff0c 又可以学习stm32单片机开发 xff0c 还可以拓展物联网 人工智能方向技术学习 xff0c 并极大丰富linux应用场景
  • STM32 Linux开发板——教程+视频+项目+硬件

    STM32 Linux开发板 适合入门进阶学习的Linux开发板 xff1a 华清远见FS MP1A开发板 xff08 STM32MP157开发板 xff09 开发板介绍 FS MP1A开发板是华清远见自主研发的一款高品质 高性价比的Lin
  • 编程语言对比 面向对象

    C 43 43 面向对象 java面向对象 python面向对象 java中是public int a 61 10 C 43 43 中是 public int a 61 10 C 43 43 中有拷贝构造
  • 嵌入式linux物联网毕业设计项目智能语音识别基于stm32mp157开发板

    stm32mp157开发板FS MP1A是华清远见自主研发的一款高品质 高性价比的Linux 43 单片机二合一的嵌入式教学级开发板 开发板搭载ST的STM32MP157高性能微处理器 xff0c 集成2个Cortex A7核和1个Cort
  • CMake(一)

    CMake xff08 一 xff09 简述 在之前的文章中介绍了 qmake的使用 相比qmake xff0c CMake稍微复杂一点 xff0c 它使用CMakeList txt文件来定制整个编译流程 同时 xff0c CMake会根据