CMakeLists.txt的基本使用语法

2023-05-16

make与Makefile,cmake与CMakeLists.txt

make用来编译c++项目,make命令根据Makefile中配置的编译链接关系;由于Makefile文件的制作是个大工程,因此出现了cmake工具cmake根据CMakeLists.txt来执行cmake命令;

使用CMake编写跨平台工程的流程如下:

(1)编写源文件

(2)编写CMakeLists.txt

(3)由CMake根据CMakeLists.txt来生成相应的makefile文件

(4)使用make并根据makefile调用gcc来生成相应的可执行文件

CMake是一个可以跨平台的编译工具,可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的 makefile 或者工程文件。和make与makefile类似,我们在使用CMake时同样也需要一个文件来提供规则,这个文件就是CMakeLists

CMakeLists.txt

编写CMakeLists.txt最常用的功能就是调用其他的.h头文件和.so/.a库文件,将.cpp/.c/.cc文件编译成可执行文件或者新的库文件。

# 指定cmake最小版本
cmake_minimun_version(VERSION 3.4.1)

# 本CMakeLists.txt的project名称
# 会自动创建两个变量,PROJECT_SOURCE_DIR和PROJECT_NAME 
# ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的文件夹路径
# ${PROJECT_NAME}:本CMakeLists.txt的project名称
# CMAKE_BINART_DIR, PROJECT_BINARY_DIR, <projectName>_BINARY_DIR:这三个变量的含义一样。
project(xxx)

# 获取路径下所有的.cpp/.c/.cc文件,并赋值给变量中
aux_source_directory(路径 变量)

# 给文件名/路径名或其他字符串起别名,用${变量}获取变量内容
set(变量 文件名/路径/...)

# 添加编译选项
add_definitions(编译选项)

# 打印消息
message(消息)

# 编译子文件夹的CMakeLists.txt
add_subdirectory(子文件夹名称) 

# 将.cpp/.c/.cc文件生成可执行文件
add_executable(可执行文件名称 文件)

# 将.cpp/.c/.cc文件生成.a静态库 // add_library(库文件名称 STATIC 文件)
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
# 生成静态库(默认) 
add_library(myCommonLib STATIC util.cpp)
# 生成动态库
add_library(myCommonLib SHARED util.cpp)

# 规定.h头文件路径
include_directories(路径)

# 规定.so/.a库文件路径
link_directories(路径)

# 对add_library或add_executable生成的文件进行链接操作
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
target_link_libraries(库文件名称/可执行文件名称 链接的库文件名称)
# 如果是链接的库,则运行的时候需要把它拷贝到可执行文件名称同目录下

如何设置DGB调试模式请看这里

CMakeLists设置源文件的方法

1.明确制定包含的源文件

add_library(demo demo.cpp test.cpp util.cpp)

2.搜索所有cpp文件

# 发现一个目录下所有的源代码文件,并将列表存储再一个变量中(不会递归遍历目录)
aux_source_directory(. SRC_LIST)
add_library(demo ${SRC_LIST})

3.自定义搜索规则

file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
#或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
#或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST) ${SRC_PROTOCOL_LIST)

添加编译选项

功能1

add_definitions的功能和C/C++中的#define是一样的

# 添加一个宏定义,设置后,代码中即可使用 `TEST_DEBUG`这个宏,等同在代码中增加 #define TEST_DEBUG
add_definitions(-DTEST_DEBUG)

于是cpp代码中,就可以使用TEST_DEBUG这个宏了

#ifdef TEST_DEBUG
...
#else 
...
#endif

问题是,由谁来驱动定义这个宏呢?通过结合options指令可以实现

# 设置一个宏选项默认值ON,
# option选项 不会影响到cpp代码(不会添加#define宏)
option(TEST_DEBUG "test"  ON)
if(TEST_DEBUG )
	message("itis" ${TEST_IT_CMAKE})
	add_definitions(-DTEST_DEBUG )
endif()

最后,在执行cmake时,就可以设置该选项了,并传递该值下去;

cmake .. -DTEST_DEBUG=1

通过cmake-gui也可以很方便的配置选项,如下:
在这里插入图片描述

功能2
add_definitions("-Wall -g")
#没加之前
gcc -c main.c -o test
#添加之后,相当于
gcc -g -Wall -c main.c -o tes

CMakeLists 查找so库的方法

#在指定目录下搜索一个库, 保存在变量MY_LIB中
find_library(MY_LIB "usr/lib/libmylib.so" )

#链接这个库
target_link_libraries(${PROJECT_NAME}  ${MY_LIB})
  1. 常用的预定义变量
