CMake学习篇[1]---CMake入门demo+从0开始+含项目文件

前言

CMake这个东西在几年前刚开始工作的时候接触了一下,当时没有什么教程,看的真是折磨,时间久了不用,又忘记了。

最近同事在CMake上遇到了一些问题,然后说一定要搞懂它,这么多年了一直没好好弄懂之类的。这不禁提醒了我,去年年中买了本《CMake构建实战》,看了三分之一,但是由于一直没用到,搁置了,然后加上软考备考之类的,久而久之,吃灰咯。

这篇博客属于CMake学习专栏的开篇,这个学习篇主要还是把一些常用的命令,以及完整的一个CMake构建流程打通,是自己重新学习CMake的一个记录。

1.CMake简介

CMake最有名的地方在于它的跨平台特性,一次编写,多平台适用。
我们在linux下写makefile依赖的事GNU make,Qt中依赖qmake,VS中依赖nmake,不同的平台写makefile的语法格式都稍有不同,且工作量比较大,对于依赖关系等处理也容易出错。

而使用CMake就有点像设计模式中的适配器模式,你只需要编写CMakeLists,执行cmake命令,就可以在对应平台生成本地化的Makefile和工程文件,用户只需要make编译即可。

所以CMake本身不可以编译,它是自动生成本地化的Makefile文件,让本地的Makefile去进行编译。

2.CMakeLists和项目结构

这是本次的CMakeLists

#CMake最小要求的版本
cmake_minimum_required(VERSION 3.11.0)

#工程名称
project(Demo1)

#生成可执行文件 依赖于文件demo1.cpp
add_executable(demo1exe demo1.cpp)

项目结构
CMakeLists.txt和demo1.cpp源码在同级目录下

+根目录
    -CMakeLists.txt
    -demo1.cpp

在这里插入图片描述

2.命令

2.1 cmake_minimum_required

含义:当前项目所需要的CMake的最小版本。

cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])

我们在CMakeLists中指定构建的最低CMake版本为3.11.0,如果低于这个版本就会报错。

下面是具体解释:

必选参数:
VERSION <min>:这是最核心的部分,<min> 表示项目所需的最低 CMake 版本。
如果用户使用的 CMake 版本低于此要求,CMake 会直接报错并终止配置过程。
作用:确保项目使用的 CMake 特性在当前环境中可用,避免因版本过低导致的语法或功能不兼容

可选参数:
[...<policy_max>]:可选部分,用于指定「策略版本范围」(例如 VERSION 3.10…3.20)。
<policy_max> 表示最高兼容的策略版本。CMake 会自动将所有策略(CMAKE_POLICY)设置为 <policy_max> 版本的行为,同时允许使用 到 <policy_max> 之间的特性。
作用:在保证兼容性的同时,启用较高版本的策略行为,避免因策略默认行为变化导致的意外问题。如果省略,则默认使用 版本的策略。

[FATAL_ERROR]:可选关键字,在 CMake 3.12 之前的版本中用于指定:当 CMake 版本低于 <min> 时,以「致命错误」终止(而非警告)。
作用:在旧版本 CMake 中强制要求版本检查的严格性。现代 CMake(3.12+)中,即使不写此关键字,版本不满足时也会默认报错,因此该选项逐渐被废弃。

这里我们用的时候其实只需要用第一个即可,后面俩基本不咋用。


2.2 project

project(<PROJECT-NAME> 
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [DESCRIPTION <project-description-string>]
        [HOMEPAGE_URL <url-string>]
        [LANGUAGES <language-name>...]
)

在本次的入门demo中我们只需要指定第一个参数,项目的名称即可。
在我们编写的CMakeLists中,我们指定第一个参数为Demo1,所以在Windows中构建后,生成的工程名称为Demo1>
在这里插入图片描述

下面是参数的详细解释

必选参数:
<PROJECT-NAME>
项目的名称(如 MyApp、MathLibrary),会被赋值给变量 PROJECT_NAME。
同时会隐式定义以项目名为前缀的变量,例如:
<PROJECT-NAME>_BINARY_DIR:项目构建目录(编译产物存放路径)。
<PROJECT-NAME>_SOURCE_DIR:项目源文件目录(CMakeLists.txt 所在路径)。
示例:project(MyProject) 会将 PROJECT_NAME 设为 MyProject。

可选参数:

VERSION
指定项目版本号,格式为 主版本.次版本.修订号.微调号(如 1.2.3 或 2.0.0.1)。
会自动定义以下变量,方便在代码中引用版本信息:
PROJECT_VERSION:完整版本号(如 1.2.3)。
PROJECT_VERSION_MAJOR:主版本号(如 1)。
PROJECT_VERSION_MINOR:次版本号(如 2)。
PROJECT_VERSION_PATCH:修订号(如 3)。
PROJECT_VERSION_TWEAK:微调号(若指定,否则为 0)。
示例:project(MyProject VERSION 2.1.0)。

