0%

Cmake

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
    2
    set(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
2
3
4
5
6
cmake_minimum_required(VERSION 3.0)	#设置cmake最低版本限制
#项目名称
project(Trluper)

set(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")

option

option() 命令用于定义构建选项,允许用户在构建项目时选择是否启用某些特性。这样可以使得项目更加灵活,适应不同的需求: - <option_variable>:定义的选项的变量名。 - "help string":对选项的描述,将会在 ccmake 或 cmake-gui 中显示给用户。 - [initial_value]:可选参数,定义选项的初始值。

1
2
3
4
option(<option_variable> "help string" [initial_value])

#定义了一个名为 BUILD_SHARED_LIBS 的构建选项,用于控制是否构建共享库
option(BUILD_SHARED_LIBS "Build shared libraries" ON)

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
7
find_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
3
find_library(<VAR> name [path1 path2 ...])
#在这个例子中,CMake 将搜索名为 libexample.so 的库文件,如果找到,则将其完整路径存储在 MY_LIB 变量中。
find_library(MY_LIB libexample.so /path/to/custom/lib)

在 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 是一个在 CMake 中用于设置目标的链接库。它的作用是指定目标链接到的库,可以是库的名称或完整的路径。与target_link_libraries不同它是全局的链接到整个项目,而target_link_libraries指定了链接目标:

1
2
3
4
5
6
7
8
9
project(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_directoriestarget_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
6
set(<variable> <value>... [PARENT_SCOPE])
#将main.cc k.cc由SOURCED_DIR表示
set(SOURCE_DIR
main.cc
k.cc
)

add_library

add_library 是 CMake 中用于添加库的命令。它的基本语法如下:

1
2
3
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
- : 库的名称,后续可用于链接。 - [STATIC | SHARED | MODULE]: 可选项,指定库的类型。默认是 STATIC,可以选择 SHARED(共享库)或 MODULE(在支持的平台上创建动态模块)。 - [EXCLUDE_FROM_ALL]: 可选项,将库排除在所有构建目标之外。 - source1 [source2 ...]: 源文件列表,用于构建库

1
2
3
4
5
# 创建一个静态库
add_library(my_static_lib STATIC source1.cpp source2.cpp)

# 创建一个共享库
add_library(my_shared_lib SHARED source3.cpp source4.cpp)

add_executable

于添加一个可执行文件的构建目标。语法如下:

1
2
3
4
add_executable(<name> [source1] [source2 ...])
# 创建一个可执行文件
add_executable(my_executable main.cpp helper.cpp)
target_link-libraries(pthread my_shared_lib)

add_dependencies 命令

用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是 add_executableadd_libraryadd_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 错误, 终止所有处理过程;