CMake的原理与使用方法

一.为什么需要CMake,什么是CMake

   1.由于各种make工具遵循不同的规范和标准,所执行的Makefile格式也不同,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。

这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。

CMake 就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。让软件真正实现了跨平台。

一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等 。

   

2.官方文档网址:www.cmake.org

3.CMake的主要特点

跨平台:CMake可以在多种操作系统上运行,包括Windows、Linux、macOS等。

编译器无关:CMake支持多种编译器,如GCC、Clang、Microsoft Visual C++等。

自动化:CMake可以自动检测系统特性,如库、头文件和编译器特性,并根据这些信息生成构建文件。

可扩展性:CMake提供了模块和脚本机制,允许用户扩展其功能。

生成多种构建系统:CMake可以生成多种构建系统的构建文件,如Makefile、Ninja、Visual Studio工程文件等。

开发语言:CMake的开发语言是C和C++。

4.其他构建工具     

除了CMake外还有很多其他构建工具:XMake,qmake,Scons, Ninja, Meson, Baze等

二.CMake怎么用

1.CMake与makefile关系图

2.CMake处理原理

CMake有两个主要的阶段。首先是"配置(configure)",在此阶段CMake处理所有的输入然后创建软件构建过程的内部表达。第二个阶段是"生成(generate)",负责创建出实际的构建文件。

1环境变量与缓存

对1999年甚至是今天的许多构建系统来说,生成工程时都要用到底层(shell级别)的环境变量。典型的情况是,用PROJECT_ROOT环境变量来指向源码树的根目录。环境变量还被用于指定可选软件包和外部软件包。但是使用环境变量的方法也有弊端,它需要每次构建时都重新设置环境变量。为解决这个问题,CMake使用缓存文件来存储生成过程中用到的所有变量。这些变量不再是环境变量,而是CMake变量。CMake针对某个特定构建树第一次运行时,会创建一个CMakeCache.txt文件,存储当前构建过程中需要用到的CMake变量。这个缓存文件属于构建树的一部分,所以在之后的每次针对该构建树的重新配置时, 这些变量都是可重用的。

2配置阶段

在配置阶段,CMake首先尝试读取CMakeCache.txt文件,该文件在第一次运行时生成。然后,读取源码树根目录下的CMakeLists.txt文件,并使用CMake词法分析器处理。CMakeLists.txt中的每条命令都由一个命令模式对象执行。通过include和add_subdirectory命令,更多的CMakeLists.txt得到执行。对于每条命令,CMake都有一个C++对象来处理,比如add_library, if, add_executable, add_subdirectory,include等。实际上,整个CMake语言就是以命令调用的方式实现的。词法分析器只不过将输入文件内容转化为命令和命令参数而已。

配置阶段主要是运行用户定义的CMake代码。等到执行完之后,以及所有缓存变量计算完成之后,CMake在内存中得到一个项目构建的内部表达。这个内存中的内部表达包括了所有的库文件,可执行文件,定制的命令,以及生成指定generator(指特定的编译环境)所需的其他必要信息。这时,CMakeCache.txt会被存储到磁盘上,供以后重新运行CMake时使用。

项目在内存中的表达实际上是一些待生成的目标的集合,包括基本的库文件和可执行文件。CMake还支持目标的定制,即用户可以定义输入和输出,并提供定制的可在构建过程中运行的可执行文件或脚本。CMake将每个目标存储在一个cmTarget对象中,然后多个cmTarget存储在一个cmMakefile对象中,cmMakefile对象实际上用来存储源码树中某个目录中的所有目标。最后得到的结果是一棵cmMakefile对象的树,树结点中存储cmTarget对象的映射。

3生成阶段

一旦配置(configure)阶段完成,生成(generator)阶段就可以开始了。生成阶段将生成用户指定类型(如Visual Studio或GNU/Linux GCC)的构建文件。这时,目标的内部表达(库,可执行文件,定制目标)转化为本地构建工具的输入文件,如Visual Studio或Makefile文件。CMake由配置阶段获得的内部表达要尽可能地抽象和通用,这样的数据结构才能被不同的本地构建工具所共享。