DESCRIPTION
项目的简短描述字符串(如 “A cross-platform utility library”)。
对应变量:PROJECT_DESCRIPTION。

示例:project(MyProject DESCRIPTION “A simple C++ application”)。

HOMEPAGE_URL
项目的主页 URL(如 “https://github.com/username/myproject”)。
对应变量:PROJECT_HOMEPAGE_URL。

示例:project(MyProject HOMEPAGE_URL “https://example.com/myproject”)。

LANGUAGES
指定项目支持的编程语言,默认值为 C 和 CXX(C 和 C++)。
常见可选值:C、CXX(C++)、Fortran、Python、CSharp 等。
若不需要默认语言,可显式指定(例如纯 C++ 项目可写 LANGUAGES CXX)。
若项目不涉及编译(仅组织脚本),可指定 LANGUAGES NONE。

示例:project(MyProject LANGUAGES CXX Fortran)(支持 C++ 和 Fortran)。


其他特性与注意事项:
变量作用域:project() 命令会设置全局变量(如 PROJECT_NAME、CMAKE_PROJECT_NAME 等),但在子目录中使用 project() 会创建新的作用域,此时 PROJECT_NAME 会变为子项目名称,而 CMAKE_PROJECT_NAME 始终保持顶层项目名称。

版本兼容性:
DESCRIPTION 和 HOMEPAGE_URL 是 CMake 3.9 及以上版本新增的参数。
若需兼容旧版本 CMake,可省略这些参数,或通过 set() 手动定义相关变量。
多项目管理:一个顶层 CMakeLists.txt 中可通过多个 project() 命令定义子项目,适合大型工程的模块化管理。

2.3 add_executable

add_executable(<target-name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])

在编写的CMakeLists中,
第一个参数指定生成的可执行文件为demo1exe,后面依赖的源文件是demo1.cpp,也就是根据demo1.cpp进行编译输出生成一个demo1exe可执行文件。
当然了,在windows中的VS2017中,其实是生成demo1exe这样一个项目,我们编译这个项目运行,就会生成对应的可执行文件。
在这里插入图片描述

必选参数:

<target-name>
指定生成的可执行文件名称(如 myapp、server)。
这是目标的唯一标识,后续可通过该名称引用此目标(如在 target_link_libraries() 中关联库)。
生成的可执行文件会自动添加系统默认扩展名(如 Windows 下为 .exe,Linux 下无扩展名)。

源文件列表 [source1] [source2 ...]
指定构建该可执行文件所需的源代码文件(如 .c、.cpp、.cxx 等)。
支持相对路径(相对于当前 CMakeLists.txt 所在目录)或绝对路径。
示例:
cmake
add_executable(myapp main.cpp utils.cpp) # 从两个源文件构建 myapp

可选参数:

WIN32:仅用于 Windows 平台,指定生成「Windows 应用程序」(而非控制台程序)。此时入口函数为 WinMain 而非 main,且运行时不会弹出控制台窗口。示例:add_executable(myapp WIN32 main.cpp)
MACOSX_BUNDLE:仅用于 macOS 平台,指定生成「应用程序束(.app)」,而非普通可执行文件。适用于 GUI 应用。示例:add_executable(myapp MACOSX_BUNDLE main.cpp)

EXCLUDE_FROM_ALL:指定该目标不会被默认构建(即执行 make 或 cmake --build 时不会自动编译),需显式指定目标名称(如 make myapp)才会构建。适用于可选工具或示例程序。示例:add_executable(example EXCLUDE_FROM_ALL example.cpp)

2.4 #与#[[ ]]

在 CMake 中,# 和 #[[ … ]] 都是用于添加注释的语法,但它们的使用场景和特性有所不同:

单行注释:#

用法:在 # 后面的内容会被视为注释,直到当前行结束。
特点:仅作用于单行,是最常用的注释方式。
示例:

# 这是一行单行注释
add_executable(myapp main.cpp)  # 这也是注释(行内注释)

多行注释:#[[ ... ]]
用法:#[[ 表示注释开始,]] 表示注释结束,中间的内容(包括换行)都会被视为注释。
特点:
支持跨多行注释,适合注释大段文本或临时注释多行代码。
可以嵌套使用(CMake 3.0 及以上支持),形式为 #[[[ … ]]](外层)和 #[[ … ]](内层)。

示例:

#[[
  这是一段
  多行注释
]]
add_executable(myapp main.cpp)

# 嵌套示例(CMake 3.0+)
#[[[
  外层注释
  #[[ 内层注释 ]]
  外层继续
]]]

注意事项
# 是最基础的注释方式,兼容性最好(所有 CMake 版本支持)。
#[[ … ]] 是 CMake 2.8.12 及以上版本引入的语法,低版本不支持。
多行注释中可以包含 # 符号,不会被解析为单行注释的开始。
实际项目中,单行注释 # 更常用,多行注释多用于临时注释大块代码或编写长文档。

