0.导语

最近做的项目使用CLION构建,而这个采用CMakeLists.txt管理,因此为了更好的学习,故找到了一篇大牛级别的入门文章,有文章有代码,本文是花了一点时间把这篇文章学习后的重要点记录吧,原作者github地址:https://github.com/wzpan/cmake-demo。

1.单个源文件

CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的。符号 # 后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。

首先创建一个main.cpp

#include int main() {    std::cout << "Hello, World!" << std::endl;    return 0;}

编写第一个CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)project(cmakeLearn)add_executable(main main.cpp)
  1. cmake_minimum_required:指定运行此配置文件所需的 CMake 的最低版本;

  2. project:参数值是 cmakeLearn,该命令表示项目的名称是 cmakeLearn

  3. add_executable:将名为main.cpp的源文件编译成一个名称为 cmakeLearn 的可执行文件。

现在查看一下路径:

light@city:~/CLionProjects/cmakeLearn$ lsCMakeLists.txt  main.cpp

输入下列命令进行cmake

cmake .

cmake过程

light@city:~/CLionProjects/cmakeLearn$ cmake .-- The C compiler identification is GNU 5.5.0-- The CXX compiler identification is GNU 5.5.0-- Check for working C compiler: /usr/bin/cc-- Check for working C compiler: /usr/bin/cc -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Detecting C compile features-- Detecting C compile features - done-- Check for working CXX compiler: /usr/bin/c++-- Check for working CXX compiler: /usr/bin/c++ -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Detecting CXX compile features-- Detecting CXX compile features - done-- Configuring done-- Generating done-- Build files have been written to: /home/light/CLionProjects/cmakeLearn

cmake 后 生成了Makefile

light@city:~/CLionProjects/cmakeLearn$ lsCMakeCache.txt  cmake_install.cmake  main.cppCMakeFiles      CMakeLists.txt       Makefile

然后执行make

