CMake学习

简介

cmake 是一个跨平台的自动构建工具, 前面导语部分也已经给大家介绍了, cmake 的诞生主要是为了解
决直接使用 make+Makefile 这种方式无法实现跨平台的问题,所以 cmake 是可以实现跨平台的编译工具,这是它最大的特点。

cmake和Makefile区别

这是我刚开始模糊的原因,就是cmake和Makefile这两者间有什么区别,为什么要用cmake,他有什么优点么?为什么github上很多项目都用camke?他到底是作什么用的。现在我们来看一个图,这是我从正点原子的手册上看到的
在这里插入图片描述
从上图我们就可以大概了解到,cmake和makefile他俩就不是一个东西,cmake是根据指定的规则(CMakeLists.txt )去生成Makefile的,有的大佬们工程直接手写Makefile而有一些大佬们觉得费劲用cmake生成Makefile反而更方便,所以使用cmake来动态生成Makefile。

cmake安装

首先cmake是个工具命令,需要安装的,一下我分为两种情况,有离线的和在线安装两种。
在线的么,顾名思义就是在线安装,用ubuntu自身的命令即可。
离线的么就是现在离线安装包自行安装。
那有的同学可能就要问了,直接在线不进行,离线这么费劲。有的公司他就不能上外网!(比如我们公司)那你咋办,只能离线啊,再麻烦也得离线啊!(哭死)

在线安装

在Ubuntu系统下,一个命令解决所有:

sudo apt-get install cmake

离线安装

首先进入官网下载界面https://cmake.org/download/
在这里插入图片描述
选择版本进行下载,这里我们下载的是cmake-3.22.3.tar.gz

解压后安装

tar -zxvf cmake-3.22.3.tar.gz
cd cmake-3.22.3
./bootstrap && make && sudo install

cmake使用

生成单个文件

编写CMakeLists.txt内容为:

project(HELLO)
add_executable(hello ./main.c)

执行命令:

cmake ./

执行完 cmake 之后,除了源文件 main.c 和 CMakeLists.txt 之外,可以看到当前目录下生成了很多其它
的文件或文件夹,包括: CMakeCache.txt、 CmakeFiles、 cmake_install.cmake、 Makefile,重点是生成了这个Makefile 文件, 有了 Makefile 之后,接着我们使用 make 工具编译我们的工程。

  • project(HELLO)
    project 是一个命令, 命令的使用方式有点类似于 C 语言中的函数,因为命令后面需要提供一对括号,
    并且通常需要我们提供参数,多个参数使用空格分隔而不是逗号“,” 。
    project 命令用于设置工程的名称, 括号中的参数 HELLO 便是我们要设置的工程名称;设置工程名称并
    不是强制性的,但是最好加上。
  • 第二行 add_executable(hello ./main.c)
    add_executable 同样也是一个命令,用于生成一个可执行文件, 在本例中传入了两个参数,第一个参数
    表示生成的可执行文件对应的文件名,第二个参数表示对应的源文件; 所以 add_executable(hello ./main.c)表
    示需要生成一个名为 hello 的可执行文件,所需源文件为当前目录下的 main.c。
使用 out-of-source 方式构建

在上面的例子中, cmake 生成的文件以及最终的可执行文件 hello 与工程的源码文件 main.c 混在了一
起,这使得工程看起来非常乱,当我们需要清理 cmake 产生的文件时将变得非常麻烦,这不是我们想看到的;我们需要将构建过程生成的文件与源文件分离开来, 不让它们混杂在一起,也就是使用 out-of-source 方式构建。
将 cmake 编译生成的文件清理下,然后在工程目录下创建一个 build 目录,然后进入到 build 目录下执行 cmake:

mkdir build
cd build
cmake ../
make

这样 cmake 生成的中间文件以及 make 编译生成的可执行文件就全部在 build 目录下了,如果要清理工
程,直接删除 build 目录即可,这样就方便多了。

多个源文件

一个源文件的例子似乎没什么意思,我们再加入一个 hello.h 头文件和 hello.c 源文件。在 hello.c 文件中
定义了一个函数 hello,然后在 main.c 源文件中将会调用该函数.


CMakeLists.txt:

project(HELLO)
set(SRC_LIST main.c hello.c)
add_executable(hello ${SRC_LIST})

同样,进入到 build 目录下,执行 cmake、再执行 make 编译工程,最终就会得到可执行文件 hello。
在本例子中, CMakeLists.txt 文件中使用到了 set 命令, set 命令用于设置变量,如果变量不存在则创建该变量并设置它;在本例中,我们定义了一个 SRC_LIST 变量, SRC_LIST 变量是一个源文件列表, 记录生成可执行文件 hello 所需的源文件 main.c 和 hello.c,而在 add_executable 命令引用了该变量; 当然我们也可以不去定义 SRC_LIST 变量,直接将源文件列表写在 add_executable 命令中。

生成库文件

在本例中,除了生成可执行文件 hello 之外,我们还需要将 hello.c 编译为静态库文件或者动态库文件,
在示例二的基础上对 CMakeLists.txt 文件进行修改

project(HELLO)
add_library(libhello hello.c)
add_executable(hello main.c)
target_link_libraries(hello libhello)

进入到 build 目录下,执行 cmake、再执行 make 编译工程,编译完成之后,在 build 目录下就会生成可
执行文件 hello 和库文件

CMakeLists.txt 文件解释

add_library

add_library 命令用于生成库文件,在本例中我们传入了两个参数.
第一个参数表示库文件的名字,需要注意的是,这个名字是不包含前缀和后缀的名字; 在 Linux 系统中,库文件的前缀是 lib,动态库文件的后缀是.so,而静态库文件的后缀是.a; 所以,意味着最终生成的库文件对应的名字会自动添加上前缀和后缀。

第二个参数表示库文件对应的源文件。本例中, add_library 命令生成了一个静态库文件 liblibhello.a,如果要生成动态库文件

add_library(libhello SHARED hello.c) #生成动态库文件
add_library(libhello STATIC hello.c) #生成静态库文件
arget_link_libraries

arget_link_libraries 命令为目标指定依赖库,在本例中, hello.c 被编译为库文件, 并将其链接进 hello 程

修改生成的库文件名字

本例中有一点非常不爽,生成的库为 liblibhello.a,名字非常不好看;如果想生成 libhello.a 该怎么办?直接修改 add_library 命令的参数,像下面这样可以吗?

add_library(hello hello.c)

答案是不行的,因为 hello 这个目标已经存在了(add_executable(hello main.c)),目标名对于整个工程来说是唯一的,不可出现相同名字的目标,所以这种方法肯定是不行的,实际上我们只需要在 CMakeLists.txt文件中添加下面这条命令即可:

set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

将源文件组织到不同的目录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值