CMake良心教程(1)手把手教你入门!

news2024/11/27 7:33:03

目录

一.CMake是什么?有什么用?

二.环境配置

2.1CMake安装

 2.2MinWG安装

三.构建最小项目

3.1项目的构建

3.2外部构建与内部构建

四.CMakeLists.txt语法介绍

4.1 project关键字

4.2 set 与 PROJECT_NAME

4.3 MESSAGE关键字

4.4 ADD_EXECUTABLE关键字

五.语法的基本原则

六.语法注意事项


一.CMake是什么?有什么用?

如果想要真正的了解一个人,那我们第一眼看到的肯定是人的轮廓。知识也是同理,所以我会先介绍CMake的大体轮廓。

想要了解CMake是干什么的,我们首先要知道一个源文件的编译过程。

  • 1.用编辑器编写源代码,如.c文件。
  • 2.用编译器编译代码生成目标文件,如.o。
  • 3.用链接器连接目标代码生成可执行文件,如.exe。

但如果源文件太多,一个一个编译那得多麻烦啊?于是人们想到,为啥不设计一种类似批处理的程序,来批处理编译源文件呢?

于是就有了make工具,它是一个自动化编译工具,你可以使用一条命令实现完全编译。但是你需要编写一个规则文件,make依据它来批处理编译,这个文件就是makefile,所以编写makefile文件也是一个程序员所必备的技能。

对于一个大工程,编写makefile实在是件复杂的事,于是人们又想,为什么不设计一个工具,读入所有源文件之后,自动生成makefile呢,于是就出现了cmake工具,它能够输出各种各样的makefile或者project文件,从而帮助程序员减轻负担。但是随之而来也就是编写cmakelist文件,它是cmake所依据的规则。

综上我们现在可以把CMake看作是用于产生Makefiles文件的工具。

二.环境配置

我的环境是 Windows10 + CMake + MinGW,MinGW 就是 GCC 的 Windows 移植版本。所以本文就以我的环境来进行讲解。

2.1CMake安装

安装链接:CMake官网安装

根据个人需求选择适当的版本进行下载,其中包含许多不同版本。

【重要提示】请确认你的计算机操作系统类型,以及是32位还是64位。(附注:x86表示32位系统;x64表示64位系统)

下载完成后,双击进行安装。 

下载完成后,单击“Next”按钮,在下图中勾选“I accept the terms in the License
Agreement”复选框接受许可协议:

选中“Add CMake to the system PATH for all users”单选按钮添加系统路径变量。也可以同时勾选“CreateCMakeDesktopIcon”复选框,以便在安装完成后在桌面上创建CMake的快捷方式图标。

点击Install进行安装。

安装完成后,进入Windows系统环境变量设置对话框,如下图所示。可以看到,由于刚才的设置CMake已经自动将其安装路径“D:\Program Files\CMake\bin” 写入环境变量Path中。

 重启电脑后,打开cmd黑窗,输入cmake,能够显示cmake的一些信息即为安装成功,如下图:

 2.2MinWG安装

下载地址:MinWG官网下载

点击上面链接,进入下图1后将页面往下滑到图2区域,点击所需离线包名称:

(Version: 指的是 gcc 的版本,如果没有特殊的需求,一般选择最高的版本号即可。最高版本是8.1.0 ,选中它即可

选默认

Architechture:电脑系统是 64位的,选择 x86_64;如果是 32位 系统,则选择 i686

选x86_64

Threads:如果是 Windows ,选择 win32 ,如果是 Linux、Unix、Mac OS 等其他操作系统要选择 posix

选win32

Exception:seh 是新发明的,而 sjlj 则是古老的。seh 性能比较好,但不支持 32位。 sjlj 稳定性好,支持 32位。

建议64位操作系统选择seh

选seh)

,然后就会弹出图3所示对话框,保存下载即可。离线包大约50MB(解压后500MB左右),下载一般只需半个小时,具体视乎网速情况而定。

 

 下载完成解压后的界面是这样的

 环境变量配置:

设置->搜索高级系统设置->环境变量->path->新建,将MinGW-w64包目录下bin文件夹的全路径粘贴到后面,bin的后面有无斜杠均可,如下图:

 

 

 

 至此环境就安装完毕。

三.构建最小项目

3.1项目的构建

最基本的项目是将一个源代码文件生成可执行文件。对于这么简单的项目,只需要一个三行的 CMakeLists.txt 文件即可,这是本篇教程的起点。在Test目录中创建一个 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.15)

project(test)