3.安装cmake

sudo apt-get install cmake

4.构建工程项目流程

(1).构建CMakeLists.txt

CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeLists.txt,并在其中包含 CMake 构建您的 C/C++ 库时需要使用的命令。如果您的原生源代码文件还没有 CMake 构建脚本,您需要自行创建一个,并在其中包含适当的 CMake 命令。

(2).在包含CMakeLists.txt的目录下使用cmake

         1)构建放在当前目录下(内部构建):cmake . 即在当前目录cmake,在当前目录build。

         2)在当前目录下创建build文件夹存放构建文件(外部构建),build内输入cmake ..。即在上级目录cmake,在该目录下build。

结果:生成4个东西:CMakeFiles文件夹、cmake_install.cmake、CMakeCache.txt、Makefile

只要产生Makefile文件,就说明cmake成功了

(3).在包含Makefile的目录下使用make

直接在build出4个东西的目录下(命令针对的是Makefile)输入make

(4).生成可执行文件。 输入./文件名运行

5.举例

1)先编写main.cpp

#include <iostream>

using namespace std;

int main(){

cout<<"hello,world"<<endl;

return 0;

}

2)编写CMakeLists.txt

PROJECT(HELLO)            #工程名为HEELO

SET(SRC_LIST main.cpp)    #变量SRC_LIST包含main.cpp

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST}) #生成可执行程序文件名为hello,源文件读取变量SRC_LIST中内容

3)cmake

cmake .

生成了4个东西:CMakeFiles文件夹、cmake_install.cmake、CMakeCache.txt、Makefile

4)make

make

生成了可执行文件hello

5)执行

./hello

显示"hello,world"

三.如何编写CMakeLists.txt

1.CMakeLists.txt并不是顺序执行的,相当于一系列的声明

CMakeList.txt 的语法比较简单,由命令、注释和空格组成:

#后面内容为注释;

命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔,其中命令是不区分大小写的。

2.语法详解

PROJECT关键字 ※

可以用来指定工程的名字和支持的语言,默认支持所有语言

PROJECT(HELLO) 指定了工程的名字为HELLO,且支持所有语言(建议这样做)

PROJECT(HELLO CXX)指定了工程的名字为HELLO,仅支持C++语言

PROJECT(HELLO C CXX)指定了工程的名字为HELLO,仅支持C和C++语言

该指定隐式地定义了两个CMake变了

<projectname>_BINARY_DIR

<projectname>_SOURCE_DIR

本例中是HELLO_BINARY_DIR、HELLO_SOURCE_DIR

MESSAGE关键字就可以直接使用这两个变量。当前都指向当前的工作目录

SET关键字

SET用来显式的指定变量,可以为多个

SET(SRC_LIST main.cpp) 意为SRC_LIST变量包含了main.cpp

SET(SRC_LIST main.cpp test1.cpp test2.cpp) 意为SRC_LIST变量包含了main.cpp、test1.cpp、test2.cpp

MESSAGE关键字

向终端输出用户自定义的信息,主要包含三种:

SEND_ERROR:产生错误,生成过程被跳过

STATUS:输出前缀为- -的信息

FATAL_ERROR:立即终止所有cmake过程

ADD_EXECUTABLE关键字 ※

生成可执行文件

ADD_EXECUTABLE(hello $(SRC_LIST)),生成的可执行文件名为hello,源文件读取变量SRC_LIST中的内容

也可直接写为 ADD_EXECUTABLE(hello main.cpp)

注意:工程名的HELLO和生成的可执行文件hello是没有任何关系的

所以,上例中的5行CMakeLists.txt可以简化为2行:

PROJECT(HELLO)

ADD_EXECUTABLE(hello main.cpp)

ADD_SUBDIRECTORY关键字

