CMake语法入门篇
一、CMake是什么?
1. CMake, make, CMakeLists.txt, CMakeFiles的关系
-
make:make是一个构建工具,用于根据makefile规则自动化构建项目。它读取一个名为makefile的文件,其中包含用于编译和链接项目的规则和依赖关系。使用make命令,可以基于makefile文件对项目进行编译、链接和执行操作,以及管理代码库中的依赖关系。
-
CMake:CMake是一个跨平台的构建工具,用于自动生成用于不同编译系统的构建脚本(例如makefile或Visual Studio项目文件)。它提供了一种简化跨平台构建过程的方法,使开发人员能够在各种操作系统和编译器上进行开发和构建。
-
CMakeLists.txt:CMakeLists.txt是CMake的输入文件,它用于描述如何构建项目。这个文件通常位于项目的根目录中,并指定了要执行的操作、要构建的源文件、依赖项和其他与构建相关的设置。CMake会读取CMakeLists.txt文件,并生成适用于特定构建系统(如makefile)的构建规则。
-
CMakeFiles:CMake生成的构建系统文件(如makefile)的输出目录通常被称为CMakeFiles目录。这个目录包含了CMake生成的用于构建项目的文件,包括编译命令、链接命令和其他与构建相关的文件。
CMake官方地址:https://cmake.org/cmake/help/latest/index.html
二、快速入门
简单示例
# 设置CMake的最低版本
cmake_minimum_required(VERSION 3.17)
# 强依赖 C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 项目信息
project(test_logger)
set(PROJECT_SOURCE_DIR "../../")
# 设置编译选项
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -g")
# 导入文件
include_directories("${PROJECT_SOURCE_DIR}/src/")
include_directories("${PROJECT_SOURCE_DIR}/include/")
aux_source_directory("${PROJECT_SOURCE_DIR}/src/" SRC_LIST)
# 生成可执行文件
add_executable(test_logger test_logger.cpp ${SRC_LIST})
# 添加依赖库
target_link_libraries(test_logger pthread)
三、Cmake语法篇
官方地址:https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html
1. 常用宏变量
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 # 目标链接库文件的存放位置
2. 脚本命令
2.1 注释
# 这是一个注释
#[[ 这里面是多行注释 ]]
2.2 变量
Setting
set(VARIABLE_NAME value)
Reading
set(SOURCE_FILES main.cpp)
message("Source files: ${SOURCE_FILES}") # 输出:Source files: main.cpp
Unset
# Unset a variable, cache variable, or environment variable.
unset(<variable> [CACHE | PARENT_SCOPE])
2.3 列表
Reading
list(LENGTH <list> <out-var>)
list(GET <list> <element index> [<index> ...] <out-var>)
list(JOIN <list> <glue> <out-var>)
list(SUBLIST <list> <begin> <length> <out-var>)
Search
list(FIND <list> <value> <out-var>)
Modification
list(APPEND <list> [<element>...])
list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)
list(INSERT <list> <index> [<element>...])
list(POP_BACK <list> [<out-var>...])
list(POP_FRONT <list> [<out-var>...])
list(PREPEND <list> [<element>...])
list(REMOVE_ITEM <list> <value>...)
list(REMOVE_AT <list> <index>...)
list(REMOVE_DUPLICATES <list>)
list(TRANSFORM <list> <ACTION> [...])
Ordering
list(REVERSE <list>)
list(SORT <list> [...])
2.4 条件语句
if(CONDITION)
# ...
elseif(OTHER_CONDITION)
# ...
else()
# ...
endif()
2.5 循环语句
foreach(item IN LISTS some_list)
# ...
endforeach()
2.6 函数
function(FUNCTION_NAME arg1 arg2)
# ...
endfunction()
2.7 宏
macro(<name> [<arg1> ...])
#...
endmacro()
2.8 依赖版本
cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])
2.9 导入
include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>] [NO_POLICY_SCOPE])
include_guard([DIRECTORY|GLOBAL])
3. 项目命令
2.1 项目信息
# Set the name of the project.
project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
[DESCRIPTION <project-description-string>]
[HOMEPAGE_URL <url-string>]
[LANGUAGES <language-name>...])
# Sets the name of the project, and stores it in the variable PROJECT_NAME. When called from the top-level CMakeLists.txt also stores the project name in the variable CMAKE_PROJECT_NAME.
2.2 宏定义
# 全局添加宏定义:Add -D define flags to the compilation of source files.
add_definitions(-DFOO -DBAR ...)
# 当前make文件添加宏定义:Add preprocessor definitions to the compilation of source files.
add_compile_definitions(<definition> ...)
# 移除宏定义:Remove -D define flags added by add_definitions().
remove_definitions(-DFOO -DBAR ...)
2.3 添加编译选项
# Add options to the compilation of source files.
add_compile_options(<option> ...)
示例:
add_compile_options(-Wall -Wextra -Wpedantic)
2.4 添加子目录
# Add a subdirectory to the build.
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
2.5 添加头文件目录
# Add include directories to the build.
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
2.6 遍历源文件,并保存到列表
# Find all source files in a directory.
aux_source_directory(<dir> <variable>)
# Collects the names of all the source files in the specified directory and stores the list in the <variable> provided
2.7 生成库
# Add a library to the project using the specified source files.
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
2.8 生成可执行文件
# Add an executable to the project using the specified source files.
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
2.9 添加链接库
# Specify libraries or flags to use when linking a given target and/or its dependents.
target_link_libraries(<target> ... <item>... ...)
2.10 添加链接库的目录
# Add link directories to a target.
target_link_directories(<target> [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# Specifies the paths in which the linker should search for libraries when linking a given target.
2.11 安装规则
# Specify rules to run at install time.
install(TARGETS <target>... [...])
install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])
install(RUNTIME_DEPENDENCY_SET <set-name> [...])
# This command generates installation rules for a project. Install rules specified by calls to the install() command within a source directory are executed in order during installation.
2.12 字符串处理
Search and Replace
string(FIND <string> <substring> <out-var> [...])
string(REPLACE <match-string> <replace-string> <out-var> <input>...)
string(REGEX MATCH <match-regex> <out-var> <input>...)
string(REGEX MATCHALL <match-regex> <out-var> <input>...)
string(REGEX REPLACE <match-regex> <replace-expr> <out-var> <input>...)
Manipulation
string(APPEND <string-var> [<input>...])
string(PREPEND <string-var> [<input>...])
string(CONCAT <out-var> [<input>...])
string(JOIN <glue> <out-var> [<input>...])
string(TOLOWER <string> <out-var>)
string(TOUPPER <string> <out-var>)
string(LENGTH <string> <out-var>)
string(SUBSTRING <string> <begin> <length> <out-var>)
string(STRIP <string> <out-var>)
string(GENEX_STRIP <string> <out-var>)
string(REPEAT <string> <count> <out-var>)
Comparison
string(COMPARE <op> <string1> <string2> <out-var>)
Hashing
string(<HASH> <out-var> <input>)
Generation
string(ASCII <number>... <out-var>)
string(HEX <string> <out-var>)
string(CONFIGURE <string> <out-var> [...])
string(MAKE_C_IDENTIFIER <string> <out-var>)
string(RANDOM [<option>...] <out-var>)
string(TIMESTAMP <out-var> [<format string>] [UTC])
string(UUID <out-var> ...)
JSON
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
{GET | TYPE | LENGTH | REMOVE}
<json-string> <member|index> [<member|index> ...])
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
MEMBER <json-string>
[<member|index> ...] <index>)
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
SET <json-string>
<member|index> [<member|index> ...] <value>)
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
EQUAL <json-string1> <json-string2>)