CMAKE前言
- Cmake是一个跨平台(Windows,Linux,mac)的安装编译工具,可以用简单的语句描述所有平台的安装编译过程。
- Cmake已成为大部分C++开源项目标配
一. 语法特性
- 基本语法格式: 指令(参数1 参数2 …)
- 参数用括号括起
- 参数之间用空格或分号分开
- 指令不区分大小写,参数和变量区分大小写
set(Hello hello.cpp)
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})
- 变量使用 ${} 方式取值,但在IF控制语句中直接使用变量名
if ${HELLO}
是错误的
二. 重要指令
· cmake_minimum_required
· 指定CMake的最小版本要求
Cmake_minimum_required(Version 版本号 [FATAL_ERROR])
#最小版本要求为2.8.3
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
· project
· 定义工程名称,并指定工程支持的语言
project(工程名 [CPP] [C] [Java])
#指定工程名为HELLOWORLD
project(HELLOWORLD)
· set
· 显式的定义变量
set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
#定义SRC变量,其值为sayhello.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
· aux_source_directory
· 把某一目录下的所有源文件定义为变量VAR
# 定义SRC变量,表示的当前目录下的所有源代码文件
aux_source_directory(. SRC)
· include_directories
· 向工程添加头文件(.h)搜索路径(等价于g++ -I./inlude参数),空格分开表示不同的头文件路径
include_directories(./include /usr/include/myincludefolder)
· add_library
· 生成库文件,这里是自定义的cpp文件生产.a或.so库文件
add_library(库文件名称 [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) #SHARED-动态库 STATIC-静态库
#通过变量SRC代表的cpp文件生成libhello.so库
add_library(libhello SHARED ${SRC})
· link_directories
· 向工程添加库文件搜索路径(等价于g++ -L./lib参数),这里一般link的是标准库文件的位置
link_directories(/usr/lib/mylibfolder ./lib)
· target_link_libraries
· 为target添加需要链接的共享库(等价于g++ -l库名)
#将hello动态库文件链接到可执行文件main
target_link_libraries(main hello)
· add_subdirectory
· 向当前工程添加存放源文件的子目录,并且可以指定中间二进制和目标二进制存放的位置
#添加src子目录,src中需要有一个Cmakelists.txt
add_subdirectory(src)
· add_executable
· 生成可执行文件
add_executable(exename source1 source2 ... sourceN)
#编译main.cpp生成可执行文件main
add_executable(main main.cpp)
· Add_compile_options
· 添加编译参数
add_compile_options(-O2 -Wall -std=c++11 .......)
#添加编译参数 -Wall -std=c++11
add_compile_options(-Wall -std=c++11 -O2)
三. 常用变量
-
CMAKE_C_FLAGS —— gcc编译选项
-
CMAKE_CXX_FLAGS —— g++编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-
CMAKE_BUILD_TYPE —— 编译类型(Debug, Release)
# 设置编译类型为debug,调试时需要选择debug,发布时选择release set(CMAKE_BUILD_TYPE Debug)
-
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
_BINARY_DIR时间
在in source编译中指代工程顶层目录,在out of source编译中指代工程编译发生的目录
-
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
_BINARY_DIR
无论采用何种编译方式,都指代工程顶层目录。
-
CMAKE_C_COMPILER —— 指定C编译器
-
CMAKE_CXX_COMPILER —— 指定C++编译器
-
EXECUTABLE_OUTPUT_OATH —— 可执行文件输出的存放路径
-
LIBARY_OUTPUT_PATH —— 库文件输出的存放路径
四. CMAKE编译
4.1 目录结构及编译规则
-
项目主目录存在CMakeLists.txt文件
-
src/中若存在CMakeLists.txt文件,主目录的CMakeLists.txt通过add_subdirectory添加/src目录即可
src/中若不存在CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中
4.2 编译流程
-
手动编写CMakeLists.txt
-
执行命令
cmake PATH
(PATH指顶层CMakeLists.txt所在目录) -
执行命令
make
进行编译cmake PATH
与make
指令在/build中执行,则为外部构建(out of source build);在/src中执行则为内部构建(in source build)。
五. CMAKE编译实践
#编译git下来的库
git clone git@github.com:ceres-solver/ceres-solver.git
cd ceres-solver/
mkdir build/
cd build/
cmake ..
make -j8
sudo make install #不是库的话好像不需要这一步