Cmake
CMake是很多项目首选的项目构建工具。其次,目前很多开发工具,比如VSCode,Clion都支持使用CMake构建项目。使用Cmake能够更加方便的用一个文件实现对C/C++项目的维护管理。
Cmake自带变量
CMAKE_C_STANDARD
:C语言标准版本1
set(CMAKE_C_STANDARD 11) #使用C11标准
CMAKE_CXX_FLAGS
:是 CMake 中用于设置C++
编译器选项的变量。这个变量允许你向C++
编译器传递额外的编译选项CMAKE_C_FLAGS
:是 CMake 中用于设置C
编译器选项的变量。这个变量允许你向C
编译器传递额外的编译选项1
2set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")
set(CMAKE_C_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")- $ENV{CXXFLAGS}: 这是从环境变量中获取 CXXFLAGS 的值,用于传递用户自定义的编译选项。
- rdynamic: 这个标志通常用于生成包含全局符号信息的可执行文件,以便在后期进行动态符号解析。
- O3: 启用较高级别的优化。
- fPIC: 生成位置独立的代码,通常用于共享库的构建。
- ggdb: 生成调试信息,以便在使用 GDB 进行调试时能够获取更多信息。
std=c++11
: 设置C++
标准为C++11
。- Wall: 启用警告信息。
- Wno-deprecated: 禁止关于已废弃特性的警告。
- Werror: 将警告视为错误,即编译过程中如果有警告会导致构建失败。
- Wno-unused-function: 禁止未使用的函数的警告。
- Wno-builtin-macro-redefined: 禁止宏被重新定义的警告。
- Wno-deprecated-declarations: 禁止有关已废弃声明的警告。
CMAKE_VERBOSE_MAKEFILE
:用于控制Makefile
的生成是否显示详细的构建信息。当CMAKE_VERBOSE_MAKEFILE
被设置为ON
时,Makefile
会生成更详细的构建信息,包括执行的编译命令等。当它被设置为OFF
时,则只显示较少的构建信息1
set(CMAKE_VERBOSE_MAKEFILE ON)
CMAKE_CURRENT_SOURCE_DIR
:CMakeLists.txt当前所在的文件路径。1
2#将 ${CMAKE_CURRENT_SOURCE_DIR}/cmake 添加到 CMAKE_MODULE_PATH 中,你可以告诉 CMake 在这个路径下查找自定义的 CMake 模块,以便在项目中使用这些模块。这对于引入额外的构建和配置逻辑非常有用
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
Cmake语句
- 命令:这里只介绍一些重要且常用的语句,Cmake命令大小写均支持,均能被识别,但是一般建议小写
- 变量:变量是区分大小写的,变量可以使用
set()
命令赋值,也可以当作参数传给命令
一些必备的Cmake命令
1 | cmake_minimum_required(VERSION 3.0) #设置cmake最低版本限制 |
option
option() 命令用于定义构建选项,允许用户在构建项目时选择是否启用某些特性。这样可以使得项目更加灵活,适应不同的需求: - <option_variable>
:定义的选项的变量名。 - "help string"
:对选项的描述,将会在 ccmake 或 cmake-gui 中显示给用户。 - [initial_value]
:可选参数,定义选项的初始值。
1 | option(<option_variable> "help string" [initial_value]) |
find_package
find_package
是 CMake 中用于查找第三方库的命令(查找原理配备第三方包.CMake
文件的查找路径而且,第三方包提供了合适的 .CMake
配置文件),当执行一个find_package
时会产生一系列变量,这里以find_package(MySQL,REQUIRED)
为例:
MYSQL_FOUND:
表示是否找到 MySQL。MYSQL_INCLUDE_DIR
: 包含 MySQL 头文件的路径。MYSQL_LIBRARY
: 包含 MySQL 库文件的完整路径。MYSQL_VERSION_STRING
: MySQL 版本的字符串表示。MYSQL_DEFINITIONS
: 包含 MySQL 定义的一系列标志。
执行完后,可以通过下述语句来引入一些头文件、库文件: 1
2
3
4
5
6
7find_package(MySQL REQUIRED)
if(MYSQL_FOUND)
include_directories(${MYSQL_INCLUDE_DIR})
target_link_libraries(your_target ${MYSQL_LIBRARY})
else()
message(FATAL_ERROR "MySQL not found!")
endif()
find_library
find_library
用于在系统上查找特定的库文件 1
2
3find_library(<VAR> name [path1 path2 ...])
#在这个例子中,CMake 将搜索名为 libexample.so 的库文件,如果找到,则将其完整路径存储在 MY_LIB 变量中。
find_library(MY_LIB libexample.so /path/to/custom/lib)
link_directories和target_link_directories
在 CMake 中,link_directories()
和 target_link_directories()
都用于指定链接器在链接阶段查找库文件的路径,即在Cmake添加相应的库文件搜索路径,但有一些关键的区别: - link_directories():
- 是一个全局命令,会影响整个 CMakeLists.txt 文件中的链接过程。 - 一旦调用,其作用范围延伸到后续的所有 target_link_libraries()
命令以及在该 CMakeLists.txt
文件中的所有目标。 - 不与具体目标关联,而是直接影响链接器在查找库文件时的路径。 1
2#将/path/to/libs加入到库文件搜索路径
link_directories(/path/to/libs)
target_link_directories():
- 与具体的目标关联,只会影响指定目标的链接过程。
- 可以在不同的目标上使用,每个目标可以指定自己的库文件查找路径,互不影响。
- 推荐使用 target_link_directories(),因为它更为精确,只影响指定目标的链接过程。
1
2#/path/to/libs加入到生成my_target_name时的库文件搜索路径
target_link_directories(my_target_name PUBLIC /path/to/libs) PUBLIC:
表示这个路径(属性)会传递给目标的依赖项PRIVATE
:表示这个路径(属性)不会传递给目标的依赖项
link_libraries和target_link_libraries
link_libraries
是一个在 CMake 中用于设置目标的链接库。它的作用是指定目标链接到的库,可以是库的名称或完整的路径。与target_link_libraries
不同它是全局的链接到整个项目,而target_link_libraries
指定了链接目标: 1
2
3
4
5
6
7
8
9project(Trluper)
#这句话表面pthread jsoncpp库文件会链接到整个项目
link_libraries(pthread jsoncpp)
add_executable(my_app main.cpp)
#指定连接目标
add_executable(my_app main.cpp)
target_link_libraries(my_app pthread jsoncpp)
inlcude_directories和target_inlcude_directories
include_directories
和 target_include_directories
都是 CMake 中用于指定头文件搜索路径的命令,但它们的作用范围不同。 1
2
3
4# 全局可见
include_directories(path1 path2 ...)
#指定目标可见
target_include_directories(target_name PRIVATE path1 path2 ...)
set
set命令用途广泛,用来设定一个变量的值 1
2
3
4
5
6set(<variable> <value>... [PARENT_SCOPE])
#将main.cc k.cc由SOURCED_DIR表示
set(SOURCE_DIR
main.cc
k.cc
)
add_library
add_library 是 CMake 中用于添加库的命令。它的基本语法如下: 1
2
3add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
1 | # 创建一个静态库 |
add_executable
于添加一个可执行文件的构建目标。语法如下: 1
2
3
4add_executable(<name> [source1] [source2 ...])
# 创建一个可执行文件
add_executable(my_executable main.cpp helper.cpp)
target_link-libraries(pthread my_shared_lib)
add_dependencies 命令
用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是 add_executable
、add_library
、add_custom_target
命令创建的目标 1
add_dependencies(target-name depend-target1 depend-target2 …)
message
用于输出信息 1
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] “message todisplay”…)
- (无) = 重要消息;
- STATUS = 非重要消息;
- WARNING = CMake 警告, 会继续执行;
- AUTHOR_WARNING = CMake 警告 (dev), 会继续执行;
- SEND_ERROR = CMake 错误, 继续执行,但是会跳过生成的步骤;
- FATAL_ERROR = CMake 错误, 终止所有处理过程;