作者:枕霞旧友
链接:https://zhuanlan.zhihu.com/p/344207718
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


前言

我们使用 Make 工具构建项目时,需要编写 Makefile,但不同的平台 Make 工具是不一样的,比如 Linux 的 GNU Make ,Windows 的 nmake,它们对 Makefile 的规范也是不一样的,如果软件要跨平台,则需要针对每一种 Make 工具写一份 Makefile,非常浪费时间;而且当软件比较庞大时,Makefile 的编写也会变的复杂。

CMake 简介

CMake(Cross-Platform-Make)是一个开源、跨平台的软件构建工具,它使用与平台独立的配置文件来对软件编译过程进行控制,根据用户所需,生成 Makefile 或者 IDE的 project。

CMake 构建过程

  • 编写 CMake 配置文件 CMakeLists.txt,一般放在项目的最顶层目录下。
  • 运行 cmake 命令,参数为 CMakeLists.txt 所在根路径,执行完成后得到 Makefile 文件。
  • 使用 make 命令进行编译。

$ mkdir -p build && cd build
$ cmake …
$ make

基本语法

指定最小版本

如果使用的 CMake 版本低于该版本,则会发出致命错误。
cmake_minimum_required(VERSION 3.9)

设置工程名

可以同时指定工程版本和语言,CXX 代表 C++。
project(sunflower VERSION 0.0.1 LANGUAGES C CXX)

设置 c/c++版本

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)

设置编译选项

set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -g -w -O3")
set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -g -w -O3”)

添加宏定义

add_definitions(-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_INFO)

设置头文件搜索目录

实现编译时的 [-I] 选项,设置后引用头文件不需要使用相对路径,直接引用文件名。
include_directories(
“${PROJECT_SOURCE_DIR}/include”
“${PROJECT_SOURCE_DIR}/depends/json/”
“${PROJECT_SOURCE_DIR}/depends/leveldb/include”
)

设置库文件搜索目录

实现编译时的[-L]选项,项目内部明确路径的库文件,可以通过该命令指定。
link_directories(
“${PROJECT_SOURCE_DIR}/depends/json/lib”
“${PROJECT_SOURCE_DIR}/depends/leveldb”
)

查找指定库文件

查找到指定的预编译库,并将它的路径存储在变量中。默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的name 即可(不需path),类似的命令还有 find_file()、find_path()、find_program()、find_package()。

find_library(log-lib,log)

查找指定目录下源文件

获取指定目录下源文件列表,保存到 DIR_SRCS 变量中,后续编译构建目标可执行文件。注意这里不能递归获取子目录下的源文件。
aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRCS)

添加子目录源文件

使用命令 add_subdirectory 指明本项目包含一个子目录,这样子目录下的 CMakeLists.txt 文件和源文件也会被处理。

项目包含多个子目录时,通常可以在子目录下也定义 CMakeLists.txt 文件,并通过 add_library 生成包含子目录源码的库文件,并最终链接到目标可执行文件。
add_subdirectory(utils)
add_subdirectory(config)

递归查找目录下的所有源文件

