参考视频教学:CMake 保姆级教程【C/C++】
编译过程
预处理(将.c .h文件展开)->编译(gcc g++)->汇编(.o .obj文件)->链接
CMake命令
cmake_minimum_required
指定使用的 cmake 的最低版本
cmake_minimum_required(VERSION 3.20.0)
project定义工程名称
定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言
project(micropython)
add_executable生成可执行程序
定义工程会生成一个可执行程序
add_executable(可执行程序名 源文件名称)
set用法
1.定义变量
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
VAR:变量名 VALUE:变量值
//解引用 ${变量名}
add_executable(app ${MICROPY_SOURCE_PORT})
set(MICROPY_SOURCE_PORT
main.c
help.c
machine_i2c.c
machine_spi.c
machine_pin.c
modbluetooth_zephyr.c
modsocket.c
modzephyr.c
modzsensor.c
mphalport.c
uart_core.c
zephyr_storage.c
)
2.指定使用的C++标准
#增加-std=c++11
set(CMAKE_CXX_STANDARD 11)
3.指定输出的路径
set(HOME /home/robin/Linux/Sort)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
4.字符串拼接
set(变量名1 ${变量名1} ${变量名2} ...)
搜索文件
aux_source_directory
aux_source_directory(< dir > < variable >)
dir:要搜索的目录
variable:将从dir目录下搜索到的源文件列表存储到该变量中
file
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。
GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。
file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
CMAKE_CURRENT_SOURCE_DIR和 PROJECT_SOURCE_DIR都代表当前CMake所在的路径
include_directories头文件路径
include_directories(headpath)
include_directories(${PROJECT_SOURCE_DIR}/include)
静态/动态库制作
区别:
Linux 静态库.a 动态库.so
windows 静态库.lib 动态库.du
在生成可执行文件时,静态库会打包进去可执行文件中,动态库则不会,并且可执行文件在运行时会加载静态库到内存中,而动态库则是在需要的时候才会被加载。
add_library(库名称 STATIC 源文件1 [源文件2] ...)
add_library(库名称 SHARED 源文件1 [源文件2] ...)
指定输出的路径
只适用动态库
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
都适用
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
链接库
指定静态库的路径link_directories
link_directories(<lib path>)
如果该静态库不是系统提供的(自己制作或者使用第三方提供的静态库)可能出现静态库找不到的情况,此时可以将静态库的路径也指定出来
# 包含头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 包含静态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 链接静态库
link_libraries(calc)
链接静态库link_libraries
link_libraries(<static lib> [<static lib>...])
参数1:指定出要链接的静态库的名字
可以是全名 libxxx.a
也可以是掐头(lib)去尾(.a)之后的名字 xxx
参数2:要链接的其它静态库的名字
链接动态库 target_link_libraries
target_link_libraries(
<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
target:指定要加载动态库的文件的名字该文件可能是一个源文件
该文件可能是一个动态库文件
该文件可能是一个可执行文件
PRIVATE|PUBLIC|INTERFACE:动态库的访问权限,默认为PUBLIC如果各个动态库之间没有依赖关系,无需做任何设置,三者没有没有区别,一般无需指定,使用默认的 PUBLIC 即可。
一般放在add_executable(app ${SRC_LIST})生成可执行程序后面
# 添加并生成一个可执行程序 add_executable(app ${SRC_LIST}) # 指定要链接的动态库 target_link_libraries(app pthread calc)
message日志输出
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
(无) :重要消息
STATUS :非重要消息
WARNING:CMake 警告, 会继续执行
AUTHOR_WARNING:CMake 警告 (dev), 会继续执行
SEND_ERROR:CMake 错误, 继续执行,但是会跳过生成的步骤
FATAL_ERROR:CMake 错误, 终止所有处理过程
# 输出一般日志信息
message(STATUS "source path: ${PROJECT_SOURCE_DIR}")
# 输出警告信息
message(WARNING "source path: ${PROJECT_SOURCE_DIR}")
# 输出错误信息
message(FATAL_ERROR "source path: ${PROJECT_SOURCE_DIR}")
字符操作list
更多API 参考官方文档CMake官方文档
1.字符串拼接
list(APPEND <list> [<element> ...])
2. 字符串移除
list(REMOVE_ITEM <list> <value> [<value> ...])
3. 列表排序
list (SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
COMPARE:指定排序方法。有如下几种值可选:
STRING:按照字母顺序进行排序,为默认的排序方法
FILE_BASENAME:如果是一系列路径名,会使用basename进行排序
NATURAL:使用自然数顺序排序
CASE:指明是否大小写敏感。有如下几种值可选:
SENSITIVE: 按照大小写敏感的方式进行排序,为默认值
INSENSITIVE:按照大小写不敏感方式进行排序
ORDER:指明排序的顺序。有如下几种值可选:
ASCENDING:按照升序排列,为默认值
DESCENDING:按照降序排列
宏定义
1.在命令行添加
$ gcc test.c -DDEBUG -o app
2.在编译时添加
add_definitions(-D宏名称)