从事linux的开发工作,不可避免的需要进行编译构建的工作,直接编辑Makefile,不仅需要熟悉Makefile的语法,还需要知道依赖和推导规则,比较麻烦。而cmake工具,只需要开发者提供头文件路径、库路径、编译参数等基本参数,就能快速生成Makefile,语法简单,能够快速上手,另外cmake工具能够满足跨平台的要求,因此应用比较广泛。

下面我们以一个实际的计算器的例子,逐步深入对cmake的学习理解。

一、最简单的例子

在linux平台下使用cmake生成Makefile并编译的通常流程有下面几步。
1、编写cmake配置文件CMakeLists.txt
通常CMakeLists.txt放在项目顶层目录,根据需要也可在子目录放置。
2、在CMakeLists.txt文件所在目录创建一个build文件夹,然后进入目录。
不建目录理论上是可行的,但是生成的中间文件不易清理,另外build目录名词也是可以自定义的。
3、执行cmake …/ 生成makefile。
4、执行make和make install进行编译和安装。

下面是一个linux C/C++最简单的程序,“欢迎使用计算器”。
main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {printf("Welcome to calculator !\n");return 0;
}

我们看一下编译它,需要的CMakeLists.txt如何编写。

#指定使用该CMakeList.txt文件需要的cmake最低版本
cmake_minimum_required(VERSION 3.5)
#指定项目信息
project(calculator)#设置安装目录
set(INSTALL_DIR ${CMAKE_SOURCE_DIR}/install)#指定生成目标
add_executable(calculator main.cpp)#安装到安装目录
INSTALL(TARGETS calculator DESTINATION ${INSTALL_DIR}/usr/bin)

其中,CMAKE_SOURCE_DIR为cmake定义的变量,指定义了顶级CMakeLists.txt的文件夹。
最后执行下面脚本,进行创建build目录、生成Makefile、编译连接、安装的操作。

mkdir build
cd build
cmake ../
make
make install

二、多个源文件的例子

下面我们对上面的例子进行扩展,增加加法运算的函数,add.cpp和add.h文件。

├── add.cpp
├── add.h
├── CMakeLists.txt
└── main.cpp

那现在怎么把增加的文件编译进去呢?我们只需要简单修改一下CMakeLists.txt文件即可。

#指定生成目标,在这里增加文件
add_executable(calculator main.cpp add.cpp)

但是,如果我们继续增加减法运算的函数,sub.cpp和sub.h文件,或者再增加更多文件呢?

├── add.cpp
├── add.h
├── CMakeLists.txt
├── main.cpp
├── sub.cpp
└── sub.h

虽然我们可以继续按照上面的方式添加,但是比较繁琐,我们可以使用aux_source_directory命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定的变量名。

#指定使用该CMakeList.txt文件需要的cmake最低版本
cmake_minimum_required(VERSION 3.5)
#指定项目信息
project(calculator)#设置安装目录
set(INSTALL_DIR ${CMAKE_SOURCE_DIR}/install)#查找当前目录下的所有源文件
#并将名称保存到ALL_SRCS变量
aux_source_directory(. ALL_SRCS)#指定生成目标
#add_executable(calculator main.cpp add.cpp sub.cpp)
add_executable(calculator ${ALL_SRCS})#安装到安装目录
INSTALL(TARGETS calculator DESTINATION ${INSTALL_DIR}/usr/bin)

三、动态库和静态库的例子

我们继续在上面的例子上进行扩展,增加乘法运算,编译成静态库,增加除法运算,编译成动态库,并最终链接为一个可执行程序。
增加后的文件如下:

├── add.cpp
├── add.h
├── CMakeLists.txt
├── div
│   ├── CMakeLists.txt
│   ├── div.cpp
│   └── div.h
├── main.cpp
├── mul
│   ├── CMakeLists.txt
│   ├── mul.cpp
│   └── mul.h
├── sub.cpp
└── sub.h

我们看到mul和div文件夹下分别有一个CMakeLists.txt子文件,然后在顶层CMakeLists.txt文件中可以对这个进行包含。

mul目录下的CMakeLists.txt文件:

#查找当前目录下的所有源文件
#并将名称保存到MUL_SRCS变量
aux_source_directory(. MUL_SRCS)#生成静态链接库
add_library(mul STATIC ${MUL_SRCS})#安装到安装目录
INSTALL(TARGETS mul DESTINATION ${INSTALL_DIR}/usr/lib)

div目录下的CMakeLists.txt文件:

#查找当前目录下的所有源文件
#并将名称保存到DIV_SRCS变量
aux_source_directory(. DIV_SRCS)#生成动态链接库
add_library(div SHARED ${DIV_SRCS})#安装到安装目录
INSTALL(TARGETS div DESTINATION ${INSTALL_DIR}/usr/lib)

其中add_library命令能够将指定的源文件根据参数的不同(STATIC/SHARED)编译为静态或者动态链接库。

顶层目录下的CMakeLists.txt文件:

#指定使用该CMakeList.txt文件需要的cmake最低版本
cmake_minimum_required(VERSION 3.5)
#指定项目信息
project(calculator)#设置安装目录
set(INSTALL_DIR ${CMAKE_SOURCE_DIR}/install)#添加子目录
add_subdirectory(mul)
add_subdirectory(div)#包含头文件目录
include_directories(${CMAKE_SOURCE_DIR}/mul)
include_directories(${CMAKE_SOURCE_DIR}/div)#查找当前目录下的所有源文件
#并将名称保存到ALL_SRCS变量
aux_source_directory(. ALL_SRCS)#指定生成目标
add_executable(calculator ${ALL_SRCS})#添加链接库
target_link_libraries(calculator mul)
target_link_libraries(calculator div)#安装到安装目录
INSTALL(TARGETS calculator DESTINATION ${INSTALL_DIR}/usr/bin)