3.构建与运行

3.1 命令行构建

在Demo1中右键打开控制台,进入到源码和CMakeLists目录下
输入cmake -S ./ -B ./build
即可以当前目录为源码目录,生成到当前目录下的build文件夹下(如果没有build文件夹,会自动创建)

在这里插入图片描述

build目录下生成的解决方案等工程文件如下:
在这里插入图片描述

当然为什么这么用,其实输入一下cmake --help即可查看。
在这里插入图片描述

3.2 GUI构建

命令行的方式其实在window上用的不多,我们一般直接开CMake的GUI来配置

在这里插入图片描述
如果build的目录不存在,会弹框提示是否需要创建,Yes即可
在这里插入图片描述
在这里插入图片描述

Use default native compilers
选择这个选项,CMake 会使用系统中默认安装的原生编译器来构建项目。比如在 Windows 下安装了 Visual Studio ,它就会使用 Visual Studio 自带的编译器 ,这样可以减少手动配置编译器路径等繁琐操作,适合大多数常规的开发场景。
Specify native compilers
当你选择这个选项时,意味着你要手动指定原生编译器的位置和相关参数。在一些特殊情况下,比如系统中安装了多个版本的编译器,或者你想使用自定义配置的编译器时,就需要通过这个选项来明确告知 CMake 使用哪个具体的编译器进行项目构建。
Specify toolchain file for cross-compiling
此选项用于指定交叉编译的工具链文件。交叉编译是在一种平台上编译出能在另一种平台上运行的程序,比如在 x86 的 Windows 系统上编译出能在 ARM 架构的 Linux 系统上运行的程序。通过指定工具链文件,CMake 可以获取到目标平台相关的编译、链接等信息,从而生成正确的交叉编译配置。
Specify options for cross-compiling
选择该选项后,你可以手动指定交叉编译的其他相关选项。除了工具链文件包含的信息外,可能还需要设置一些额外的参数,比如目标平台的系统根目录、头文件路径、库文件路径等,以确保交叉编译过程能够顺利进行,生成符合目标平台要求的可执行文件或库。


在这里插入图片描述
CMAKE_CONFIGURATION_TYPES
来源:
对于支持多配置生成器(如 Visual Studio 系列生成器)的情况,CMAKE_CONFIGURATION_TYPES 是 CMake 内置的变量,用于指定项目支持的构建配置类型。
它的值通常是在 CMake 本身的模块或者项目的 CMake 脚本中进行设置的,也可以通过用户在 CMake 配置过程中进行自定义修改。
含义:
该变量定义了项目可以生成的构建配置类型。例如图中的 Debug;Release;MinSizeRel;RelWithDebInfo,分别代表:
Debug:调试模式,包含调试信息,未进行优化,方便开发者调试程序。
Release:发布模式,进行了各种优化,不包含调试信息,适合最终发布的程序。
MinSizeRel:最小尺寸发布模式,在优化时主要考虑减小生成的可执行文件或库的大小。
RelWithDebInfo:带调试信息的发布模式,既进行了优化,又包含了调试信息,便于在发布后仍能进行一定的调试工作。

对应生成的项目中这里的类型
在这里插入图片描述

CMAKE_INSTALL_PREFIX
来源:
这是 CMake 内置的变量,用于指定项目安装时的默认前缀路径。
它的默认值通常由 CMake 根据系统和生成器等因素确定,也可以在 CMake 配置过程中(比如通过 CMake GUI 或者命令行参数 -DCMAKE_INSTALL_PREFIX=…)由用户进行自定义设置。
含义:
该变量指定了使用 make install(在基于 Makefile 的生成器中)或者在 Visual Studio 中执行安装目标时,项目的可执行文件、库文件、头文件等将被安装到的根目录。图中指定为 C:/Program Files (x86)/Demo1,意味着执行安装操作后,相关文件会被安装到这个路径下。

完成后点击Generate,就可以在你指定的build目录看到生成的工程文件


写到这里你可能会疑惑,为什么我的GUI还要选择什么构建工具之类的,但是在我们的控制终端中却没有指定。其实这里也指定了,只不过用到的都是默认值。
我们在控制台输入cmake --help后,往下拉,这里有一个Generators分组,里面说明了我们默认构建项目的工具集或集成开发环境(IDE)

在这里插入图片描述

3.3 运行

打开生成的Demo1.sln,切换一下启动项目,接着编译运行即可。
在这里插入图片描述

在这里插入图片描述


总结

这是最简单的一个CMakeLists入门demo,本文从0开始阐述怎么搭建一个CMake构建的简单项目,包括命令行以及GUI的方式进行配置,自己看了教程千千万,觉得也就几句话就可以构建了,真的写起来发现门道还是不少的。

demo的文件我放在gitee了,需要自取https://gitee.com/Edwinwzy1/cmake-learn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

澄澈i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值