示例源码
在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
- 编写 CMake 配置文件 CMakeLists.txt
- 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile
ccmake 和 cmake 的区别在于前者提供了一个交互式的界面。
。其中, PATH 是 CMakeLists.txt 所在的目录。
- 使用 make 命令进行编译。
入门案例一(单文件)
先看下目录和源码
代码的逻辑非常简单就是求10的立方。
重点时候在CMakeLists.txt
# '#'行后面的都是注释
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Calc)
# 指定生成目标 main为编译生成文件, main.cpp为源文件
add_executable(main main.cpp)
-
#
为注释标识 -
cmake_minimum_required
是最低版本要求,这个是必须要的 -
project
项目信息 -
add_executable
将main.cpp编译成main
如果我们将cmake_minimum_required (VERSION 2.8)
版本改成2.9.2。我的机器上cmake版本是cmake version 2.8.12.2
。执行cmake .
后报错:
正常执行完
cmake
后,会在根目录下生成Makefile。然后我们就可以用make
来编译了。
入门案例二(同目录多文件)
这里我们在案例一的基础上新增Math.h
、Math.cpp
#include "Math.h"
long pow(int base,int power){
long res=1;
for(int i=0; i<power; i++) {
res*=base;
}
return res;
}
然后修改main.cpp的include文件,将使用系统的math.h
替换成我们自己的Math.h
#include <iostream>
#include "Math.h"
using namespace std;
int main(){
int x=10;
int y=3;
int res=pow(10,3);
cout<<res<<endl;
return 0;
}
修改CMakeLists.txt
方法一
add_executable(main main.cpp Math.cpp)
在add_executable
参数中加入Math.cpp
方法二
如果源文件很多,这样写就很蛋疼了。我们可以使用aux_source_directory
命令
aux_source_directory(<dir> <variable>)
该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。
# '#'行后面的都是注释
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Calc)
# 指定生成目标 main为编译生成文件, main.cpp为源文件
# 方法一:一个个添加
# add_executable(main main.cpp Math.cpp)
# 方法二:查找目录下文件到变量中,然后引用变量
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
入门案例三(多目录、多文件)
对于这种情况,需要分别在项目根目录 Simple和 math 目录里各编写一个 CMakeLists.txt 文件。为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用。
math瞎的CMakeLists.txt内容为:
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library (MathFunctions ${DIR_LIB_SRCS})
当然,main.cpp引入的头文件也要修改,math.h的位置已经变了。
#include "math/Math.h"
入门案例四(自定义编译选项)
# '#'行后面的都是注释
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Calc)
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
"Use provided math implementation" ON)
# 是否加入 MathFunctions 库
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/math")
add_subdirectory (math)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(main main.cpp)
# 添加链接库
target_link_libraries(main ${EXTRA_LIBS})
添加config.h.in
#cmakedefine USE_MYMATH
修改main.cpp
#include <iostream>
#include "config.h"
#ifdef USE_MYMATH
#include "math/Math.h"
#else
#include <math.h>
#endif
using namespace std;
int main(){
int x=10;
int y=3;
int res=pow(10,3);
cout<<res<<endl;
return 0;
}
如果定义了USE_MYMATH就使用自己的Math.h否则include系统的math.h
这里我们可以使用ccmake命令,可以选择ON或OFF。然后按c进行配置。然后再按g进行生成
入门案例五(安装和测试)
添加版本号
首先修改顶层 CMakeLists 文件,在 project 命令之后加入如下两行:
# 设置版本号
set (Demo_VERSION_MAJOR 1)
set (Demo_VERSION_MINOR 0)
为了在代码中获取版本信息,我们可以修改 config.h.in 文件,添加两个预定义变量:
#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
程序中就可以获取相关信息
cout<<"Version "<<Demo_VERSION_MAJOR<<"."<<Demo_VERSION_MINOR<<endl;
生成安装包
首先在顶层的 CMakeLists.txt 文件尾部添加下面几行:
# 构建一个 CPack 安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
"${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
include (CPack)
上面的代码做了以下几个工作:
导入 InstallRequiredSystemLibraries 模块,以便之后导入 CPack 模块;
设置一些 CPack 相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号;
导入 CPack 模块。
- 生成二进制安装包:
cpack -C CPackConfig.cmake
- 生成源码安装包
cpack -C CPackSourceConfig.cmake