其中,add_subdirectory命令表示本项目包含一个子目录,include_directories命令表示将指定目录添加到编译器的头文件搜索路径之下,target_link_libraries命令表示可执行文件calculator需要连接一个名为 mul/div的链接库。

注:每次CMakeLists.txt变动,需要重新执行cmake …/生成Makefile文件。

本文所用到的源文件和CMakeLists.txt可以在这获得:https://download.csdn.net/download/fddnihao/19132675
cmake教程-提高篇:https://blog.csdn.net/fddnihao/article/details/117370344

cmake教程-入门篇相关推荐

  1. 【helloworld】-微信小程序开发教程-入门篇【1】

    1. 开篇导言 本节目标:旨在演示如何用开发者工具构建并运行简单的 helloworld 应用. 目标用户:无编程经验,但对微信小程序感兴趣的同学. 学习目标:开发者工具的基本使用流程,即创建.导入. ...

  2. jQuery LigerUI 使用教程入门篇

    jQuery LigerUI 使用教程入门篇 阅读目录 获取最新代码 ligerUI是什么 如何使用 如何扩展 获取最新代码 可以到http://ligerui.googlecode.com下载最新代 ...

  3. java ligerui_[Java教程]jQuery LigerUI 使用教程入门篇_星空网

    jQuery LigerUI 使用教程入门篇 2012-01-17 0 阅读目录获取最新代码 ligerUI是什么 如何使用 如何扩展 获取最新代码 可以到http://ligerui.googlec ...

  4. 微信小程序教程入门篇

    微信小程序教程入门篇: 微信小程序怎么做?做一个微信小程序要多少钱呢? 作为Z时代,Y时代的我们,做一个微信小程序难道还要去看书学代码吗? 不存在的各位. 现在制作一个微信小程序,只需要动动鼠标键盘, ...

  5. python语言自学教程-3D图示Python标准自学教程入门篇

    内容简介: Python入门篇教程从最基础的计算机发展史.Python的来源与发展历史开始讲起: 依次讲解python变量与表达式.数据类型.运算符.流程控制语句等,末尾通过课堂练习.课后作业以及微型 ...

  6. python自学教程-3D图示Python标准自学教程入门篇

    内容简介: Python入门篇教程从最基础的计算机发展史.Python的来源与发展历史开始讲起: 依次讲解python变量与表达式.数据类型.运算符.流程控制语句等,末尾通过课堂练习.课后作业以及微型 ...

  7. python自学课堂_3D图示Python标准自学教程入门篇

    内容简介: Python入门篇教程从最基础的计算机发展史.Python的来源与发展历史开始讲起: 依次讲解python变量与表达式.数据类型.运算符.流程控制语句等,末尾通过课堂练习.课后作业以及微型 ...

  8. 基于AT89C51教程入门篇一

    51单片机入门篇一之单片机概述 (本文是参考郭天祥老师的教程,用于巩固自我知识,不喜勿喷) 1.1什么是单片机 具备独立处理程序,自带存储器及各种IO口的芯片,叫做单片微型计算机,大陆称之单片机,台湾 ...

  9. 《Genesis-3D游戏引擎系列教程-入门篇》九:发布到移动平台

    2019独角兽企业重金招聘Python工程师标准>>> 注:本系列入门教程仅针对引擎编辑器:v1.2.2及以下版本 1.发布到Android平台 在游戏制作完毕后,需要进行平台打包才 ...

最新文章

  1. 测试Linux网卡是否正常工作
  2. 二者取其一(初遇)_网络流
  3. N001-SQL Server 2016企业版本安装
  4. 【Java后台】Java执行Python代码的3类5种情况测试【Java源码+Python源码举例】
  5. nginx系列之三:日志配置
  6. 排序算法python版本
  7. springboot 前缀_springboot搭配thymeleaf访问html页面的时候,什么时候需要自定义前缀和后缀呢...
  8. SpringMVC+idea+maven搭建项目
  9. PAIP.MYSQL数据库比较
  10. 写给自己的CDSN账号
  11. 视频开头独白怎么做?一分钟学会
  12. 怎么手动修改域名服务器地址,如何修改域名dns服务器地址
  13. 由word制作CHM文件
  14. JVM - 工欲善其事必先利其器之虚拟机工具(上)
  15. 微信小程序图片懒加载插件
  16. mysql leader/followers_Leader/Followers 模式
  17. C语言——矩阵计算(转置、加法、减法、数乘、乘法)
  18. Enterprise Architect Professional操作系统特性和功能
  19. ES6给对象部署Iterator
  20. 单向链表的实现(不设立虚拟头节点)

热门文章

  1. 涨姿势:10 大主宰世界的牛逼算法!
  2. hortonworks-registry-0.5.4 : Memory: 4k page, physical 3880928k(308720k free), swap 0k(0k free)
  3. 一键收藏!阿里技术精选文章回顾
  4. 速度收藏!《阿里技术参考图册》发布,公开600页技术全景图
  5. 绿色水处理技术 纳滤膜分离在废水处理中的应用
  6. 目标检测网络进展跟踪
  7. 深度学习 --- BP算法详解(流程图、BP主要功能、BP算法的局限性)
  8. 敢不敢尝试自己写个安全扫描器(java)
  9. 登录亚马逊显示内部服务器出错,亚马逊账号无法登录怎么办?是什么原因导致的?...
  10. 半年翻倍!内存条掀起涨价潮