①有子目录时,要用ADD_SUBDIRECTORY关键字包含所有需要访问的子文件夹。除了工程目录外,每个被访问的子目录里也都需要有一个CMakeLists.txt说明

②将目标文件放入构建目录的bin子目录:ADD_SUBDIRECTOR(子目录名 bin):自动在子目录下新建一个名为bin的子目录,存放中间二进制文件、目标二进制文件、库文件。

注意:文件就是file。目录(文件夹)就是directory。

语法基本原则

(1).变量取值 ${ }

(1).分隔多个文件:空格或者分号

(3).大小写:指令大小写不敏感,参数和变量对大小写敏感

3.安装文件

INSTALL(FILES 文件名 DESTINATION 目标地址)

举例3:

工程目录下的CMakeLists.txt添加一行:

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake)   #会自动安装到/usr/local/share/doc/cmake下

DESTINATION后面:

(1).写绝对路径

(2).相对路径:

CMAKE_INSTALL_PREFIX 默认是在/usr/local/

若想要更改,可以手动设置

set(CMAKE_INSTALL_PREFIX "目标路径")

这时候再 DESTINATION ${CMAKE_INSTALL_PREFIX},就导出到目标路径上了。

4.可执行文件安装

在src的CMakeLists.txt里输入

INSTALL(TARGETS hello DESTINATION bin)

5.生成静态库和动态库

SET(变量 源文件名)

ADD_LIBRARY(库名 STATIC或SHARED ${变量})

构建动态库(命令用SHARED) (构建静态库,命令用STATIC)

举例:

SET(LIBHELLO_SRC hello.cpp)

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})    #生成动态库libhello.so

6.使用外部头文件和共享库

 (1)添加头文件搜索路径:

  INCLUDE_DIRECTORIES(路径)

 (2)添加需要链接的共享库

TARGET_LINK_LIBRARIES(源文件名 库名)

TARGET_LINK_LIBRARIES(main libhello.so)    #链接动态库

TARGET_LINK_LIBRARIES(main libhello.a)     #链接静态库

四.QT中的CMake

1.QMake和CMake

  qmake和cmake两者都用来构建系统,都生成一个Makefile,该文件由make读取以构建项目,告诉编译器和链接器该做什么,以创建可执行文件(或动态或静态库)。

  qmake专注于使用Qt的项目,QtCreator可以轻松生成项目文件(适合初学者),并由QtCreator支持;CMake用于广泛的项目,支持多种平台和语言,受多个IDE支持:例如QtCreator,Visual Studio,

  生成多个IDE的项目描述,包含简化Qt使用的命令(最重要:automoc)。如果项目使用Qt,则最好使用qmake。 CMake更通用,几乎适合任何类型的项目。

2.Qt公司自Qt 5.14版本开始推荐使用CMake作为Qt项目的构建系统,而不是qmake。

  CMake是一个跨平台的构建系统,支持多种编译器和IDE,而qmake是Qt自带的构建工具,主要用于Qt项目。

Qt公司推荐使用CMake的原因包括:

跨平台支持:CMake支持多种操作系统和编译器,使得Qt项目可以在不同的平台上轻松构建。

社区支持:CMake拥有一个活跃的社区,提供了大量的模块和工具,可以帮助开发者更高效地构建和管理项目。

集成支持:CMake与许多IDE和构建系统紧密集成,如Visual Studio、Xcode、Make等。

模块化:CMake提供了模块化的构建脚本,使得项目可以更容易地管理和扩展。

性能:CMake的配置和生成过程通常比qmake更快,特别是在处理大型项目时。

3.qmake更适合构建小型Qt项目,简单易用;而cmake更适合构建复杂、跨平台的C++项目,功能更加强大和灵活。

如果没有什么跨平台需求的话,qmake也是没有问题的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/666055.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA入门】Day06 - 字符串

