CMake教程

1、CMake简介

CMake是一个跨平台的编译工具,可以用简单的语句来描述所有平台的编译过程。

Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。

2、CMake中的变量

变量 名含义

PROJECT_SOURCE _DIR

(等价于CMAKE_SOURCE_DIR )

工程的根目录,及顶层CMakelists.txt文件的所在目录

PROJECT_BINARY_DIR

(等价于CMAKE_BINARY_DIR )

运行 cmake 命令的目录,通常是 build/
CMAKE_CURRENT_SOURCE_DIR对于CMake嵌套调用时,表示当前正在执行的CMakeList.txt的路径
CMAKE_CURRENT_BINARY_DIR目标编译目录
CMAKE_CURRENT_LIST_DIRCMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE当前所在的行
EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH重新定义目标链接库文件的存放位置
CMAKE_MODULE_PATH定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
PROJECT_NAME返回通过 project 命令定义的项目名称

3、CMake中的函数

1)设置最小版本

cmake_minimum_required(VERSION 3.4.1)

当 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。

2)设置项目名称

project(main)    #通过${PROJECT_NAME}可访问此函数设置的项目名字,即"main"。

3)操作变量

set(SRC_LIST main.cpp)                #创建变量SRC_LIST
set(SRC_LIST ${SRC_LIST} test.cpp)    #向变量SRC_LIST追加内容
list(APPEND SRC_LIST uart.cpp)        #向变量SRC_LIST追加内容
list(REMOVE_ITEM SRC_LIST test.cpp)   #删除变量SRC_LIST中的指定值

 4)变量打印

message(${PROJECT_SOURCE_DIR})
message("print string")
message(WARNING "This is a warnning message")
message(FATAL_ERROR "fatal error has occurred")     #致命等级错误将导致编译失败

5)设置编译类型

add_executable(demo main.cpp)         # 生成可执行文件main
add_library(common uart.cpp)          # 生成静态库libuart.a
add_library(common STATIC uart.cpp)   # 生成静态库libuart.a
add_library(common SHARED uart.cpp)   # 生成动态库或共享库libuart.so
add_subdirectory(uart/)               # 添加子目录uart,并执行uart目录下的CMakeLists.txt

6)设置资源路径

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)    #设置头文件的搜索目录
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)       #设置库文件的搜索目录

#上述过程等价于
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/inc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/lib")

7)添加库文件

#下述两种方式都是在link_directories设置目录下进行搜索的
link_libraries(-pthread uart)                        #链接线程库和libuart.so
target_link_libraries(${PROJECT_NAME} pthread uart)  #链接线程库和libuart.so

上述链接的库,可以显示地指定为静态的或动态的,若未指定,则优先使用动态库。指定方法如下:

link_libraries(libuart.so)                         #链接libuart.so
target_link_libraries(${PROJECT_NAME} libuart.so)  #链接libuart.so

 注意:这两个函数的功能相同,但用法略有不同。其中link_directories通常用在add_execable之前,而target_link_directories则在其后。

8)文件搜索

aux_source_directory(. SRC_LIST)     #搜索当前目录下的所有源文件,不递归搜索子目录

#也可以自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "uart/*.cpp")    #搜索当前目录下和uart目录下所有的cpp文件
file(GLOB_RECURSE SRC_LIST "*.cpp")         #从当前目录进行递归搜索,搜索所有的cpp文件

9)添加依赖

#当main的生成需要依赖于uart库和sound库时,添加此语句,可先编译依赖的库
add_dependencies(main libuart.so libsound.so)

10)宏的传递

#向程序中传递宏X86和LINUX,则程序中可以使用"#ifdef LINUX"
add_definitions(-DX86 -DLINUX)

#等价于
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -DLINUX")      #C语言
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLINUX")    #C++

11)编译控制

#CMake代码
option(TEST_DEBUG "option for debug" OFF)    #默认TEST_DEBUG为OFF态
if (TEST_DEBUG)
    add_definitions(-DTEST_DEBUG)            #向源代码中传递宏TEST_DEBUG
endif()

#CMake命令
cmake -DTEST_DEBUG=ON .        #向当前文件夹的CMakeLists传递CMake宏TEST_DEBUG,其值为ON

12)引入外部功能包(find_package)

参考:Cmake之深入理解find_package()的用法 - 知乎 (zhihu.com)

13)在CMake执行子进程(execute_process)

参考:CMake命令之execute_process - 程序园 (aiuxian.com)

4、CMake中的语法

1)if

常见用法:

if(TEST_DEBUG)
    #操作
else()
    #操作
endif()

 逻辑判断:

if (expr)        #判断是否为空,其中空的范围包括(0,N,NO,OFF,FALSE,NOTFOUND)
if (not expr)         #非
if (var1 AND var2)    #与
if (var1 OR var2)     #或
if (variable LESS number)    #小于
if (variable GREATER number) #大于
if (variable EQUAL number)   #等于

#判断变量是否被定义过,而不关心变量的值
if (DEFINED var)

字符串比较:

if (variable STRLESS string)      #小于
if (variable STRGREATER string)   #大于
if (variable STREQUAL string)     #等于
if (variable MATCHES regex)       #正则匹配

系统操作:

if (COMMAND cmd)    #判断cmd是否为可执行命令
if (EXISTS file)    #判断文件是否存在
if (EXISTS dir)     #判断目录是否存在
if (IS_DIRECTORY dir)    #判断变量dir是否为目录

#判断file1是否比file2新。注意:file1、file2中有一个不存在时也为真,且文件名需使用全路径
if (file1 IS_NEWER_THAN file2)    

2)foreach

foreach(i RANGE 1 7 2)    #其中1表示起始值,7表示终止值,2为步长。即i∈[1,7]
    message(${i})    #依次输出的结果为1357
endforeach(i)

3)while

while(condition)
    #操作
endwhile()

4、范例

cmake_minimum_required(VERSION 2.8)
project(awake_aiui)            #设置项目名称
set(CMAKE_CXX_STANDARD 11)     #使用c11标准

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAIUI_LINUX")    #向源代码传递宏AIUI_LINUX

include_directories(${CMAKE_CURRENT_LIST_DIR}/../../include)    #设置头文件搜索目录
link_directories(${CMAKE_CURRENT_LIST_DIR}/../../libs/x64)      #设置库文件搜索目录

link_libraries(aiui -pthread msc rt dl asound)        #添加动态库

add_execute(${PROJECT_NAME}       #创建可执行程序awake_aiui
            src/FileUtil.cpp
            src/AIUITest.cpp
            src/demo.cpp
            src/jsoncpp/json_reader.cpp
            src/jsoncpp/json_value.cpp
            src/jsoncpp/json_writer.cpp
            src/linuxrec.c
            )

5、参考资料

1)CMakeLists.txt 语法介绍与实例演练_阿飞的博客-CSDN博客_cmakelist

2)ROS CMakelist.txt教程_LeonShen的博客-CSDN博客_cmakelists.txt 教程

3)CMake学习笔记二:cmake 常用变量和常用环境变量 - fengMisaka - 博客园 (cnblogs.com)

4)Cmake之深入理解find_package()的用法 - 知乎 (zhihu.com)

5)CMake命令之execute_process - 程序园 (voidcn.com)

6)cmake:option选项_OceanStar的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值