C++进阶 Cmake
一.makefile和Cmake对比
makefile的执行过程写一个脚本文件
CMake可以生成makefile文件的
底层的学习makefile接触的比较多
二.CMake
1.1 Cmake工程流程
1> 在不使用CMake时,编译工程如下
2> 在上面的机制中,工程文件中添加一个源程序 bar.cpp
3> 使用CMake来管理工程的状态
4> 使用CMkake管理工程中添加一个新文件 bar.cpp
1.2 语法特性介绍
1> 基本语法:指令(参数1 参数2 ...)
参数使用括号括起来
参数之间使用空格或分号隔开
2> 注意:指令是大小写无关的,但是参数和变量是大小写相关的
set(HELLO hello.cpp) # 定义一个变量名叫HELLO 变量的值为hello.cpp
add_executable(hello main.cpp hello.cpp) # 通过main.cpp 和hello.cpp 编译生成,这里的hello可执行程序名
ADD_EXECUTABLE(hello main.cpp ${HELLO}) # 作用同上
3> 变量使用${}进行取值,但是在if控制语句中,是直接使用变量名的
if(HELLO) 是正确的
if(${HELLO}) 是不正确的
4> 语句不以分号结束
7.4 重要的指令
1> cmake_minimum_required:
指定CMake的最小版本支持,一般作为第一条cmake指令
# CMake设置最小支持版本为 2.8
cmake_minimum_required(VERSION 2.8)
2> project:
定义工程的名称,并可以指定工程支持的语言
# 指定工程的名称为HELLOWORLD
project(HELLOWORLD CXX) # 表示工程名为HELLOWORLD 使用的语言为C++
3> set:
显式定义变量
# 定义变量 SRC 其值为 sayhello.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
4> add_executable:
通过依赖生成可执行程序
# 编译main.cpp 生成main的可执行程序
add_executable(main main.cpp)
5> include_directories:
向工程添加多个特定的头文件搜索路径吗,类似于g++编译指令中的 -I
# 将/usr/lib/mylibfolder 和 ./include添加到工程路径中
include_directories(/usr/lib/mylibfolder ./include)
6> link_directories:
向工程中国添加多个特定的库文件搜索路径,类似于g++编译指令的 -L选项
# 将将/usr/lib/mylibfolder 和 ./lib添加到库文件搜索路径中
link_directories(/usr/lib/mylibfolder ./lib)
7> add_library:
生成库文件(包括动态库和静态库)
# 通过SRC 变量中的文件,生成动态库
add_library(hello SHARED ${SRC}) # 该语句生成的是动态库
add_library(hello STATIC ${SRC}) # 该语句生成的是静态库
8> add_compile_options:
添加编译参数
# 添加编译参数: -Wall -std=c++11
add_compile_options(-Wall -std=c++11)
9> target_link_libraries:
为target添加需要链接的共享库,类似于g++编译中的 -l 指令
# 将hello 动态库文件链接到可执行程序main中
target_link_libraries(main hello)
7.5 CMake常用变量
1> CMAKE_C_FLAGS:gcc编译选项的值
2> CMAKE_CXX_FLAGS:g++编译选项的值
# 在CMAKE_CXX_FLAGS编译选项后追加 -std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
3> CMAKE_BUILD_TYPE:编译类型(Debug 、Release)
# 设定编译类型为Debug,调试时需要选择该模式
set(CMAKE_BUILD_TYPE Debug)
# 设定编译类型为Release,发布需要选择该模式
set(CMAKE_BUILD_TYPE Release)
三.CMake工程实战
7.6 CMake编译工程
CMake目录结构:项目主目录中会放一个CMakeLists.txt的文本文档,后期使用cmake指令时,依赖的就是该文档
1> 包含源文件的子文件夹中包含CMakeLists.txt文件时,主目录的CMakeLists.txt要通过add_subdirector添加子目录
2> 包含源文件的子文件夹中不包含CMakeLists.txt文件时,子目录编译规则,体现在主目录中的CMakeLists.txt
7.6.1 两种构建方式 (推荐外部构建)
1> 内部构建:不推荐使用
内部构建会在主目录下,产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件放在一起时,会显得比较杂乱无章
## 内部构建
# 在当前目录下,编译主目录中的CMakeLists.txt 文件生成Makefile文件
执行语法:cmake .
# . 表示当前路径
# 执行make命令,生成目标文件
执行语法:make
2> 外部构建:推荐使用
将编译输出的文件与源文件放到不同的目录下,进行编译,此时,编译生成的中间文件,不会跟工程源文件进行混淆
## 外部构建步骤
# 1、在当前目录下,创建一个 build 文件,用于存储生成中间文件
mkdir build
# 2、进入build文件夹内
cd build
# 3、编译上一级目录中的CMakeLists.txt,生成Makefile文件以及其他文件
cmake ..
# ..表示上一级目录
# 4、执行make命令,生成可执行程序
make
7.7 CMake代码实战
7.7.1 同一目录下的文件进行编译
1> 源文件
2> CMakeLists.txt文件
3> 内部构建
4> 外部编译
7.7.2 分文件编译
1> 头文件
2> 源文件
3> 测试文件
4> 分文件编译使用g++编译器生成可执行程序
5> 创建工程管理文件 CMakeLists.txt
