CMake入门实战 笔记

1. 基本模板

# CMake 最低版本要求
cmake_minimum_required (VERSION 2.8)

# 项目名称
project (Demo1)

# 指定生成目标
add_executable(Demo main.cc)

编译命令如下:

$ camke . # 如果是编译上一层目录,则 cmake ..
$ make

先生成Makefile文件,再make编译!

2. 同一目录多个源文件

# 查找指定目录下的所有源文件
aux_source_directory(<dir> <variable>)

$ aux_source_directory(. DIR_SRCS)
$ add_executable(Demo ${DIR_SRCS})

3. 多目录多源文件

  • 生成链接库
    add_library (MathFunctions ${DIR_LIB_SRCS})
    add_library(common STATIC util.cpp) # 生成静态库
    add_library(common SHARED util.cpp) # 生成动态库或共享库
    
  • 添加math子目录,这样就能同时处理math子目录下的CMakeLists.txt和源代码了
    add_subdirectory(math)
    
  • 添加链接库
    target_link_libraries(test MathFunctions)
    

注意:如果是两个CMakeLists.txt文件,应该注意子目录下名称变量不能与主目录下重复,否则报错!

4. 自定义编译选项

CMakeLists.txt内容如下:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo4)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
	   "Use provided math implementation" ON)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否加入 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 (Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

源代码中也要通过宏定义实现修改:

#ifdef USE_MYMATH
  #include <MathFunctions.h>
#else
  #include <math.h>
#endif

配置文件config.h.in的内容如下,CMake会自动根据此内容生成config.h文件,如果选项为OFF,则config.h内容会自动生成为#undef USE_MYMATH

#cmakedefine USE_MYMATH

编译时,使用ccmake进入交互式配置界面,通过选项c进入修改配置界面,通过回车键进行配置修改,修改完后通过c返回上层界面,然后选择g选项生成Makefile,最后make生成可执行文件即可。

5. 安装和测试

定义库的安装路径:

# 指定安装路径,默认安装在/usr/local/下
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

如果自定义指定安装路径,则在install之前添加:

# 设置上一层目录下的install_file文件夹为安装目录
set(CMAKE_INSTALL_PREFIX ../install_file)

安装指令为:

make install

添加测试:

# 启用测试
enable_testing()

# 测试程序是否成功运行
add_test(test_5_2 Demo 5 2)
# 测试是否能够正常打印
set_tests_properties(test_5_2  PROPERTIES PASS_REGULAR_EXPRESSION "is 25")

编写宏,简化测试:

# 定义宏
macro(do_test arg1 arg2 result)
	add_test(test_${arg1}_${arg2} Demo ${arg1} ${arg2})
	set_tests_properties(test_${arg1}_${arg2} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro(do_test)

# 使用宏
do_test(5 2 "is 25")
do_test(10 2 "is 100")
do_test(2 10 "is 1024")

测试指令为:

make test

注意:必须make生成可执行文件后才能进行测试,测试生成的报告位于"编译目录/Testing/Temporary/"下

6. 支持gdb

如果没有设置支持gdb,则查看代码时会提示:

(gdb) l
没有符号表被读取。请使用 "file" 命令。
(gdb) 

只需要指定Debug模式下开启-g选项即可完成CMake支持gdb的设置:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

7. 添加环境检查

在顶层 CMakeLists 文件中添加 CheckFunctionExists.cmake宏,并调用 check_function_exists命令测试链接器是否能
够在链接阶段找到pow函数:

#检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)

注意:由于我们在代码中会通过一些宏定义来调用不同环境下的函数,因此我们要在config.h.in文件里定义#cmakedefine HAVE_POW,因此,检查语句要放在configure_file命令之前。

8. 添加版本号

#项目信息
project (Demo7)
set(Demo_VERSION_MAJOR 2) # 指定当前项目的主版本号
set(Demo_VERSION_MINOR 3) # 指定当前项目的副版本号
set(Demo_VERSION_PATCH 1) # 指定当前项目的补丁等级

为了在代码中能够获取版本信息,修改config.h.in文件:

// the configured options and settings for Tutorial
#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@
#define Demo_VERSION_PATCH @Demo_VERSION_PATCH@

在代码中,即可通过打印宏定义实现版本获取。

9. 生成二进制安装包和源码安装包

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)
  • 生成二进制安装包
cpack -C CPackConfig.cmake
  • 生成源码安装包
cpack -C CPackSourceConfig.cmake

执行以后,会在执行目录下生成3个不同格式的二进制包文件:

  • Demo8-1.0.1-Linux.sh
  • Demo8-1.0.1-Linux.tar.gz
  • Demo8-1.0.1-Linux.tar.Z

执行以后会提示安装在了Demo8-1.0.1-Linux目录下,有bin、include、lib三个文件夹,即我们在CMakeLists.txt中设置的内容。

更多CPack的详细用法可通过man 1 cpackcpack --help查看。

10. 将其他平台的项目迁移到CMake

  • autotools
    • am2cmake工具:将autotools系的项目转换到CMake
    • Alternative Automake2CMake工具:可以转换使用automake的KDevelop工程项目
  • qmake
    • qmake converter:可以转换使用QT的qmake工程
  • Visual Studio
    • vcproj2cmake.rb:可以根据 Visual Studio 的工程文件(后缀名是 .vcproj或 .vcxproj)生成 CMakeLists.txt 文件。
    • vcproj2cmake.ps1:vcproj2cmake 的 PowerShell 版本。
    • folders4cmake:根据 Visual Studio 项目文件生成相应的 “source_group” 信息,这些信息可以很方便的在 CMake脚本中使用。支持 Visual Studio 9/10 工程文件。
  • CMakeLists.txt自动推导
    • gencmake根据现有文件推导 CMakeLists.txt 文件。
    • CMakeListGenerator应用一套文件和目录分析创建出完整的 CMakeLists.txt 文件。仅支持 Win32 平台。

11. 完整Demo

cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo8)
set (Demo_VERSION_MAJOR 1)
set (Demo_VERSION_MINOR 0)

set (CMAKE_INCLUDE_CURRENT_DIR ON)

# 检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否加入 MathFunctions 库
if (NOT HAVE_POW)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)  
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (NOT HAVE_POW)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

# 启用测试
enable_testing()

# 测试程序是否成功运行
add_test (test_run Demo 5 2)

# 测试帮助信息是否可以正常提示
add_test (test_usage Demo)
set_tests_properties (test_usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent")

# 定义一个宏,用来简化测试工作
macro (do_test arg1 arg2 result)
  add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
  set_tests_properties (test_${arg1}_${arg2}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
 
# 利用 do_test 宏,测试一系列数据
do_test (5 2 "is 25")
do_test (10 5 "is 100000")
do_test (2 10 "is 1024")

# 构建一个 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)

参考文献:

  • CMake入门实战_HaHack
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值