add_executable(Test test.c)

  1. cmake_minimum_required(VERSION 3.15): 这一行指定了编译这个项目所需的CMake的最低版本。在这个例子中,这个项目需要3.15或者更高版本的CMake。

  2. project(test): 这一行定义了项目的名字,这里的项目名字是“test”。CMake将会创建一些变量,比如test_SOURCE_DIRtest_BINARY_DIR,以便在项目内部使用。

  3. add_executable(Test test.c): 这一行告诉CMake创建一个叫做“Test”的可执行文件,源文件是test.c。CMake将自动找到正确的编译器(在这种情况下,是C编译器)来编译test.c,然后链接生成名为“Test”的可执行文件。

注意,此示例在 CMakeLists.txt 文件中使用小写命令。CMake 支持大写、小写和混合大小写命令。

test.c文件在 Test 目录中 :

#include<stdio.h>
int main(){
printf("hello dxm");
return 0;
}

现在就可以构建和运行我们的项目了,就是先运行 cmake 命令来构建项目,然后使用你选择的编译工具进行编译。

先从命令行进入到Test目录,并创建一个构建目录 build,接下来,进入 build 目录并运行 CMake 来配置项目,并生成构建系统:

依次解释:

1. cd C:\Users\86137\Desktop\Test 目的是切换到Test目录下

2.mkdir build 创建一个构建目录 build

3.cd build 进入 build 目录

4.cmake -G "MinGW Makefiles" ..  这个命令的意思是在当前目录生成一个用于MinGW的Makefile,它会根据位于上级目录的源代码来设置Makefile的内容。然后你就可以使用MinGW的make命令来编译你的项目了。

5.cmake --build . --build 指定编译生成的文件存放目录,其中就包括可执行文件,. 表示存放到当前目录。

6.Test.exe 可以看到执行出了正确结果

此时目录结构为:

Test/
    build/
    CMakeLists.txt
    test.cpp

3.2外部构建与内部构建

这里创建了一个 build 目录存放编译产物,可以避免编译产物与代码文件混在一起,这种叫做外部构建。

还有一种内部构建,即直接在项目根目录下进行构建系统与编译,这时构建和编译命令就更改为:

cmake -G"MinGW Makefiles" .
cmake --build .

内部构建会使得项目文件很混乱,一般直接用外部构建即可。 到这里我们的第一个CMake项目就完成了。

四.CMakeLists.txt语法介绍

4.1 project关键字

  • 用来设置项目的名字和支持的语言,默认支持所有语言
project(demo)
project(demo CXX) 

第二行代表指定工程名为demo,支持语言是C++ 

最好写上,它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。

4.2 set 与 PROJECT_NAME

这是上文的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.15)

project(test)

add_executable(Test test.c)

指定了项目名后,后面可能会有多个地方用到这个项目名,如果更改了这个名字,就要改多个地方,比较麻烦,那么可以使用 PROJECT_NAME 来表示项目名。

add_executable(${PROJECT_NAME} test.cpp)

生成可执行文件需要指定相关的源文件,如果有多个,那么就用空格隔开,比如:

add_executable(${PROJECT_NAME} a.cpp b.cpp c.cpp)

我们也可以用一个变量来表示这多个源文件:

set(SRC_LIST a.cpp b.cpp c.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})

 set 命令指定 SRC_LIST 变量来表示多个源文件,用 ${var_name} 获取变量的值。

  • 设置变量

1.set 直接设置变量的值

set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})

2. set 追加设置变量的值

set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})

于是原来的 CMakeLists.txt 文件就可以变成如下所示:

cmake_minimum_required(VERSION 3.15)

project(Test)

SET(SRC_LIST test.cpp)

add_executable(${PROJECT_NAME} ${SRC_LIST})

这样看起来就很简洁。

4.3 MESSAGE关键字

message关键字用于向用户显示一些消息。这可能是一些调试信息、警告或者错误信息。基本的使用格式如下:

message([<mode>] "message text" ...)

其中<mode>用于指定消息的类型,可以是以下几种:

  • (none): 等同于 STATUS,这是默认选项,消息会打印到 stderr。
  • STATUS: 普通信息,打印出一些状态消息,例如提示用户某个操作正在进行。该消息会被 CMake GUI 和 ctest -S 脚本捕获。
  • WARNING: 警告信息,但不会停止处理。
  • AUTHOR_WARNING: 类似于 WARNING,但可以通过设置 CMAKE_SUPPRESS_DEVELOPER_WARNINGS 变量来抑制,以避免对最终用户的干扰。
  • SEND_ERROR: 类似于 ERROR,但处理过程会继续进行。它会在 CMake 运行过程中立即显示错误消息,并将错误标记在生成过程中。
  • FATAL_ERROR: 严重错误信息,遇到此类信息将会停止所有的 CMake 运行过程。

以下是几个 message 的示例:

message(STATUS "This is a status message. It is used for providing information.")
message(WARNING "This is a warning message. It can be used to convey important information.")
message(FATAL_ERROR "This is a fatal error. It will stop the processing of CMake.")

这些信息可以在你运行 cmake 命令时在命令行中看到,帮助你了解你的配置文件的状态或者是出现的错误。

4.4 ADD_EXECUTABLE关键字

在CMake中,ADD_EXECUTABLE是一个关键指令,它被用来从指定的源代码文件创建一个可执行文件。

ADD_EXECUTABLE的基本语法如下:

ADD_EXECUTABLE(executable_name source1 source2 ... sourceN)

在这个语法中:

  • executable_name是你希望创建的可执行文件的名称。这个名字不包含任何后缀,例如“.exe”。CMake会根据目标系统自动添加适当的后缀。
  • source1, source2, ..., sourceN是你希望包含在可执行文件中的源代码文件。这些文件可以是C,C++或者其他CMake支持的编程语言的源代码文件。

例如,如果你有一个C++项目,其中包含两个源文件main.cppfunctions.cpp,并且你想将这个项目编译成名为myProgram的可执行文件,那么你可以使用以下的CMake指令:

ADD_EXECUTABLE(myProgram main.cpp functions.cpp)

请注意,ADD_EXECUTABLE只会创建可执行文件的构建规则,但并不会真正执行编译。实际的编译过程会在你运行make或者与你的构建系统相对应的命令时进行。

五.语法的基本原则

  • 变量使用${}方式取值,但是在IF控制语句中是直接使用变量名
  • 指令(参数1 参数2...)参数使用括弧括起,参数之间用空格或分号分开。
  • 指令是大小写无关的,参数和变量是大小写有关的。但推荐全部使用大写。

六.语法注意事项

  • SET(SRC_LIST main.cpp) 可以写成SET(SRC_LIST "main.cpp") ,如果源文件名字中含有空格,就必须要加双引号。
  • ADD_EXECUTABLE(hello main)后缀可以不写,他会自动去找.c和.cpp,最好不要这么写,容易产生误导。 

注:本节先到这里,下一节进入实操,让你的代码看起来更像一个工程。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅谈建筑能耗管理云平台系统的分析与设计

安科瑞 华楠 摘要&#xff1a;本文以建筑能耗为研究对象&#xff0c;分析并设计了基于云服务平台的建筑能耗管控系统。该系统可辅助企业多维度&#xff08;即纵向时间纬度、不同专业指标纬度、不同权限纬度等&#xff09;监测企业建筑能耗情况&#xff0c;并基于其对海量数据、…

马氏杆法检查斜视

使用 检查水平向斜视时&#xff0c;使用水平向马氏杆检查;重直向斜视时&#xff0c;使用重直问马氏杆;检查旋转斜视时&#xff0c;使用双马氏杆. 检查水平向斜视 双眼屈光不正全矫 双眼同时打开&#xff0c;右眼前加水平向马氏杆&#xff0c;左眼前不加 双眼同时观察点光源&…

extern关键字的使用

test.c int add(int a, int b) {return a b; }main.cpp #include <iostream> using namespace std;//方法一&#xff1a; //#include "test.c"//方法二&#xff1a; extern "C" int add(int a, int b); //如果直接在C程序中调用C编译过的函数&…

边写代码边学习之批归一化(BatchNormalization)

1. 为什么要归一化 归一化&#xff08;Normalization&#xff09;是指将不同类型、不同取值范围等不同的数据按照一定的规则统一转化为相同的范围&#xff0c;使得数据在同一数值区间内比较、处理更加合理、有意义。归一化可以消除数据特征之间的量纲差异&#xff0c;使得每个…

热评国内AI四小龙:此一时彼一时,彼此彼此

引言&#xff1a;阿里“清仓”全部持股 商汤科技表示“没啥事” 【科技明说 &#xff5c; 热点关注】 作为国内AI领域的知名科技上市公司&#xff0c;商汤科技SenseTime的一举一动都牵动着业内人士的心。 然而&#xff0c;商汤科技的财报表现没有出奇制胜&#xff0c;却让不…

史上最细,自动化测试-logging日志采集详细实战(一)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 日志概述 1、日志…

Python爬虫在框架下的合规操作与风险控制

大家好&#xff01;作为一名专业的爬虫代理供应商&#xff0c;我今天要和大家分享一些关于Python爬虫在法律框架下的合规操作与风险控制的知识。随着互联网的发展&#xff0c;数据爬取在商业和研究领域扮演着重要的角色&#xff0c;但我们也必须遵守相关法律和规定&#xff0c;…

Android界面设计与用户体验

