Cmake的使用

2023-11-19

简介

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。

简言之,cmake是一个可以支持多个平台的编译工具,CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库(so(shared object))

优点

(1) 自动搜索你的软件所依赖的库、头文件,CMake在搜索的时候会将环境变量和注册表(Windows平台)也包含
在内;
(2) 项目的构建目录和源码目录分离:也就是说可以在项目源码目录之外单独建立一个构建目录,用于存放构建过程
中生成的文件
(3) 在配置阶段选择可选的组件:
(4) 很容易在共享库和静态库的构建上进行切换
(5) CMake能自动生成项目文件的依赖关系,同时绝大多数平台上支持并行构建

编译

CMake的编译基本就两个步骤:

cmake
make

cmake 指向CMakeLists.txt所在的目录,cmake后会生成很多编译的中间文件以及makefile文件,所以一般建议新建一个新的目录,专门用来编译

mkdir build
cd build
cmake ../
make

make根据生成makefile文件,编译程序

CMakeLists.txt文件编写

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

# 设置项目名
project(demo)

#打印相关消息消息   
message("Project: ${PROJECT_NAME}")
message("Project Directory: ${PROJECT_SOURCE_DIR}")
message(WARNING "this is warnning message")
message(FATAL_ERROR "this build has many error") # FATAL_ERROR 会导致编译失败

# 设置编译类型
add_executable(demo demo.cpp) # 生成可执行文件
add_library(demo  STATIC util.cpp) # 生成静态库
add_library(demo SHARED util.cpp) # 生成动态库或共享库

# 搜索当前目录下的所有.cpp文件,并存储在SRC_LIST变量中
aux_source_directory(. SRC_LIST) 
add_library(demo ${SRC_LIST}) #默认是静态库

# 自定义搜素规则
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})

# 查找到指定的预编译库log ,并将它的路径存储在变量logLib 中
find_library(logLib log )

# 设置包含的目录,可包含头文件所在目录
include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")

# 设置链接库搜索目录
link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/libs )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")

# 设置链接库
target_link_libraries( demo ${log-lib} log)
# 指定链接动态库或静态库
target_link_libraries(demo liblog.so) # 链接libface.so
# 指定库全路径
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.so)
#库名可以是lib***.so 、 全路径、 ***


set(CMAKE_C_FLAGS_DEBUG "-g -Wall")             #C
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")           #C++
set(SRC_LIST main.cpp test.cpp)                 #设置变量的值
set(SRC_LIST ${SRC_LIST} test.cpp)              #追加变量的值

list(APPEND SRC_LIST test.cpp)                  #追加变量的值
list(REMOVE_ITEM SRC_LIST main.cpp)             #删除变量的值

# 包含其他make文件
include(./common.cmake) # 指定包含文件的全路径
include(def) # 在搜索路径中搜索def.cmake文件
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # 设置include的搜索路径



# 条件控制  if…elseif…else…endif
if(${USER_TARGET_OS} STREQUAL “qnx”)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14 -Wall -DHAS_SOMEIP_BINDING")
elseif(${USER_TARGET_OS} STREQUAL “linux”)
set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -std=gnu++14 -pthread -Wall -DHAS_SOMEIP_BINDING”)
endif()



# 循环
while(condition)
    ...
endwhile()
# start 表示起始数,stop 表示终止数,step 表示步长
foreach(loop_var RANGE start stop [step])
    ...
endforeach(loop_var)
# 示例
foreach(i RANGE 1 9 2)
    message(${i})
endforeach(i)
# 输出:13579

CMakeLists.txt中常用变量

1. 预定义变量

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

2. 环境变量

使用环境变量

 $ENV{Name}

写入环境变量

 set(ENV{Name} value) # 这里没有“$”符号
3. 系统信息

­CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
­CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
­CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
­CMAKE_SYSTEM:系统名称,比如 Linux-­2.6.22
­CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
­CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
­CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686
­UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
­WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin

4. 主要开关选项

BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加

参考资料:
https://blog.csdn.net/afei__/article/details/81201039

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

Cmake的使用 的相关文章