变量说明
PROJECT_SOURCE_DIR工程根目录
PROJECT_BINARY_DIR运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build
PROJECT_NAME返回通过project命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在的路径
CMAKE_CURRENT_BINARY_DIRtarget 编译目录
CMAKE_CURRENT_LIST_DIRCMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE当前所在的行
CMAKE_MODULE_PATH定义自己cmake模块所在的路径。SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH重新定义目标链接库的存放位置
  1. 环境变量

    1. 使用环境变量$ENV{name}
    2. 写入环境变量 set(ENV{name} value)
  2. cmake命令的常用参数

Cmake命令行使用:
-G 指明生成的Makefile格式
-D 添加参数
-S 指明源码位置
-B 指明输出路径
例如:
cmake -G “MinGW Makefiles” -S “源码路径” -B “输出路径”
或者
cmake -G “MinGW Makefiles” -D CMAKE_TOOLCHAIN_FILE=“编译工具链路径” -S “源码路径” -B “输出路径”
注意:Cmake是不支持中文的,无论是GUI还是命令行,都严禁出现中文字符.
  1. 一个项目框架文件目录组织
- project
  - .gitignore
  - README.md
  - LICENCE.md
  - CMakeLists.txt
  - cmake
    - FindSomeLib.cmake
    - something_else.cmake
  - include
    - project
      - lib.hpp
  - src
    - CMakeLists.txt
    - lib.cpp
  - apps
    - CMakeLists.txt
    - app.cpp
  - tests
    - CMakeLists.txt
    - testlib.cpp
  - docs
    - CMakeLists.txt
  - extern
    - googletest
  - scripts
    - helper.py
  1. Do’s and Don’ts
    不好的 CMake 的用法
        不要使用全局函数,例如 link_directories,include_libraries,add_definitions 等,请你忘记它们
        不要滥用 PUBLIC,除非有依赖传递,否则请你使用 PRIVATE 替换 PUBLIC
        不要使用 GLOB 来添加文件
        不要直接链接文件,而是链接目标
        链接时千万不要跳过 PUBLIC/PRIVATE,这会导致未来的链接都没有关键字

    良好的 CMake 用法
        把 CMake 视作代码,保持它的整洁和可读性
        围绕 target 构建你的 CMake。将需要的信息打包在 target 里,然后链接那个目标
        导出你的接口
        写 Config.cmake 文件,这是一个库作者应该做的,可以方便别人使用你的库
        使用 ALAS 目标,以保持使用一致性
        将常用的功能提取成函数或者宏,通常函数更好
        使用小写的函数名,全大写是变量
        使用 cmake_policy 或者 range of versions

如何使用CMakeLists.txt 完成一次编译过程

创建如下目录结构

- /myCpp
 - CMakeLists.txt 
 - /build
 - /src
   - myHello.cpp 

myHello.cpp