【JAVA入门】Day06 - 字符串 文章目录 【JAVA入门】Day06 - 字符串一、API二、字符串2.1 创建 String 对象的方式2.2 字符串内存模型 三、字符串的相关操作3.1 字符串的比较3.2 遍历字符串3.3 统计字符出现次数3.4 拼接字符串3.5 字符串反转 四、StringBuilder3.1 构造方法3.2 …

束测后台实操文档2-OpenWrt

束测后台实操文档1-PVE、PBS 上面文&#xff0c;把proxmox装好并添加好PBS上的镜像存储空间后&#xff0c;还原已经做好的镜像基本上就可以在已有的镜像下开展工作了。 调试的PVE环境一般两个网口&#xff0c;一个外网wan&#xff0c;一个子网lan&#xff0c;虚拟机一般在lan…

体验Photoshop:无需下载,直接在浏览器编辑图片

搜索Photoshop时&#xff0c;映入眼帘的是PS软件下载&#xff0c;自学PS软件需要多长时间&#xff0c;学PS软件有必要报班吗...PS软件的设计功能很多&#xff0c;除了常见的图像处理功能外&#xff0c;还涉及图形、文本、视频、出版等。不管你是平面设计师&#xff0c;UI/UX设计…

可变参数

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;还可以定义可变参数。可变参数也称不定长参数&#xff0c;即传入函数中的实际参数可以是任意多个。 定义可变参数时&#xf…

植物大战僵尸杂交版破解C++实现

文章目录 前言准备工作&#xff1a;基地址与偏移UI界面设计和绑定项目模板总览图生成与实现信号处理1、阳光值更新:BTN12、三种钱币值更新:BTN2-BTN43、冷却刷新:BTN54、锁定阳光&#xff1a;check15、无冷却&#xff1a;check26、OnTimer&#xff08;&#xff09;和OnClose&am…

Linux上传文件

在finalshell中连接的Linux系统中&#xff0c;输入命令rz然后选择windows中的文件即可。

透视茅台股东大会三大关键词:稳定、竞争力、创新

执笔 | 尼 奥 编辑 | 扬 灵 “让我们携手共同致力于茅台的稳定、健康、可持续发展。”上任刚满一个月的贵州茅台党委书记、董事长张德芹&#xff0c;在5月29日的贵州茅台酒股份有限公司2023年度股东大会上迎来首秀。 张德芹在40多分钟脱稿演讲与30多分钟互动环节中&#x…

TiDB学习9:Ti Cloud简介

目录 1. 为什么选择TiDB 2. 多租户 3. TiDB架构 4. 什么是TiDB Cloud 5. TiDB Cloud Provider Region 6. TiDB Cloud 入门 6.1 在浏览器中打开TiDB Cloud 6.2 创建您的账户 6.3 Developer Tier 与Dedicated Tier 6.3.1 Developer Tier 6.3.2 Dedicated Tier 6.3.2.…

项目纪实 | 版本升级操作get!GreatDB分布式升级过程详解

某客户项目现场&#xff0c;因其业务系统要用到数据库新版本中的功能特性&#xff0c;因此考虑升级现有数据库版本。在升级之前&#xff0c;万里数据库项目团队帮助客户在本地测试环境构造了相同的基础版本&#xff0c;导入部分生产数据&#xff0c;尽量复刻生产环境进行升级&a…

【NVM】nvm常用命令,切换node版本命令

nvm常用的命令&#xff0c;切换node版本命令 nvm 查看支持安装的node版本 nvm list available nvm安装指定版本node nvm install 版本号 例如&#xff1a;nvm install 10.24.1 nvm查看本机安装所有node版本 nvm list nvm切换node版本 nvm use 10.24.1 检测当前node版本 node -…

玄机平台应急响应—Linux日志分析

1、前言 啥是日志呢&#xff0c;日志就是字面意思&#xff0c;用来记录你干了啥事情。日志大体可以分为网站日志和系统日志&#xff0c;网站日志呢就是记录哪个用户在哪里什么时候干了啥事&#xff0c;以及其它的与网站相关的事情。系统日志呢&#xff0c;就是记录你的电脑系统…