随机推荐

  • MQ如何保证消息的顺序一致性问题?

    产生原因 MQ服务器集群化或MQ采用分区模型架构来存放消息 每个分区对于一个消费者消费消息 解决消息一致性问题 核心思想 消息一定要投递到同一个MQ 且是同一个分区模型且被用一个消费者消费 可以根据消息key对分区模型总数取余来实现 1 大
  • 【云原生•监控】基于Prometheus的云原生集群监控(理论+实践)-03

    云原生 监控 基于Prometheus的云原生集群监控 理论 实践 03 k8s服务组件指标 kubernetes云原生集群作为大规模多节点容器调度平台 在交付和部署上的巨大优势逐渐让其称为一种技术趋势 如基于工作负载快速进行扩 缩容 故障
  • c++通讯录管理系统

    系统需求 代码 include
  • 7-37 5门课的平均分 7-38 等边三角形面积

    目录 7 37 5门课的平均分 输入格式 输出格式 样例 gt 输入样例 输出样例 思路 代码 7 38 等边三角形面积 输入格式 输出格式 输入样例 输出样例 思路 代码 7 37 5门课的平均分 输入5门课程成绩 整数 求平均分 结果保
  • 安装nextcloud文档

    root nextcloud php v PHP 7 2 24 cli built Oct 22 2019 08 28 36 NTS Copyright c 1997 2018 The PHP Group Zend Engine v3 2
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • 电脑迷你世界,迷你世界电脑版

    游戏介绍 配置要求 操作系统 Windows XP Windows Vista Windows 7 Windows 8 运行环境 无特殊需求 CPU Intel Core2 Duo E4600 2 40Hz AMD Athlon 64 X2
  • 关于element-ui中表单重置不生效的原因,及解决方法

    resetFields这个方法是将表单重置为初始值 也就是说 是将表单中的数据重置为dom节点渲染时的值 而不是重置为空对象 也就是说 当你的表单数据 是在dom节点渲染前被赋值的 那么他的初始值就不为空了 还有就是vue中对象是不能直接赋
  • excalidraw 添加手绘中文字体

    Excalidraw是一个矢量绘图工具 支持在绘图中添加文字 Excalidraw目前支持一些常见的中文字体 例如微软雅黑 宋体等 如果你想添加其他的手绘中文字体 可以按照以下步骤进行操作 打开Excalidraw 选择文字工具 在工具栏中
  • 使用python中的SVM进行数据回归预测

    在Python中使用支持向量机 SVM 进行数据回归预测 你可以遵循以下步骤 导入必要的库 from sklearn svm import SVR from sklearn model selection import train test
  • 【数据分析】业务指标的几个相关思考

    业务指标的几个相关思考 1 如何理解数据 拿到数据后 第一步 弄清楚数据里每一列的含义 第二步 对数据进行分类 有助于后期的分析 通常将数据分为 用户数据 行为数据 产品数据 三类 用户数据 指的是用户的基本情况 包括姓名 性别 邮箱 年龄
  • linux下查看redis是否正常运行 和设置密码

    一 查找redis conf文件 我们服务器已经安装了redis 现在通过命令查看下redis的进程 root lnp ps aux grep redis root 7374 0 0 0 0 145312 7524 Ssl 16 37 0
  • Error:(28, 8) java: 类Demo01Array是公共的, 应在名为 Demo01Array.java 的文件中声明

    public 修饰的class类必须与 Java文件名一致 若声明的class非public则文件名无需与类名相同 必须一致
  • Android原生系统真的那么好用吗?安卓原生系统吊打其他系统,因为有Google-Play

    Android原生系统真的那么好用吗 这种问题当然是否定的 原生 Android 指的是直接基于 AOSP 构建的而非手机厂商出厂固件修改的第三方 ROM 但包括 Nexus Pixel 或其它被 Google 直接支持的手机的可能是闭源的
  • 你们所不了解的程序员思维黑洞

    如果你也是程序员 看看你中了几条 1 数数会从 0 开始数起 比如 程序员吵架的时候会说 我数三下 你再不闭嘴 我就不客气了 零 一 二 或者 在列清单的时候 编号会从 0 开始写 为什么会这样 因为 0 是数组的第一个元素 在经过无数次的
  • 1分钟部署自己的AutoGPT

    4 月初 AutoGPT 引发热潮 短短一个多月 它已经在全球最大的开源软件社区 Github 上累积了131 000颗星 其热度依然持续上升 我体验后发现 虽然基于 3 5 模型的 AutoGPT 还无法最终生成完整的报告 但是它确实可以
  • MySQL高级学习笔记(一)

    文章目录 MySQL高级学习笔记 一 1 索引 1 1索引概述 1 2索引优势劣势 1 3索引结构 1 3 1BTREE 结构 1 3 2B TREE 结构 1 3 3MySQL中的B Tree 1 4索引分类 1 5索引语法 1 5 1
  • agplv3_我是否需要根据AGPLv3许可证提供对源代码的访问?

    agplv3 GNU Affero通用公共许可证版本3 AGPLv3 是与GPLv3几乎相同的copyleft许可证 两种许可证具有相同的版权保留范围 但在一个重要方面存在实质性差异 AGPLv3的第13节规定了GPLv2或GPLv3中不存
  • 断点续传----位图

    首先了解什么是位图和他的工作原理 定义 位图就是bitmap的缩写 所谓bitmap 就是用每一位来存放某种状态 适用于大规模数据 该数据都是不重复的简单数据 通常是用来判断某个数据存不存在的 工作原理 查找一个数是否存在 其实答案就是存在
  • Cmake的使用

    简介 CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 他能够输出各种各样的makefile或者project文件 能测试编译器所支持的C 特性 类似UNIX下的automake 只是 CMake 的