c++编程基础(二)——Makefile与cmake入门

 

 

 

在上一篇我们讲了c++编译的过程,如果对g++命令了解过你会知道每次我们想要编译一个程序,就需要每次都写一大段命令行来指定我们想要的编译情形(多文件编译,不同的文件编译顺序,库的加载,编译结果的类型等等),类似于这种:

c++编程基础(二)——Makefile与cmake入门

上图是win下cl编译器的命令行(这也是vs帮我们隐藏住的细节,g++也是类似)

那么每次都让我们写这一大段未免太麻烦了,于是可以很快想到——我们把这段写好,并保存进txt文件里每次编译的时候粘贴复制一下不就好了?是的,就是这个思路,于是出现了Makefile

一、makefile

Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在命令行提示符下输入make命令。整个工程完全自动编译,极大提高了效率。

make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。Makefile(在其它的系统上可能是另外的文件名)在绝大多数的IDE 开发环境中都在使用,已经成为一种工程的编译方法。

以上就是makefile的解释,简单的讲通过makefile文件(我们按照它的语法编写)我们就不用每次都去敲编译器命令了。当然makefile的编写现在不是我们学习的重点了(是的你需要重新再学一套语法,而且再学makefile的语法现在看来没多大必要了),我们只需要了解有这么个东西和他能干啥?因为有了cmake的存在,我们就不用自己动手写makefile。下面重点介绍一下cmake。

二、CMake

首先谈谈cmake是怎么被引进的?上节我们讲过通过编写makefile文件然后使用make命令就能避免我们每次都编写那么大一段命令行命令,但是makefile使用起来有几个问题:

  1. 在大型项目中要自己编写makefile文件还是很麻烦
  2. makefile文件依赖于平台,简单描述下:win平台下使用微软自己的nmake工具以及cl编译器,假使我们在win下写好了makefile,想要将之移植到linux下(使用make与g++)又得重新再写一个makefile
  3. 与2类似,现在不同的平台上有不同的IDE他们都使用自己的项目构建方案各自不兼容,每次重新编译我们肯定不会希望还得自己重新写makefile

cmake的出现基本解决了上面的问题,于是现在大部分的第三方库都是构建在cmake上的。

cmake的特点:

  1. 跨平台,并可生成 native 编译配置文件,在 Linux/Unix 平台,生成 makefile,在 苹果平台,可以生成 xcode,在 Windows 平台,可以生成 MSVC 的工程文件。
  2. 简化编译构建过程和编译过程。Cmake 的工具链非常简单:cmake+make。
  3. 可扩展,可以为 cmake 编写特定功能的模块,扩充 cmake 功能。

 

2.1cmake的安装

几乎所有主流的Linux发行版的源中都包含有cmake的安装包,直接从源中添加即可。当然,也可以在官方网站下载源代码自行编译安装。对于Windows和Mac用户,cmake的官方网站上有相应的安装包,下载安装即可。

需要注意的有:

  1. cmake的版本号需要注意一下,因为有的库cmake版本过低不支持。
  2. 建议如果能使用cmake-gui就最好使用,现在各平台上都有,因为图形化操作可以帮我们节省很多时间(cmake 命令也有很多,敲键盘哪有点鼠标来的轻松哈哈~)。
  3. 当然最好还是使用cmake命令行编译一个工程体会一下具体的过程。

2.2编写CMakeLists.txt

啥是CMakeLists.txt?CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。

简单点讲,我们按照cmake语法规则,在CMakeLists.txt里写好我们的项目的编译规则,然后编译即可。

下面简单讲下几个常用的cmake语句,学了这些基本上就能应付大多数情况了:

project (HELLO)   #指定项目名称,生成的VC项目的名称;

>>使用${HELLO_SOURCE_DIR}表示项目根目录

include_directories:指定头文件的搜索路径,相当于指定gcc的-I参数

>> include_directories (${HELLO_SOURCE_DIR}/Hello)  #增加Hello为include目录

link_directories:动态链接库或静态链接库的搜索路径,相当于gcc的-L参数

>> link_directories (${HELLO_BINARY_DIR}/Hello)     #增加Hello为link目录

add_subdirectory:包含子目录

>> add_subdirectory (Hello)

add_executable:编译可执行程序,指定编译,好像也可以添加.o文件

>> add_executable (helloDemo demo.cxx demo_b.cxx)   #将cxx编译成可执行文件——

add_definitions:添加编译参数

>> add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义;

>> add_definitions( “-Wall -ansi –pedantic –g”)

target_link_libraries:添加链接库,相同于指定-l参数

>> target_link_libraries(demo Hello) #将可执行文件与Hello连接成最终文件demo

add_library:

>> add_library(Hello hello.cxx)  #将hello.cxx编译成静态库如libHello.a

2.3cmake的使用

cmake的使用还是很简单的:在我们写好CMakeLists.txt后在有CMakeLists.txt 目录下:

cmake               //生成makefile
            make                //编译

当然要是使用vs编写项目的话我们讲的这么多东西都被隐藏住了,虽然底层都是一样的,vs提供了更为简单的方式来帮我们构建项目(微软就是对程序员最友善的公司,不接受反驳)。

所以在win平台下我们使用cmake的情况大部分是在需要编译第三方库的时候:

c++编程基础(二)——Makefile与cmake入门

之后cmake就帮我们生成了一个vs工程,我们只需要在vs里编译就好啦。