light@city:~/CLionProjects/cmakeLearn$ makeScanning dependencies of target main[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o[100%] Linking CXX executable main[100%] Built target main

执行

light@city:~/CLionProjects/cmakeLearn$ ./mainHello, World!

2.多个源文件

2.1 同一目录,多个源文件

在1中的cmake添加下面这行:

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

当本地源文件很多,如果将源文件都加到里面就很烦,所以这里采用aux_source_directory。CMake 会将当前目录所有源文件的文件名赋值给变量 DIR_SRCS ,再指示变量 DIR_SRCS 中的源文件需要编译成一个名称为 Demo 的可执行文件。

这样就避免出现下面这种情况:

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

小结:

  • aux_source_directory(. DIR_SRCS)

查找当前目录下的所有源文件,并将名称保存到 DIR_SRCS 变量。

2.2 多个目录,多个源文件

此时目录架构:

./Demo3    |    +--- main.cc    |    +--- math/          |          +--- MathFunctions.cc          |          +--- MathFunctions.h

对于这种情况,需要分别在项目根目录 Demo3 和 math 目录里各编写一个 CMakeLists.txt 文件。

为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用

这里与上述2.1CMakeLists不同之处是在上面基础上加上了:

# 添加 math 子目录add_subdirectory(math)# 添加链接库target_link_libraries(Demo MathFunctions)

以此完成:

  • 子目录添加

  • 链接库添加

最后,在子目录下指定链接库名字:

子目录中的 CMakeLists.txt:

# 查找当前目录下的所有源文件# 并将名称保存到 DIR_LIB_SRCS 变量aux_source_directory(. DIR_LIB_SRCS)# 生成链接库add_library (MathFunctions ${DIR_LIB_SRCS})

小结:

  • add_library(MathFunctions ${DIR_LIB_SRCS})

将 src 目录中的源文件编译为静态链接库。

3.自定义编译选项

CMake 允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。

例如,可以将 MathFunctions 库设为一个可选的库,如果该选项为 ON ,就使用该库定义的数学函数来进行运算。否则就调用标准库中的数学函数库。

本节CMake与2不同如下三块:

(1)加入一个配置头文件,用于处理 CMake 对源码的设置

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

configure_file 命令用于加入一个配置头文件 config.h ,这个文件由 CMake 从 config.h.in生成,通过这样的机制,将可以通过预定义一些参数和变量来控制代码的生成。

例如:修改main.cc:

#include "config.h".........#ifdef USE_MYMATH  #include "math/MathFunctions.h"#else  #include#endif

根据 USE_MYMATH 的预定义值来决定是否调用标准库还是 MathFunctions 库。

上修改main.cc中引用了一个 config.h 文件,这个文件预定义了 USE_MYMATH 的值。但我们并不直接编写这个文件,为了方便从 CMakeLists.txt 中导入配置,我们编写一个 config.h.in 文件:

#cmakedefine USE_MYMATH

这样 CMake 会自动根据 CMakeLists 配置文件中的设置自动生成 config.h 文件。

这里使用了ccmake进行可视化编译选择,Ubuntu上安装:

sudo apt-get install cmake-curses-gui

运行ccmake .后:

hjkl控制方向移动,enter 键可以修改该选项。修改完成后可以按下 c 选项完成配置,之后再按 g 键确认生成 Makefile 。ccmake 的其他操作可以参考窗口下方给出的指令提示。

下面来看一下config.h文件内容:

USE_MYMATH 为 ON
#define USE_MYMATH
USE_MYMATH 为 OFF
/* #undef USE_MYMATH */

(2)是否加入 MathFunctions 库

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

option 命令添加了一个 USE_MYMATH 选项,并且默认值为 ON

(3)是否使用自己的 MathFunctions 库

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

根据 USE_MYMATH 变量的值来决定是否使用我们自己编写的 MathFunctions 库。

4.安装和测试

4.1 安装

之前在编译一些源代码程序的时候,先make后make install,这样会把一些头文件与静态/动态库安装到指定的目录下。

那在CMAKE中同样可以这么做,如下:

首先先在 math/CMakeLists.txt 文件里添加下面两行:

 指定 MathFunctions 库的安装路径install (TARGETS MathFunctions DESTINATION bin)install (FILES MathFunctions.h DESTINATION include)

指明 MathFunctions 库的安装路径。之后同样修改根目录的 CMakeLists 文件,在末尾添加下面几行:

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

通过上面定制,后安装如下:

light@city:~/cmake-demo/Demo5$ sudo make install[ 50%] Built target MathFunctions[100%] Built target DemoInstall the project...-- Install configuration: ""-- Installing: /usr/local/bin/Demo-- Installing: /usr/local/include/config.h-- Installing: /usr/local/lib/libMathFunctions.a-- Installing: /usr/local/include/MathFunctions.h

据此完成了安装工作。

4.2 测试

CMake 提供了一个称为 CTest 的测试工具。我们要做的只是在项目根目录的 CMakeLists 文件中调用一系列的 add_test 命令。

启动测试:

# 启用测试enable_testing()

(1)无帮助信息测试

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

(2)有帮助信息测试

# 测试 2 的 10 次方add_test (test_2_10 Demo 2 10)set_tests_properties (test_2_10) PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")

其中 PASS_REGULAR_EXPRESSION 用来测试输出是否包含后面跟着的字符串。

5.支持gdb

让 CMake 支持 gdb 的设置也很容易,只需要指定 Debug 模式下开启 -g 选项:

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")

6.添加版本号

在编写项目中给项目添加版本号:

set (Demo_VERSION_MAJOR 1)set (Demo_VERSION_MINOR 0)

分别指定当前的项目的主版本号和副版本号。

如果想在代码中获取信息,可以修改config.h.in文件,添加两个预定义变量:

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

主程序调用,打印:

printf("%s Version %d.%d\n",        argv[0],        Demo_VERSION_MAJOR,        Demo_VERSION_MINOR);

7.生成安装包

如何配置生成各种平台上的安装包,包括二进制安装包和源码安装包。为了完成这个任务,我们需要用到 CPack ,它同样也是由 CMake 提供的一个工具,专门用于打包。

我们做如下三个工作:

  1. 导入 InstallRequiredSystemLibraries 模块,以便之后导入 CPack 模块;

  2. 设置一些 CPack 相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号;

  3. 导入 CPack 模块。

对应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 .,也可以指定二进制与源码安装包:

  • 生成二进制安装包:

cpack -C CPackConfig.cmake
  • 生成源码安装包

cpack -C CPackSourceConfig.cmake

cpack安装:

light@city:~/cmake-demo/Demo8$ cpack -CPackConfig.cmakeCPack: Create package using STGZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.sh generated.CPack: Create package using TGZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.tar.gz generated.CPack: Create package using TZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.tar.Z generated.

此时会在本地目录下创建3个不同格式的二进制包文件:

light@city:~/cmake-demo/Demo8$ ls Demo8*Demo8-1.0.1-Linux.sh  Demo8-1.0.1-Linux.tar.gz  Demo8-1.0.1-Linux.tar.Z

随便选择一个安装,例如sh:

sh Demo8-1.0.1-Linux.sh

使用:

light@city:~/cmake-demo/Demo8$ ./Demo8-1.0.1-Linux/bin/Demo 5 2Now we use our own Math library.5 ^ 2 is 25

cmake install_CMAKE入门实战相关推荐

  1. cmake 从入门到入土

    为什么需要CMake 你或许听过好几种 Make 工具,例如 : GNU Make QT 的 qmake 微软的 MS nmake BSD Make(pmake)Makepp 这些 Make 工具遵循 ...

  2. Fastlane 入门实战教程从打包到上传iTunes connect

    有关神器 Fastlane 持续集成\部署的文章网上挺多,本文定位是入门教程,针对 iOS 应用的持续部署,只需一条命令就可实现从 Xcode 项目到 编译\打包\构建\提交审核 文章稍微有点长,涵盖 ...

  3. Spark入门实战系列--6.SparkSQL(中)--深入了解SparkSQL运行计划及调优

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.1  运行环境说明 1.1.1 硬软件环境 l  主机操作系统:Windows 64位, ...

  4. Gerrit代码Review入门实战

    代码审核(Code Review)是软件研发质量保障机制中非常重要的一环,但在实际项目执行过程中,却因为种种原因被Delay甚至是忽略.在实践中,给大家推荐一款免费.开放源代码的代码审查软件Gerri ...

  5. Spark入门实战系列--5.Hive(下)--Hive实战

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1.Hive操作演示 1.1 内部表 1.1.1 创建表并加载数据 第一步   启动HDFS ...

  6. python入门新手项目-Python入门实战项目有哪些适合新手?

    Python入门实战项目有哪些适合新手?目前市面上有很多适合新手的Python入门练手项目,Python入门需要理论与实践相结合,前面夯实基础知识,后面通过实战项目帮助你更好的运用这些Python知识 ...

  7. 干货 | 架构师入门实战视频课程(一)

    2018-04-04 码农章为忠 <架构师入门实战视频课程> 废话不多说,直接上干货吧 这次先整理了比较初级的视频教程,后续视频会慢慢整理出来. 关注微信公众号,回复相关代码,即可获得相关 ...

  8. Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫)

    Python3网络爬虫快速入门实战解析(一小时入门 Python 3 网络爬虫) https://blog.csdn.net/u012662731/article/details/78537432 出 ...

  9. PyTorch 入门实战

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36556893/article/ ...

  10. Java 定时任务调度(8)--ElasticJob 入门实战(ElasticJob-Lite使用)

    ElasticJob 是一个分布式调度解决方案,由 2 个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成.本文主要介绍 ElasticJob-Lite 的 ...

