CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多。CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库(so(shared object))。因此CMake的编译基本就两个步骤:
cmake
make
cmake 指向CMakeLists.txt所在的目录,例如cmake .. 表示CMakeLists.txt在当前目录的上一级目录。cmake后会生成很多编译的中间文件以及makefile文件,所以一般建议新建一个新的目录,专门用来编译,例如
mkdir build
cd build
cmake .. //CMakeLists.txt所在的目录
make
make根据生成makefile文件,编译程序。
1 CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
cmake –version :查看版本
2 给工程起个名字
project (Demo1)
3 指定生成目标
add_executable(Demo main.cc)
由main.cc生成Demo可执行文件
最简单的CMakeLists.txt以上三项就可以了,此工程只包含1个源文件,
4 多个源文件在同一目录中
# 查找src目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(./src DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
(用 aux_source_directory 命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。)
5 ..$ tree
├── CMakeLists.txt
├── include
│ └── util.h
├── lib
│ └── libutil.a
└── src
└── main.cpp
11.让CMake找到我的头文件:
include_directories(./include)
or
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
相当于: gcc -I./include
CMAKE_CURRENT_LIST_DIR变量表示当前CMakeLists所在的路径.
22.让CMake找到我的源文件:
aux_source_directory(./src ${hello_src})
作用:查找dir路径下的所有源文件,保存到variable变量中.
aux_source_directory 不会递归包含子目录,仅包含指定的dir目录
CMake官方不推荐使用aux_source_directory及其类似命令(file(GLOB_RECURSE …))来搜索源文件,源文件多了,而CMakeLists并不需要(没有)变化,也就使得构建系统不能察觉到新加的文件,。
33.让CMake找到我的库文件
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
相当于: gcc -L./lib
44.告诉CMake我的构建目标
add_executable(${PROJECT_NAME} ${hello_src})
作用是使用
hellosrc里面的源文件来生成一个可执行文件,起名叫
h
e
l
l
o
s
r
c
里
面
的
源
文
件
来
生
成
一
个
可
执
行
文
件
,
起
名
叫
{PROJECT_NAME}。
55.告诉CMake我要链接哪个库文件
target_link_libraries(${PROJECT_NAME} util)
优先搜索libutil.a(util.lib),如果没有就搜索libutil.so(util.dll)。
66.传递FLAGS给C++编译器
set(CMAKE_CXX_COMPILER "clang++" ) # 显示指定使用的C++编译器
set(CMAKE_CXX_FLAGS "-std=c++11") # c++11
set(CMAKE_CXX_FLAGS "-g") # 调试信息
set(CMAKE_CXX_FLAGS "-Wall") # 开启所有警告
set(CMAKE_CXX_FLAGS_DEBUG “-O0” ) # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE “-O2 -DNDEBUG ” ) # release包优化
完整的CMakeLists.txt如下所示:
cmake_minimum_required ( VERSION 3.0)
project(hello)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src ${hello_src})
add_executable(${PROJECT_NAME} ${hello_src})
target_link_libraries(${PROJECT_NAME} util)
set(CMAKE_CXX_COMPILER "clang++" ) # 显示指定使用的C++编译器
set(CMAKE_CXX_FLAGS "-std=c++11") # c++11
set(CMAKE_CXX_FLAGS "-g") # 调试信息
set(CMAKE_CXX_FLAGS "-Wall") # 开启所有警告
set(CMAKE_CXX_FLAGS_DEBUG "-O0" ) # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " ) # release包优化
77.开始构建
在CMakeLists.txt所在目录,新建build目录,并切换进build进行构建即可.
CMake的使用有如下的“惯例”:
在项目根目录建立一个build目录:mkdir build && cd build.
执行:cmake ../
确定生成Makefile成功,执行make . 生成可执行文件。
运行可执行文件。
6.
function (fun_name arg)
# message(STATUS “length of ARGV: ${argv_len}”)
endfunction ()
fun_name(arg0 arg1 arg2 arg3)
7.多个目录,多个源文件
./Demo3
|
+— main.cc
|
+— math/
|
+— MathFunctions.cc
|
+— MathFunctions.h
根目录中的 CMakeLists.txt :
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo3)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 添加 math 子目录
add_subdirectory(math)
# 指定生成目标
add_executable(Demo main.cc)
# 添加链接库
target_link_libraries(Demo MathFunctions)
第3行,使用命令 add_subdirectory 指明本项目包含一个子目录 math,这样 math 目录下的 CMakeLists.txt 文件和源代码也会被处理 。第6行,使用命令 target_link_libraries 指明可执行文件 main 需要连接一个名为 MathFunctions 的链接库 。
子目录中的 CMakeLists.txt:
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library (MathFunctions ${DIR_LIB_SRCS})
8 . 查找库所在目录FIND_LIBRARY
FIND_LIBRARY(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH)
//严格
PROJECT(main)
SET(SRC_LIST main.cpp)
SET(CMAKE_CXX_COMPILER "clang++")
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Werror -Weverything -Wno-deprecated-declarations -Wno-disabled-macro-expansion -Wno-float-equal -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-global-constructors -Wno-exit-time-destructors -Wno-missing-prototypes -Wno-padded -Wno-old-style-cast")
SET(CMAKE_EXE_LINKER_FLAGS "-lc++ -lc++abi")
SET(CMAKE_BUILD_TYPE Debug)
ADD_EXECUTABLE(main ${SRC_LIST})
//宽松
PROJECT(main)
SET(SRC_LIST main.cpp)
SET(CMAKE_CXX_COMPILER "g++")
SET(CMAKE_CXX_FLAGS "-std=c++11 -O3")
SET(CMAKE_BUILD_TYPE Release)
ADD_EXECUTABLE(porgram_name ${SRC_LIST})
INSTALL(PROGRAMS porgram_name DESTINATION /usr/bin/)
确保被包含的目录确实是包含目录的子目录.
参考:
https://github.com/wzpan/cmake-demo/tree/master/Demo3
http://www.hahack.com/codes/cmake/
https://elloop.github.io/tools/2016-04-05/learning-cmake-1