前言
在 Windows上开发我使用最多的IDE还是 Visual Studio,编写、编译一条龙服务,导致了不少编译流程知识的缺失,这种大型的IDE确实好用,诸多配置通过在界面上勾选一下就可以了,但是在编译细节的掌握上还是漏掉了一些知识。
在 linux 开发环境下通常会使用 gcc 或者 g++ 进行编译,可是编译选项有点多,当工程非常大的时候需要写的编译参数太多了,这时可以使用make命令来帮助我们编译 C++ 程序,编译时依赖一些规则,这些规则就写在一个叫 Makefile 的文件中。
后来发现写 Makefile 还是太麻烦了,这个文件也相当大。于是“懒惰”的程序员们又开发出了各种各样的工具用来生成 Makefile 文件,我使用过的目前就只有 automake
和 cmake
。
生成Makefile
之前使用的生成 Makefile 文件的工具是 automake
,被称为是“八股文”一样的操作,每次操作都是固定的几个步骤,比如每次都要运行 autoscan
、aclocal
、autoconf
、automake
、./confiugre
等命令,需要个人发挥的地方并不多,之前使用的时候也不是完全从0开始一点点写的,往往是写一个项目模板之后,对照着在Makefile.am文件中修改几个参数就好了。
现在新的工作内容中使用 cmake 来生成 Makefile,这个 cmake 之前还确实接触过一些,大概是2012年的时候,那时在编译 OpenCV 库还有增强现实插件的时候用过几次,当时感觉安装起来太麻烦了,对那个红绿蓝的图标记忆犹新,感觉和当时的新闻联播的图标有些亲戚关系。
其实当时根本分不清什么是编译器,什么是 Makefile,对于各种库文件的编译完全是按照文档来操作,现在回过头来看看 cmake 生成 Makefile 还是比较简单的,最起码要比 automake 省了很多步骤,只要编写一个 CMakeLists.txt 文件就好了。
编写CMakeLists.txt生成Makefile
为了练习使用编写CMakeLists.txt生成Makefile,进而编译C++项目,我们可以从头来实现一个小例子,目标是编写一个计算加法的静态库和一个计算减法静态库,然后实现一个测试工程来使用这两个函数库,整个工程使用 cmake 来生成 Makefile,然后使用 make 命令完成编译。
实现简单的代码文件
加法和减法都是常用的简单计算,用来举例子很容易理解,接下来展示要用到的几个文件内容,每个文件只有几行,只为了说明问题,文件内容如下:
1 | //myadd.h |
1 | //myadd.cpp |
1 | //mysub.h |
1 | //mysub.cpp |
1 | //test.cpp |
使用常规方法编译
首先使用最简单 g++ 命令来编译这个样例程序:
- 查看目录下文件
1 | albert@home-pc:testcmake$ ls |
- 将
myadd.h
和myadd.cpp
编译成静态库libmyadd.a
1 | albert@home-pc:testcmake$ g++ -c myadd.cpp |
- 将
mysub.h
和mysub.cpp
编译成静态库libmysub.so
1 | albert@home-pc:testcmake$ g++ -c mysub.cpp |
- 编译链接静态库
libmyadd.a
、动态库libmysub.so
和测试文件生成可执行程序test
1 | albert@home-pc:testcmake$ g++ test.cpp libmyadd.a -L. -lmysub -o test -Wl,-rpath=. |
- 运行查看结果,成功计算表达式的值
1 | albert@home-pc:testcmake$ ./test |
使用cmake方式
上面展示了最原始的编译方法,每次都要敲这些命令,接下来编写一个 CMakeLists 文件,使用 cmake 生成Makefile,以后只要运行 make 命令就可以完成编译了。
调整一下目录结构如下:
1 | albert@home-pc:testcmake$ tree |
- 进入 myadd 目录新建 CMakeLists.txt 编写内容如下:
1 | aux_source_directory(. SRC_LIST) #将此目录的源文件集合设置为变量SRC_LIST |
- 进入 mysub 目录新建 CMakeLists.txt 编写内容如下:
1 | aux_source_directory(. SRC_LIST) #将此目录的源文件集合设置为变量SRC_LIST |
- 在工程主目录下新建 CMakeLists.txt 编写内容如下:
1 | # 指定cmake版本 |
- 新建build目录和lib目录,整个工程目录关系如下:
1 | albert@home-pc:testcmake$ tree |
- 进入 build 目录下依次运行
cmake ..
和make
命令
1 | albert@home-pc:testcmake/build$ cmake .. |
至此,使用cmake方式编译工程的例子就写完了。
总结
cmake
和automake
本身不提供编译功能,只是可以按照编写的 CMakeLists.txt 文件生成 Makefilemake
可以根据 Makefile 文件调用 gcc/g++ 命令对源代码进行编译工作-Wl,-rpath=.
这个选项可以指定可执行文件查找动态库的路径,感觉比export LD_LIBRARY_PATH
要方便一点-DGLIBCXX_USE_CXX11_ABI
这个宏可坑了我不少时间,编译使用libmysqlcppconn8的时候,如果不禁用会报编译错误
有你,真好~
2020-11-15 23:55:35