1、定义
CMALKE是一款开源的跨平台构建系统,这个名字是"Cross platform Make"的缩写。其工作依赖于CMakeLists.txt文件,通过该文件生成不同平台下对应的构建体。
1)构建
- Xcode
cmake .. -G "Xocde"
- Visual Studio
cmake .. -G "Visual Studio 2019 Win64"
- Linux
cmake ..
2)平台区分
跨平台构建时可从一下预定义区分编译环境:
| 目标平台 | 宏 CMAKE_SYSTEM_NAME |
|---|---|
| windows | Windows |
| linux | Linux |
| mac | Darwin |
| 目标处理器 | 宏 CMAKE_HOST_SYSTEM_PROCESSOR |
|---|---|
| x86 | x86_64 |
| ARM | arm64 |
2、常用选项
1)设置项目名称
project(<project-name>)
cmake会将设置的变量存入PROJECT_NAME与CMAKE_PROJECT_NAME中。后续可以使用${PROJECT_NAME}或${CMAKE_PROJECT_NAME}调用。
2)包含源文件
aux_source_directory(<dir> <variable>)
将目录dir中的文件名,全部存入variable中。(这里不会递归调用子目录)
例:
aux_source_directory(./BBEncoder/src DIR_SRCS)
3) 包含头文件
file(GLOB_RECURSE <variable> [RELATIVE <path>] [<globbing-expressions>...] )
从源文件树收集文件列表,写入变量variable中。GLOB_RECURSE 将会递归所有匹配文件夹的子文件夹和匹配的文件。
source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])
source_group() 用于定义生成 IDE 工程时的源码分组。
例:
file(GLOB_RECURSE CURRENT_HEADERS ./BBEncoder/include/*.h ./BBEncoder/include/*.hpp)
source_group("Header Files" FILES ${CURRENT_HEADERS})
4) 指定生成目标
add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL]
[source1] [source2 ...])
使用指定的源文件将可执行文件添加到项目中,只有在 add_executable() 中的文件才会被 source_group 分组。
例:
add_executable(${PROJECT_NAME} ${DIR_SRCS} ${CURRENT_HEADERS})
5)指定安装路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
//或
set(RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
6)设置编译属性
//debug
set(CMAKE_BUILD_TYPE "debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -std=c++11 -Wall -g -ggdb")
//release
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -std=c++11 -Wall -O2")
3、添加外部库
当添加外部库时,程序的编译构建需要以下信息:
- 外部库的头文件(*.h)
- 函数库的动态/静态链接文件(.so、.dylib、.dll、.lib)
- 函数库名
1)指定头文件目录
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
2) 链接库文件
target_link_libraries(<target> ... <item>... ...)
这里需要区分链接路径和运行路径:连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径。
cmake设定link_directories添加链接器查找库的目录:
link_directories([AFTER|BEFORE] directory1 [directory2 ...])
cmake设定rpath:
set(INSTALL_LIB_DIR "${PROJECT_BINARY_DIR}/lib") # 假设安装目录在编译目录的lib子目录内
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
2) 查找系统自带的库
系统自带的库的安装路径,在不同的机器上可能不同,使用cmake的find_package可自动搜索该路径。
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
以查找JPEG为例,系统如果找到了JPEG模块,那么cmake会设置以下变量供CMakeLists.txt使用:
JPEG_FOUND #为true
JPEG_INCLUDE_DIRS #include路径
JPEG_LIBRARY_DIRS #library路径
JPEG_LIBRARIES #library的名字