cmake学习总结

cmake 简介

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

1.开放源代码。我们可以直接从 cmake 官网 https://cmake.org/下载到它的源代码。
2.跨平台。cmake 并不直接编译、构建出最终的可执行文件或库文件,它允许开发者编写一种与平台无关的 CMakeLists.txt 文件来制定整个工程的编译流程,cmake 工具会解析 CMakeLists.txt 文件语法规则,再根据当前的编译平台,生成本地化的 Makefile 和工程件,最后通过 make 工具来编译整个工程;所以由此可知,cmake 仅仅只是根据不同平台生成对应的 Makefile,最终还是通过 make工具来编译工程源码,但是 cmake 却是跨平台的。
3.语法规则简单。Makefile 语法规则比较复杂,对于一个初学者来说,通常并不那么友好,并且Makefile 语法规则在不同平台下往往是不一样的;而 cmake 依赖的是 CMakeLists.txt 文件,该文件的语法规则与平台无关,并且语法规则简单、容易理解!cmake 工具通过解析 CMakeLists.txt 自动帮我们生成 Makefile,这样就不需要我们自己手动编写 Makefile 了。

cmake和Makefile

直观上理解,cmake 就是用来产生 Makefile 的工具,解析CMakeLists.txt 自动生成 Makefile:
cmake与makefile
除了 cmake 之外,还有一些其它的自动构建工具,常用的譬如 automake、autoconf 等,有兴趣的朋友可以自己了解下。

从“Hello, world!”开始

了解cmake的基本原理并在系统中安好cmake后,我们就可以用cmake来演示那个最经典的”Hello, world!”了。

第一步,我们给这个项目起个名字——就叫HELLO吧。因此,第一部为项目代码建立目录hello,与此项目有关的所有代码和文档都位于此目录下。

第二步,在hello目录下建立一个main.c文件,其代码如下:

#include<stdio.h>
int main(void)
{
    printf("Hello,World\n");
    return 0;
}

第三步,在hello目录下建立一个新的文件CMakeLists.txt,它就是 cmake所处理的“代码“。在CMakeLists.txt文件中输入下面的代码(#后面的内容为代码行注释):

#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(HELLO) #项目名称
#把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
AUX_SOURCE_DIRECTORY(. SRC_LIST)
#生成应用程序 hello
ADD_EXECUTABLE(hello ${SRC_LIST})

至此,整个hello项目就已经构建完毕,可以进行编译了。

第四步,编译项目。

为了使用外部编译方式编译项目,需要先在目录hello下新建一个目录build(也可以是其他任何目录名)。现在,项目整体的目录结构为:

hello/
|– CMakeLists.txt
|– build /
|– main.c

处理多源文件目录的方法

CMake处理源代码分布在不同目录中的情况也十分简单。现假设我们的源代码分布情况如下:
在这里插入图片描述其中 src 目录下的文件要编译成一个链接库。
第一步,项目主目录中的 CMakeLists.txt在目录
step2 中创建文件 CMakeLists.txt 。文件内容如下:清单 3 目录 step2 中的 CMakeLists.txt

PROJECT(main)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 
ADD_SUBDIRECTORY( src )
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(main ${DIR_SRCS}  )
TARGET_LINK_LIBRARIES( main Test )

相对于清单 2,该文件添加了下面的内容: 第三行,使用命令 ADD_SUBDIRECTORY 指明本项目包含一个子目录 src 。第六行,使用命令 TARGET_LINK_LIBRARIES 指明可执行文件 main 需要连接一个名为Test的链接库 。

第二步,子目录中的 CmakeLists.txt
在子目录 src 中创建 CmakeLists.txt。文件内容如下:

1 AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
2 ADD_LIBRARY ( Test ${DIR_TEST1_SRCS})

在该文件中使用命令 ADD_LIBRARY 将 src 目录中的源文件编译为共享库。
第三步,执行 cmake,在执行 cmake 的过程中,首先解析目录 step2 中的 CMakeLists.txt ,当程序执行命令 ADD_SUBDIRECTORY( src ) 时进入目录 src 对其中的 CMakeLists.txt 进行解析。

静态链接库和动态链接库

也就是说,程序完成链接操作的方式有两种,一种是在生成可执行文件之前完成所有链接操作,使用的库文件称为静态链接库;另一种是将部分链接操作推迟到程序执行时才进行,此过程使用的库文件称为动态链接库。

  1. 静态链接库
    静态链接库用来和所有的目标文件一起组织成可执行文件,生成的可执行文件可以独立运行。

采用静态链接库完成链接操作,存在诸多缺点。首先,可执行文件内部拷贝了所有目标文件和静态链接库的指令和数据,文件本身的体积会很大。当系统中存在多个链接同一个静态库的可执行文件时,每个可执行文件中都存有一份静态库的指令和数据,就会造成内存空间的极大浪费。

此外,一旦程序中有模块更新,整个程序就必须重新链接后才能运行。假设一个程序有 20 个模块构成,每个模块的大小为 1 MB,那么每次更新任何一个模块,用户就必须重新获取 20 MB 的程序,对用户很不友好。
2) 动态链接库
实际上,动态链接库是 Windows 平台上对动态链接过程所用库文件的称谓,Linux 平台上习惯称为共享库或者共享对象文件,它们表达的是一个意思。

所谓动态链接,指的是将链接的时机推迟到程序运行时再进行。具体来讲,对于一个以动态链接方式运行的项目,首先由静态链接器将所有的目标文件组织成一个可执行文件,运行时将所需的动态链接库全部载入内存,由动态链接器完成可执行文件和动态库文件的链接工作。

动态链接库可以随可执行文件一同载入内存,也可以在可执行文件运行过程中载入,即可执行文件什么时候需要,动态链接库才会载入内存。

和静态链接库相比,动态链接库可以很好地解决空间浪费和更新困难的问题。动态链接库和可执行文件是分别载入内存的,因此动态链接库的体积通常会小一些。当有多个程序使用同一个动态链接库时,所有程序可以共享一份动态链接库的指令和数据,避免了空间的浪费。采用动态链接的方式也可以方便程序的更新和升级,当程序的某个模块更新后,只需要将旧的模块替换掉,程序运行时会自动将所有模板载入内存并动态地链接在一起。

有读者可能会问,采用动态链接的方式,每次程序运行时都需要重新链接,会不会很慢?的确,动态链接确实会损失一部分程序性能,但实践证明,动态链接库和静态链接相比,性能损失大约在 5% 以下,由此换取程序在空间上的节省以及更新时的便利,是相当值得的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值