最新文章

  1. 第一周 01-复杂度2 Maximum Subsequence Sum
  2. -jar参数运行应用时classpath的设置方法
  3. 16、Python与设计模式--模板模式
  4. 直接修改html文本页面没变化,VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析...
  5. oracle字符串处理substr、dbms_lob.substr、case when
  6. hibernate 错误 could not determine type for
  7. 牛客小白月赛8: E. 诡异数字(数位DP)
  8. vmware虚拟机挂载Windows磁盘的两种方法
  9. 构建高可用MYSQL主从复制集群
  10. <JVM上篇:内存与垃圾回收篇>01-JVM与Java体系结构
  11. Google Adsense西联汇款邮政储蓄收款流程
  12. 用css3 3d效果做一个立体盒子
  13. ppt转换成pdf格式转换器怎么使用
  14. 杰里混响调MIC增益和深度【篇】
  15. 美国旅游签证办理流程
  16. Unity ShaderGraph初始使用配置
  17. java毕业设计——基于java+Jsp+Tomcat的牙科诊所管理系统设计与实现(毕业论文+程序源码)——牙科诊所管理系统
  18. 串行干扰消除matlab仿真,串行干扰消除求详解
  19. lda plda主题模型
  20. 索引:手把手教你索引从零基础到精通使用

热门文章

  1. Atitit 前端重要概念和趋势总结 大前端 目录 1. 大前端 1 2. 三个层面上的大前端 1 2.1. 大前端与NodeJS与前后端分离 1 2.2. 微信Web 1 2.3. React
  2. Atitit 搜集热点,热门文章的整理 attilax 最近
  3. Atitit blend mode COLOR_DODGE 混合模式  “颜色减淡”模式
  4. Atitit.  Exception in thread main java.lang.Error: Unresolved compilation problem:
  5. Atitit.  Js 冒泡事件阻止 事件捕获   事件传递  事件代理
  6. Atitit.网页爬虫的架构总结
  7. paip.vs2010 或.net 4.0安装出错解决大法.
  8. paip.XXListener is already configured监听器已经被配置的解决
  9. PAIP.pdf使用
  10. 投行巨头金融科技战略——摩根士丹利财富管理转型之路篇