Android界面设计与用户体验 1. 引言 在如今竞争激烈的移动应用市场&#xff0c;提供优秀的用户体验成为了应用开发的关键要素。无论应用功能多么强大&#xff0c;如果用户界面设计不合理&#xff0c;用户体验不佳&#xff0c;很可能会导致用户流失。因此&#xff0c;在Androi…

QToolButton内存提前释放导致mouseReleaseEvent崩溃问题

QToolButton内存提前释放导致mouseReleaseEvent崩溃问题 1、问题现象及原因分析 1.1、问题现象 如图所示&#xff0c;mouseReleaseEvent接口this指针地址为空&#xff0c;导致了Qt内部发生了Access violation异常。 1.2、问题原因 在项目中&#xff0c;使用该QToolButton…

一文解读!如何选择适合你的零代码、低代码开发平台

首先&#xff0c;我们来探讨一下什么是低/零代码。低代码和零代码的概念最早出现在2014年&#xff0c;由Forrester提出。它们的核心要点包括&#xff1a; 1. 快速交付业务应用&#xff1a;低代码和零代码平台能够实现业务应用的快速交付&#xff0c;这种速度甚至可以是颠覆性的…

JUC并发编程(JUC核心类、TimeUnit类、原子操作类、CASAQS)附带相关面试题

目录 1.JUC并发编程的核心类 2.TimeUnit&#xff08;时间单元&#xff09; 3.原子操作类 4.CAS 、AQS机制 1.JUC并发编程的核心类 虽然java中的多线程有效的提升了程序的效率&#xff0c;但是也引发了一系列可能发生的问题&#xff0c;比如死锁&#xff0c;公平性、资源管理…

局域网共享文件夹怎么加密?共享文件夹加密软件盘点

局域网共享文件夹可以提高企业的沟通效率&#xff0c;使数据交流更加方便&#xff0c;但同时也增大了数据泄露的风险。那么局域网共享文件夹怎么加密呢&#xff1f;下面我们就来了解一下。 局域网共享文件夹加密设置方法 普通的文件夹加密软件仅适用于电脑本地文件夹&#xff…

C++ 运算符重载为非成员函数

运算符也可与重载为非成员函数。这时运算所需要的操作数都需要通过函数的形参表来传递&#xff0c;在形参表中形参从左到右的顺序就是运算符操作数的顺序。如果需要访问运算符参数对象的私有成员&#xff0c;可以将该函数声明为友元函数。 【提示】不用机械地将重载运算符的非…

关于ANCE OS兼容性评估 Linux智能全栈调优KeenTune介绍 | 第 93-94 期

本周「龙蜥大讲堂」预告来啦&#xff01;我们邀请了龙蜥 ANCE 操作系统兼容性评估工具 Maintainer、QA SIG Maintainer 谭伯龙分享《ANCE 操作系统兼容性评估》、龙蜥 KeenTune SIG Maintainer 胡玉溪做《KeenTune 智能全栈调优》主题演讲&#xff0c;精彩多多&#xff0c;快来…

wireshark入门指北

文章目录 前言安装Linux上wireshark安装 使用捕获的时候添加过滤条件抓取浏览器https内容 附录抓取非浏览器的https流量 前言 本文长期维护&#xff0c;记录使用wireshark的使用过程。 虽然有官方文档-Wireshark User’s Guide&#xff0c;但是不想去慢慢读。应用层的图形软件…

opencv基础-33 图像平滑处理-中值滤波cv2.medianBlur()

中值滤波是一种常见的图像处理滤波技术&#xff0c;用于去除图像中的噪声。它的原理是用一个滑动窗口&#xff08;也称为卷积核&#xff09;在图像上移动&#xff0c;对窗口中的像素值进行排序&#xff0c;然后用窗口中像素值的中值来替换中心像素的值。这样&#xff0c;中值滤…

SpringBoot源码分析(8)--内置ApplicationContextInitializer

文章目录 1、DelegatingApplicationContextInitializer2、SharedMetadataReaderFactoryContextInitializer3、ContextIdApplicationContextInitializer4、ConfigurationWarningsApplicationContextInitializer5、ServerPortInfoApplicationContextInitializer6、ConditionEvalu…

[mongo]应用场景及选型

应用场景及选型 MongoDB 数据库定位 OLTP 数据库横向扩展能力&#xff0c;数据量或并发量增加时候架构可以自动扩展灵活模型&#xff0c;适合迭代开发&#xff0c;数据模型多变场景JSON 数据结构&#xff0c;适合微服务/REST API基于功能选择 MongoDB 关系型数据库迁移 从基…

Databend 开源周报第 105 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Databend 轻量级…

【我们一起60天准备考研算法面试(大全)-第三十八天 38/60】【双指针】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…