动态分配函数参数用二级指针的作用

文章目录 前言一、案例 前言 在一些情况下&#xff0c;我们需要在函数内部动态地分配内存来存储结构体&#xff0c;并且需要在函数外部访问该结构体。在这种情况下&#xff0c;可以使用二级指针作为函数参数来实现动态内存分配&#xff0c;并且在函数外部使用指针访问结构体。…

12V转19V4A升压恒压WT3207

12V转19V4A升压恒压WT3207 WT3207是款高效的PWM升压控制器&#xff0c;采用SO-8封装设计。该控制器经过优化以适应低输入电压应用&#xff0c;具有从5V至36V的广泛输入电压范围&#xff0c;适用于需要提高12V、15V和19V系统电压的场合&#xff0c;特别是对于两节或三节锂离子电…

Apache Doris 基础 -- 数据表设计(数据模型)

Versions: 2.1 1、模型概览 本主题从逻辑角度介绍了Doris中的数据模型&#xff0c;以便您可以在不同的业务场景中更好地使用Doris。 基本概念 本文主要从逻辑的角度描述Doris的数据模型&#xff0c;旨在帮助用户在不同的场景更好地利用Doris。 在Doris中&#xff0c;数据在…

GEE 10m近实时 LULC 数据集Dynamic World

Google Earth Engine 和 Dynamic World Google 利用其地球引擎&#xff08;Earth Engine&#xff09;和人工智能&#xff08;AI&#xff09;平台技术&#xff0c;推出了 Dynamic World 数据库&#xff0c;能够提供接近实时的全球土地环境数据。Dynamic World 是基于 Google Ear…

【Gradle】Gradle的本地安装和使用

目录 1、Gradle 的安装 2、集成 IntelliJ IDEA 3、使用 Gradle Gradle 完全兼容 Maven 和 Ivy 仓库&#xff0c;你可以从中检索依赖也可以发布你的文件到仓库中&#xff0c;Gradle 提供转换器能把 Maven 的构建逻辑转换成 Gradle 的构建脚本。 1、Gradle 的安装 Gradle 的…

卷积网络迁移学习:实现思想与TensorFlow实践

摘要&#xff1a;迁移学习是一种利用已有知识来改善新任务学习性能的方法。 在深度学习中&#xff0c;迁移学习通过迁移卷积网络&#xff08;CNN&#xff09;的预训练权重&#xff0c;实现了在新领域或任务上的高效学习。 下面我将详细介绍迁移学习的概念、实现思想&#xff0c…

【Qt】Qt界面美化指南:深入理解QSS样式表的应用与实践

文章目录 前言&#xff1a;1. 背景介绍2. 基本语法3. QSS 设置方式3.1. 设置全局样式3.2. 从文件加载样式表3.3. 使用 Qt Designer 编辑样式 总结&#xff1a; 前言&#xff1a; 在当今这个视觉至上的时代&#xff0c;用户界面&#xff08;UI&#xff09;的设计对于任何软件产…

嵌入式Linux复制剪切删除指令详解

指令操作 1. cp 复制指令 a. 用法&#xff1a;cp [ 选项 ] [ 源文件或目录 ] [ 目标文件或目录 ]&#xff1b; b. 用途&#xff1a;用于复制文件或目录&#xff1b; c. 通常情况下&#xff0c;复制的都不是空文件夹&#xff0c;所以直接使用 cp 复制空文件会失败&#xff0…

[ROS 系列学习教程] 建模与仿真 - Xacro 语法

ROS 系列学习教程(总目录) 本文目录 一、属性与属性块二、数学表达式三、宏3.1 宏的基本使用3.2 属性块做为宏的入参3.3 任意数量元素做为宏的入参3.4 指定多个块元素的处理顺序3.5 宏嵌套3.6 默认参数3.7 局部属性 四、Rospack 命令五、包含其他 xacro 文件六、条件语句七、YA…