Cmake笔记记录

这篇具有很好参考价值的文章主要介绍了Cmake笔记记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

工作后开发内容都是在Linux系统下完成,cmake使用比较频繁,找到一篇很不错的CMake笔记。
记录下来方便自己查阅。

1.CMake介绍

CMake是一种跨平台的编译配置工具,它可以在不同的平台下基于同样的源代码文件生成对应的工程文件。例如Makefile和VS工程. 使用CMake的流程如下:
①编写CMakeLists.txt
②执行cmake PATH或ccmake PATH生成Makefile
③使用make进行编译

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

2.示例一:编译单个文件

  • 工程目录如下
./Demo1
    |
    +--main.cpp

现在有一个源文件main.cpp,程序里面包含一个函数power,main中调用了它,在同目录下编写CMakeLists.txt文件。
Cmake笔记记录,C++,Linux,cmake
main.cpp

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

/**
 * 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;
}

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

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

# 项目信息
project (Demo1)

# 指定生成目标
add_executable(Demo main.cpp)

上面的CMakeLists.txt文件出现如下命令:

  • cmake_minimum_required:表示指定运行此配置文件所需的CMake的最低版本
  • project:参数值Demo1,表示此项目的名称是Demo1
  • add_executable:将名为main.cpp的文件编译成一个名为Demo的可执行文件

在当前目录执行cmake . cmake就会根据平台自动生成工程文件,未报错就继续执行make,生成可执行文件。
Cmake笔记记录,C++,Linux,cmake

  • 运行可执行文件
    Cmake笔记记录,C++,Linux,cmake
  • 指定DEBUG模式
    也可以在CMakeLists.txt文件中添加以下代码来指定DEBUG模式.
set(CMAKE_BUILD_TYPE Debug)

①修改CMakeLists.txt文件
Cmake笔记记录,C++,Linux,cmake
②终端执行make clean
③将CMakeCache.txt文件删除,重新进行cmake .
Cmake笔记记录,C++,Linux,cmake

CMAKE_BUILD_TYPE

1.可选值包括
Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件
Release:用于构建的优化的库或可执行文件,不包含调试符号
RelWithDebInfo:由于构建较少的优化库或可执行文件,包含调试符号MinSizeRel:用于不增加目标代码大小的优化方式,来构建或可执行文件

2.使用方法
set(CMAKE_BUILD_TYPE "Debug") # CMakeLists.txt中指定
或者
cmake .. -D CMAKE_BUILD_TYPE=“Debug” # 生成时命令行指定

3.示例二:编译同个目录下多个文件

  • 工程目录如下,把power函数单独写进一个MathFunctions.c的源文件中
./Demo2
    |
    +--main.cpp
    |
    +--MathFunctions.cpp
    |
    +--MathFunctions.h

Cmake笔记记录,C++,Linux,cmake
main.cpp

#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;
}

MathFunctions.cpp

/**
 * 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;
}

MathFunctions.h

#ifndef POWER_H
#define POWER_H

extern double power(double base, int exponent);

#endif

CMakeLists.txt

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

# 项目信息
project (Demo2)

# 指定生成目标
add_executable(Demo main.cpp MathFunctions.cpp)

此时CMakeLists.txt修改只是在add_executable命令中增加了一个MathFunctions.cc,如果源文件太多,可以使用aux_source_directory命令。

aux_source_directory()

该命令会查找指定目录下的所有源文件,然后把结果存进指定变量名,通过${variable}来使用变量。

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})

4.示例三:编译多个目录下多个文件

  • 工程目录如下,将MathFunctions.h和MathFunctions.cc文件移动到单独的Math目录下。
./Demo3
    |
    +--main.cpp
    |
    +--math/
            |
            +--MathFunctions.cpp
            |
            +--MathFunctions.h

需要在根目录和math下各建立一个CMakeLists.txt文件,先将math目录下的文件编译成静态库再由main函数调用。
只需要将示例二源码中main.cpp引用路径由#include "MathFunctions.h"改为#include "math/MathFunctions.h"即可。

根目录中的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)

使用命令add_subdirectory指明项目包含一个子目录math,这样math目录下的CMakeList.txt 和源代码也会被处理。使用命令 target_link_librarys指明可执行文件main需要链接一个名为MathFunctions的链接库。

add_subdirectory()

target_link_librarys()

add_library()

子目录中的CMakeLists.txt

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

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

使用命令add_library将src目录中的源文件编译为静态链接库

5.示例四:通过CMake自定义编译选项

CMake允许为项目增加编译选项,从而根据用户的环境和需求选择最合适的编译方案。

例如,可以把MathFunctions库设为一个可选的库,如果该选项为ON,就是用该库的数学函数来进行计算,否则就调用标准库中的数学函数库。

  • 工程目录如下
./Demo4
    |
    +--main.cpp
    |
    +--config.h.in
    |
    +--CMakeLists.txt
    |
    +--math/
            |
            +--MathFunctions.cpp
            |
            +--MathFunctions.h
            |
            +--CMakeLists.txt

Cmake笔记记录,C++,Linux,cmake
①修改根目录下的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)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunction)
endif (USE_MYMATH)

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

# 指定生成目标
add_executable (Demo ${DIR_SRCS})
target_link_libraries (Demo ${EXTRA_LIBS})
  • 其中configure_file命令用于加入一个配置文件config.h,这个文件由CMake从config.h.in生成,通过这样的机制,可以通过预定义一些参数和变量来控制代码的生成
  • option命令添加了一个USE_MYMATH选项,并且默认值是ON
  • if (USE_MYMATH)根据USE_MYMATH变量的值决定是否使用math目录下的MathFunctions库
  • option选项必须放置在coufibure_file 前,否则会按照没有定义USE_MYMATH来生成config.h

configure_file()

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

复制一份输入文件到输出文件,替换输入文件中被@VAR@或者${VAR}引用的变量值。

configure_file的其他选项
COPYONLY:只拷贝文件,不进行任何的变量替换。这个选项在指定了NEWLINE_STYLE选项时不能使用(无效)。
ESCAPE_QUOTES:躲过任何的反斜杠(C风格)转义。
@ONLY:限制变量替换,让其只替换被@VAR@引用的变量(那么 ${VAR}格式的变量将不会被替换)。这在配置${VAR}语法的脚本时是非常有用的。
NEWLINE_STYLE style:指定输出文件中的新行格式。UNIX和LF的新行是\n,DOS和WIN32和CRLF的新行格式是\r\n。这个选项在指定了COPYONLY选项时不能使用(无效)。
通常情况下,输入文件以.h.in为后缀,输出文件以.h为后缀。
eg.

configure_file(src/translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) # f=复制src文件夹下的translations.qrc文件到编译的目录下

修改main.cpp文件
让其根据USE_MYMATH的预定义值来决定调用标准库还是MathFunctions库

#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;
}

上面的程序引用了一个config.h,config.h控制是否定义了USE_MYMATH
config.h由config.h.in生成
config.h.in

#cmakedefine USE_MYMATH

我们要做的第一步是在顶层的CMakeLists.txt文件中添加该选项

CMake会自动根据CMakeLists配置文件中的设置生产config.h文件。
使用CMake进行编译即可得到使用MYMATH的编译版本,修改CMakeLists.txt中的USE_MYMATH为OFF即可使用库函数中的函数。

测试如下:
CMakeLists.txt中的USE_MYMATH为ON
Cmake笔记记录,C++,Linux,cmake
使用cmake .后生成的config.h
Cmake笔记记录,C++,Linux,cmake
运行结果:
Cmake笔记记录,C++,Linux,cmake
CMakeLists.txt中的USE_MYMATH为OFF
Cmake笔记记录,C++,Linux,cmake
使用cmake .后生成的config.h
Cmake笔记记录,C++,Linux,cmake
运行结果:
Cmake笔记记录,C++,Linux,cmake

6.示例五:CMake指定安装规则

CMake也可以指定安装规则,可以通过在产生Makefile后使用make install

首先在math/CMakeLists.txt的结尾添加下面两行:

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

上面的代码指明了MathFunctions库的安装路径,之后修改根目录的CMakeLists文件,在末尾添加下面几行:

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

通过上面的设置,生成的Demo文件和MathFunctions函数库。libMathFunctions.o将会被复制到/usr/local/bin中,而MathFunctions.h和生成的config.h文件将会被复制到/usr/local/include中。

PS:这里需要加权限sudo进行make install,否则会失败
Cmake笔记记录,C++,Linux,cmake
cmake .
sudo make install
Cmake笔记记录,C++,Linux,cmake

这里的/usr/local是默认安装目录,可以通过修改CMAKE_INSTALL_PREFIX变量的值来制定安装目录。

7.支持gdb

8.添加环境检查

9.添加版本号

10.生成安装包

11.导入第三方库

在CMake中导入第三方库可以通过include_directorieslink_directories设置第三方库的路径,然后使用target_link_libraries进行链接。

12.链接本地库文件

官方推荐使用find_library获得库绝对目录然后接target_link_libraries

find_library(VI_LIB vi ./vi/lib)
target_link_libraries(${PROJECT_NAME} ${VI_LIB})

13.

14.CMake 复制文件方法

http://t.zoukankan.com/JoyPoint-p-11629521.html

FILE-COPY

ADD_CUSTOM_COMMAND

ADD_CUSTOM_TARGET

15.关于CPack打包

https://blog.csdn.net/lqzer/article/details/125238748

16.关于install的用法

install用于指定在安装时运行的规则。它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等。

https://blog.csdn.net/qq_38410730/article/details/102837401

# 1.安装的文件夹
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/biz_sdk/lib/linux_lib/ DESTINATION lib)

# 2.安装的文件
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config.json DESTINATION ./)

# 3.安装的动态链接库(库的软链接也会拷贝过去)
install(FILES ${PROJECT_SOURCE_DIR}/lib/libFormatConversion.so DESTINATION lib)

17.set_target_properties

set_target_properties(
Thirdlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/libThirdlib.so
)

# 举例
set_target_properties(
MVS 
PROPERTIES IMPORTED_LOCATION 
${MVS_SOURCE_DIR}/lib/64/libMvCameraControl.so
)

18.set_property

https://blog.csdn.net/sinat_31608641/article/details/123834265

在指定域中设置一个命名属性

set_property(<GLOBAL                            |
                DIRECTORY [dir]                   |
                TARGET    [target1 [target2 ...]] |
                SOURCE    [src1 [src2 ...]]       |
                TEST      [test1 [test2 ...]]     |
                CACHE     [entry1 [entry2 ...]]>
               [APPEND][APPEND_STRING]
               PROPERTY <name>[value1 [value2 ...]])

在某个域中对零个或多个对象设置一个属性。第一个参数决定该属性设置所在的域。它必须为下面中的其中之一:

GLOBAL域是唯一的,并且不接特殊的任何名字。

DIRECTORY域默认为当前目录,但也可以用全路径或相对路径指定其他的目录(前提是该目录已经被CMake处理)。

TARGET域可命名零或多个已经存在的目标。

SOURCE域可命名零或多个源文件。注意:源文件属性只对在相同目录下的目标是可见的(CMakeLists.txt)。

TEST域可命名零或多个已存在的测试。

CACHE域必须命名零或多个已存在条目的cache.

必选项PROPERTY后面紧跟着要设置的属性的名字。其他的参数用于构建以分号隔开的列表形式的属性值。如果指定了APPEND选项,则指定的列表将会追加到任何已存在的属性值当中。如果指定了APPEND_STRING选项,则会将值作为字符串追加到任何已存在的属性值。

举例:

set_property(TARGET hikcamera_client PROPERTY POSITION_INDEPENDENT_CODE ON)

其中POSITION_INDEPENDENT_CODE ON表示编译成动态库。

19.CMAKE_PREFIX_PATH

https://www.cnblogs.com/Fitanium/p/16181605.html

20.GLOB和GLOB_RECURSE

file的一个作用是生成目录列表。文章来源地址https://www.toymoban.com/news/detail-600217.html

// 添加当前目录下的所有c文件列表到lib_srcs变量中
file(GLOB lib_srcs *.c)

// 添加当前目录及其子目录下的所有c文件列表到lib_srcs变量中
file(GLOB_RECURSE lib_srcs *.c)

到了这里,关于Cmake笔记记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vscode g++ cmake 学习笔记

    1 Linux常用指令   2开发环境搭建    3GCC编译器       4th gdb 调试器 5vscode  6cmake            

    2024年03月16日
    浏览(43)
  • cmake与交叉编译(x86 to arm)过程和问题全记录

    公司维护一批c++动态库,由于生产需要,每次更新都要在windows、linux_x86、kylin_arm等多个环境中编译一遍,操作比较麻烦,所以想通过交叉编译的方式在一台机器上边编译多个环境的动态库,减少工作量。考虑到工作难度以及本人水平,决定从官方发布的成品交叉编译工具链中

    2024年04月28日
    浏览(44)
  • Linux下安装 CMake

     我们选择下载直接可以使用的版本,右键保存链接地址,打开Linux系统(以Ubuntu为例) 历史版本下载地址:Index of /files 注意: 这里不要装太老的cmake版本,因为后面make的时候没法做,要装 3.16 以上的 创建/opt/cmake目录,在该目录下执行 wget -c https://cmake.org/files/v3.22/cmake-3.

    2024年02月08日
    浏览(32)
  • Linux下CMake开发

    编写CMakeLists.txt 编写C++文件main.cpp 编译和运行 一般把CMakeLists.txt文件放在工程目录下,使用时,先创建一个叫build的文件夹(这个并非必须,因为cmake命令指向CMakeLists.txt所在的目录,例如cmake … 表示CMakeLists.txt在当前目录的上一级目录。cmake后会生成很多编译的中间文件以及

    2024年02月15日
    浏览(38)
  • Cmake 之Linux库编译

    一 camake第一列,C编译为so库 对应的CmakeList文件 二 Cmake介绍 2.1 CMake 是一个跨平台的项目构建工具,CMake可以生成各种构建系统的配置文件,包括Makefile、Visual Studio项目文件、Xcode项目文件等,可以帮助开发人员简化项目的构建过程,提高开发效率 2.2 CMake执行流程图 2.3 Cmak

    2024年01月21日
    浏览(43)
  • Linux 系统下 CMake 示 例

    CMake 是一个开源的跨平台工具,可以构建、测试和打包软件。 它具有如下特性: 自动搜索可能需要的程序、库和头文件的能力; 独立的构建目录(如 build ),可以安全清理; 支持复杂的自定义命令(下载、生成各种文件); 自定义配置可选组件; 从简单的文本文件( C

    2024年02月09日
    浏览(26)
  • CMake 学习笔记(控制生成 Release 和 Debug)

    CMake 支持4中Build type。分别是: Debug : 调试模式,带调试信息,没有任何的优化 Release : 没有调试信息,速度优化 RelWithDebInfo:执行部分的优化,带有调试信息 MinSizeRel : 生成的可执行文件的体积最小 下面的例子使用 MSYS2 里面的cmake 来演示。 用个非常简单的例子: CMake

    2024年02月12日
    浏览(34)
  • Linux下CMake安装遇到的问题

    在使用pip install cmake安装完cmake以后,想要检查一下cmake的版本,于是输入 结果出现如下报错: 这个问题是由于CMake无法找到正确的安装路径。 首先,卸载现有的cmake: 然后,使用Anaconda提供的CMake包来安装: 安装完成以后即可解决问题。

    2024年04月12日
    浏览(45)
  • 使用CMake交叉编译Arm Linux程序

    注意,工具链文件的指定一定要紧跟cmake命令之后,不能放到 … 后面构建arm架构cmake 工程里新建一个文件叫arm_linux_setup.cmake arm_linux_setup.cmake内容如下

    2024年02月03日
    浏览(53)
  • Linux下安装CMake的两种方法

    方法一:使用包管理器安装CMake 在Linux系统中,可以使用包管理器来安装CMake。不同的Linux发行版可能使用不同的包管理器,下面以常见的Ubuntu系统为例: 打开终端,输入以下命令更新包管理器的软件源信息: 安装CMake: 输入管理员密码确认安装。包管理器将自动下载并安装

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包