可以通过 file 命令递归获取指定目录下的所有源文件,这样可以不用为子目录专门定义CMakeLists.txt,也不需要通过链接的方式集成各个子目录,而是统一编译构建。
file(GLOB_RECURSE DIR_SRCS
${PROJECT_SOURCE_DIR}/src/.c
${PROJECT_SOURCE_DIR}/src/
.cc
${PROJECT_SOURCE_DIR}/src/*.cpp
)

设置可执行文件输出路径

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

生成可执行文件

add_executable(${PROJECT_NAME} ${DIR_SRCS})

生成库文件

add_library(${PROJECT_NAME} STATIC ${DIR_SRCS})
add_library(${PROJECT_NAME} SHARED ${DIR_SRCS})

链接库文件

set(EXTRA_LIBS
sasl2
libleveldb.a
)
target_link_libraries(${PROJECT_NAME}
${EXTRA_LIBS}
)

常用变量

PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行cmake命令的目录,通常为${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置

支持 Debug 版本

设置不同版本的编译选项
set(CMAKE_CXX_FLAGS_DEBUG “$ENV{CXXFLAGS} -O0 -Wall -g -ggdb”)
set(CMAKE_CXX_FLAGS_RELEASE “$ENV{CXXFLAGS} -O3 -Wall”)

cmake 时指定版本
cmake … -DCMAKE_BUILD_TYPE=Debug
cmake … -DCMAKE_BUILD_TYPE=Release

完整示例

工程结构

+-- CMakeTest|+-- CMakeList.txt+-- src|+--  main.cc+--- utils/|+--- utils.cc+--- utils.h+-- config/|+-- config.cc+-- config.h+-- libs|+-- libleveldb.a

CMakeLists.txt

cmake_minimum_required(VERSION 3.7.1)project(CMakeTest VERSION 0.0.1 LANGUAGES C CXX)set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -g -w -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -w -O3")set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)include_directories("utils""config"
)link_directories(""${PROJECT_SOURCE_DIR}/libs""
)# 子目录的CMakeList.txt也可以定义到主配置中
# 将utils和config两个子目录的源文件打包成库test_share
aux_source_directory(${PROJECT_SOURCE_DIR}/src/utils SHARE_SRC_FILES)
aux_source_directory(${PROJECT_SOURCE_DIR}/src/config SHARE_SRC_FILES)
add_library(test_share STATIC ${SHARE_SRC_FILES} )aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRCS)
add_executable(${PROJECT_NAME} ${DIR_SRCS})# 也可以使用file命令递归获取目录下所有源文件
file(GLOB_RECURSE DIR_SRCS${PROJECT_SOURCE_DIR}/src/*.c${PROJECT_SOURCE_DIR}/src/*.cc${PROJECT_SOURCE_DIR}/src/*.cpp
)
add_executable(${PROJECT_NAME} ${DIR_SRCS})set(EXTRA_LIBSldlpthreadlibleveldb.a
)target_link_libraries(${PROJECT_NAME}test_share${EXTRA_LIBS}
)

CMake 使用总结(转载)相关推荐

  1. cmake用法及常用命令总结(全)

    CMakeLists.txt 的语法比较简单,由命令.注释和空格组成,其中命令是不区分大小写的.指令是大小写无关的,参数和变量是大小写相关的.但推荐全部使用大写指令.符号 # 后面的内容被认为是注释. ...

  2. mac 安装cmake

    下载:https://cmake.org/download/ 下载完成后,双击安装 安装完成后,打开命令行,运行 bogon:~ macname$ sudo "/Applications/C ...

  3. [BuildRelease]跨平台构建工具Cmake

    一 CMake CMake 是一个跨平台的构建工具,通过一次的cmake script的编写,能够生成常见平台常见IDE的project文件或maikefile文件,例如生成visual studio ...

  4. HelloWorld CMake Demo 03:CMake中构建静态库与动态库及其使用

    继续完善Hello World,建立它的共享库,包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc向终端输出Hello W ...

  5. CMake参考手册(草稿)

    CMakeList.txt 引言 cmake_minimum_required(VERSION XXX) project(xxx) add_executable(xx xxx)CMAKE_SOURCE ...

  6. DirectFB编译环境

    DirectFB是用于嵌入式平台的一个2D图形库,主要面向嵌入式平台.不过,也支持在PC平台进行开发,测试相关功能,只要对应的Linux支持FrameBuffer设备. 本文以DirectFB源码自带 ...

  7. Ubuntu配置交叉编译环境

    1.配置aarch64-linux-gnu编译环境 sudo apt-get install gcc-aarch64-linux-gnu sudo apt-get install g++-aarch6 ...

  8. 如何在Lua与C/C++之间实现table数据的交换

    为什么80%的码农都做不了架构师?>>> 之前在<C/C++和Lua是如何进行通信的?>一文中简单的介绍了lua与宿主之间的通信.简单的说两种不同的语言之间数据类型不一样 ...

  9. NVIDIA PhysX宣布正式开源 最强物理仿真引擎

    2019独角兽企业重金招聘Python工程师标准>>> 近日,辉达(NVIDIA)在官方部落格宣布正式开源被誉为「市面最强大物理仿真引擎」的 PhysX,除了广泛用于提升游戏特效,还 ...

  10. arm开发板源码编译mysql

    2019独角兽企业重金招聘Python工程师标准>>> mysql:5.5.58,arm 32位开发板:centos 7,4.4.52-armada-17.06.2 一.下载mysq ...

最新文章

  1. 案例:Oracle dul数据挖掘 磁盘损坏dul提取数据文件中表的数据及l
  2. 「starter推荐」简单高效 Excel 导出工具
  3. Code Generate of Power Designer[转]
  4. Windows 8 动手实验系列教程 实验6:设置和首选项
  5. 还在熬夜憋思路?这12篇最新论文打包送给你 | 本周值得读
  6. 中柏平板u盘启动_大冶深圳东莞平板硫化机推选得新科技自动化
  7. 551. Student Attendance Record I 从字符串判断学生考勤
  8. Kubernetes1.7 新特性:日志审计变化
  9. php smarty if,php Smarty中if,elseif,else用法详解
  10. 【蓝牙】 HCI log分析工具----Frontline ComProbe Protocol Analysis System使用教程
  11. 计算机重装系统怎么链接打印机,如何连接打印机,详细教您电脑如何与打印机连接...
  12. 输入出租车类型和里程,计算打车的费用。
  13. 京东淘宝天猫API销量接口
  14. 水题poj1423 解题报告
  15. 关于Linux下Docker内网离线安装的一些笔记
  16. Linux下修改Oracle字符集为ZHS16GBK
  17. 塘沽区学计算机考证去哪
  18. HTML图像、背景、颜色
  19. 对比度亮度调整与通道分离合并
  20. 两个可取代Nero的免费刻录软件下载

热门文章

  1. 1 操作系统安全加固
  2. RHEL服务器配置BIND以及实现DNS负载均衡
  3. .NET软件授权管理解决方案Eziriz .NET IntelliLock
  4. 单臂路由实验(子接口的使用)
  5. Axis1.x WebService开发指南—目录索引
  6. load runner
  7. 27. 安全 HTTP (2)
  8. 6. wordpress plug-in
  9. 第4讲 The Zend Framework MVC Architecture
  10. oracle+导入导出教程,oracle导入导出整理(一)