#include <iostream>
int main() {
    std::cout<<"Hello world!"<<std::endl;
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(Hello)
MESSAGE(STATUS"This is BINARY_dir" ${PROJECT_BINARY_DIR})
MESSAGE(STATUS"This is SOURCE_dir"${PROJECT_SOURCE_DIR})
aux_source_directory(./src DIR_SRCS)
add_executable(${PROJECT_NAME} ${DIR_SRCS})

编译过程

$ cd build
$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
STATUS"This is BINARY_dir"/home/bing/bingCpp/myDemo/build
STATUS"This is SOURCE_dir"/home/bing/bingCpp/myDemo
-- Configuring done
-- Generating done
-- Build files have been written to: /home/bing/bingCpp/myDemo/build
$ make
Scanning dependencies of target Hello
[ 50%] Building CXX object CMakeFiles/Hello.dir/src/main.cpp.o
[100%] Linking CXX executable Hello
[100%] Built target Hello
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMakeLists.txt的基本使用语法 的相关文章

随机推荐

  • 任务调度器算法(leetcode621)

    题目描述如下 xff1a 思路 xff1a 要想完成任务的时间最短 xff0c 那么必须优先处理出现次数最多的任务 xff08 如果将次数多的任务留到最后 xff0c 必然在每次任务之间留出大量的等待时间 xff09 xff0c 因此我们可
  • ubuntu16.04安装docker及桌面

    安装 Docker 所需条件 xff1a 需要 64 位架构的系统和Linux 3 10 内核或更高版本 uname r 注意 xff1a 如果你之前使用APT安装过docker xff0c 为了新版本的docker仓库 xff0c 确保你
  • vncserver too many security failures

    在服务器上开了几个虚拟机 xff0c 装了VNC之后 xff0c 经常遇到报错too many security failures 查了下相关资料 xff0c 原来是有人在暴力破解 xff0c 触发了VNC的黑名单机制 重置黑名单 xff0
  • 计算机网络复习题3(含答案及解析及知识点)

    1 为了使数据在网络中传输时延最小 xff0c 首选的交换方式是 A A 电路交换 B 报文交换 C 分组交换 D 信元交换 交换方式的比较 信元交换 是一种面向连接的快速分组交换技术 xff0c 是通过建立虚电路来进行数据传输 虚电路结合
  • 串级PID和 前馈系统

    1 串级PID 可以这样理解 外环是速度环 内环是电流环 控制的目标是速度 然后如果速度过低 第一级pid后脉冲就增加1随之的 电流环也会增加 xff0c 这样就可以理解 速度环的输出当作电流环的输出 xff0c 他们都是同样的 要大一起大
  • STM32模拟串口总结

    STM32模拟串口总结 发送端的方法 1 纯延时模拟 此方法延时精确度不够 xff0c 或者发送前必须关中断 span class token keyword void span span class token function IO T
  • 工匠小四轴之一_PCB外框结构

    工匠小四轴之一 PCB外框结构 工匠小四轴的PCB就是机架 xff0c 为了最优化设计需要满足以下几个条件 xff1a 美观 xff0c 有科技感 动力效率最大化 质量轻 废话不多说 xff0c 先上图 xff1a 为了美观 xff0c 有
  • px4新建一个uORB消息

    px4新建一个uORB消息 方法非常简单 参考自 https dev px4 io master en middleware uorb html 第一步 在 src Firmware msg 下新建一个 msg文件 文件里面包含需要的变量
  • PX4混控器文件理解

    PX4混控器文件理解 1 简单混控器2 多旋翼混控器纯多旋翼 1 简单混控器 以固定翼的混控文件为例 xff0c 文件位于 Firmware ROMFS px4fmu common mixers fw generic wing main m
  • arm中断(小结10)

    中断 xff1a 分三部分 step 1 set arm cpsr mrs r0 cpsr bic r0 r0 0x80取 0x80 的非 xff0c 清楚第七位 step 2 set vic vectored iterrupt cont
  • parrot 国内源

    parrot 国内源 parrot mirrors etc apt sources list d parrot list China USTC 1Gbps CMCC 1Gbps Cernet 300Mbps ChinaNetUniversi
  • 数据结构C语言单链表的实现和几点注意的问题

    一 定义数据结构 这是本链表中的数据结构 xff0c 需要注意的有两点 xff1a 1 结构指针 xff0c 这是链表中很重要的一个部分 这里面LinkList就是一个结构指针类型 xff0c 一定要注意LinkList的实际含义 2 ty
  • sql查询之分页查询

    文章目录 简介limit实例 专栏目录请点击 简介 分页查询我们一般会用到limit一般分页查询的语法如下 span class token keyword SELECT span 查询列表 span class token keyword
  • yolo系列学习笔记----yolov3

    1 xff0c yolov3的结构 Yolov3中 xff0c 只有卷积层 xff0c 通过调节卷积步长控制输出特征图的尺寸 所以对于输入图片尺寸没有特别限制 DBL 代码中的Darknetconv2d BN Leaky xff0c 是yo
  • slam学习笔记五----视觉里程计的学习1

    一 xff0c 什么是视觉里程计 SLAM系统分为前端和后端 xff0c 前端也称为是视觉里程计 xff0c 主要功能是根据相邻图像的信息粗略的估计出相机的运动 xff0c 为后端提供较好的初始值 视觉里程计的算法有两大类特征点法和直接法
  • SLAM学习笔记-----对极几何及三角化求单目相机的三维坐标

    一 xff0c 使用对极几何约束求R T 第一步 xff1a 特征匹配 提取出有效的匹配点 void find feature matches const Mat amp img 1 const Mat amp img 2 std vect
  • RealSense相机在ros2环境的安装

    一 SDK的安装 在安装前一定要确定SDK和realsense相机之间的版本对应的关系 xff0c 我使用的SDK的版本是 xff1a librealsense 2 51 1 对应的ROS的版本是 xff1a realsense ros 4
  • openVSLAM-stella_vslam的编译安装

    stella vslam 适配的相机硬件有 xff1a stella vslam is a monocular stereo and RGBD visual SLAM system 该算法支持单目 双目还有RGBD的视觉SLAM系统 它兼容
  • Ubuntu下的Kitematic安装启动出现无法使用的问题

    Kitematic的安装环境如下 xff1a Ubuntu16 04 桌面版 Kitematic的版本如下 解压zip后 xff0c 安装deb包 xff0c 然后在app中心 xff0c 找到Kitematic xff0c 运行时无法进入
  • CMakeLists.txt的基本使用语法

    make与Makefile xff0c cmake与CMakeLists txt make用来编译c 43 43 项目 xff0c make命令根据Makefile中配置的编译链接关系 xff1b 由于Makefile文件的制作是个大工程