CMake API使用指南

CMake(Cross-platform Make,跨平台构建)是一个跨平台的构建工具,用于管理项目的构建过程。它使用简单的配置文件(CMakeLists.txt)来生成本地化的构建文件,如 Makefile 或 Visual Studio 解决方案。

以下是 CMake 的基本语法和用法:

CMake 的基本语法和用法

1. CMakeLists.txt 基本结构

一个简单的 CMakeLists.txt 文件通常包含以下基本结构:

# 最小版本要求
cmake_minimum_required(VERSION 3.10)

# 项目名称
project(MyProject)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)

# 添加可执行文件或库的源文件
add_executable(MyExecutable main.cpp)

# 添加子目录,进入子目录继续构建
add_subdirectory(subdirectory_name)

2. 变量和宏

# 定义变量
set(SOURCES file1.cpp file2.cpp)

# 使用变量
add_executable(MyExecutable ${SOURCES})

# 定义宏
macro(my_macro arg1 arg2)
    # 宏体
    message("Arguments: ${arg1}, ${arg2}")
endmacro()

# 使用宏
my_macro(value1 value2)

3. 条件语句

# 条件语句
if(CONDITION)
    # 条件成立时执行的命令
elseif(ANOTHER_CONDITION)
    # 另一个条件成立时执行的命令
else()
    # 如果所有条件都不成立时执行的命令
endif()

4. 循环语句

# 循环语句
foreach(item IN LISTS my_list)
    # 循环体
    message(${item})
endforeach()

5. 定义和使用函数

# 定义函数
function(my_function arg1 arg2)
    # 函数体
    message("Arguments: ${arg1}, ${arg2}")
endfunction()

# 使用函数
my_function(value1 value2)

6. 导入库和链接库

# 导入库
find_library(MY_LIBRARY my_library)

# 链接库
target_link_libraries(MyExecutable ${MY_LIBRARY})

7. 设置编译器选项

# 设置编译器选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

# 或者
add_compile_options(-Wall)

message

message 命令用于在 CMake 构建过程中输出信息。它对于调试和显示构建脚本中的信息非常有用。基本语法如下:

message([<mode>] "message to display" ...)

其中:

  • <mode> 是可选的,用于指定消息的模式,可以是 STATUSWARNINGAUTHOR_WARNINGSEND_ERRORFATAL_ERRORDEPRECATION。如果省略 <mode>,则默认为 STATUS
  • "message to display" 是要显示的消息字符串。

以下是一些 message 命令的使用示例:

1. 显示普通消息:

message("This is a normal message.")

2. 显示带模式的消息:

message(STATUS "This is a status message.")
message(WARNING "This is a warning message.")
message(SEND_ERROR "This is an error message.")
message(FATAL_ERROR "This is a fatal error message.")

3. 显示变量值:

set(my_variable "Hello, CMake!")
message("Value of my_variable: ${my_variable}")

4. 显示多行消息:

message(STATUS "This is a multi-line message.\n"
        "It spans multiple lines.")

5. 显示条件消息:

if(MY_CONDITION)
    message("Condition is true.")
else()
    message("Condition is false.")
endif()

message 命令对于调试 CMakeLists.txt 文件和构建过程中的问题非常有帮助。通过在适当的位置添加消息,可以更容易地理解 CMake 脚本的执行过程,以及在构建时的一些关键信息。

set的常见用法

在 CMake 中,set 命令用于定义变量。这个命令的基本语法是:

set(variable_name value1 value2 ...)

其中,variable_name 是变量的名称,而 value1 value2 ... 是变量的值。可以通过空格分隔多个值。

以下是一些 set 命令的常见用法:

1. 简单的变量定义:

set(my_variable "Hello, CMake!")

2. 定义列表变量:

set(my_list_variable "item1" "item2" "item3")

3. 引用变量的值:

message("Value of my_variable: ${my_variable}")

4. 添加到已有变量:

set(my_variable "Hello")
set(my_variable "${my_variable}, CMake!")

5. 条件设置:

if(SOME_CONDITION)
    set(my_variable "Value1")
else()
    set(my_variable "Value2")
endif()

6. 缓存变量:

set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type (Debug/Release)" FORCE)

在这个例子中,CMAKE_BUILD_TYPE 是一个缓存变量,用于指定构建类型。FORCE 选项表示如果已经存在这个缓存变量,就覆盖它。

更多的使用场景和用法可以在CMake 官方文档中查看更详细的信息:

CMake - set Command

file

在 CMake 中,file 命令用于操作文件系统。这个命令有多个子命令,用于执行不同的文件操作。以下是一些常见的 file 命令的用法:

1. 复制文件

file(COPY source_file DESTINATION destination_directory)

这个命令用于将文件从一个位置复制到另一个位置。例如:

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

2. 创建目录

file(MAKE_DIRECTORY directory_path)

这个命令用于创建目录。例如:

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/my_directory)

3. 移动文件

file(RENAME old_name new_name)

这个命令用于移动或重命名文件。例如:

file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/file.txt ${CMAKE_CURRENT_BINARY_DIR}/new_file.txt)

4. 移除文件

file(REMOVE [files...])

这个命令用于移除文件。例如:

file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/unnecessary_file.txt)

5. 读取文件内容

file(READ filename variable)

这个命令用于读取文件的内容并存储到一个变量中。例如:

file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.txt VERSION)
message("Version: ${VERSION}")

6. 写入文件内容

file(WRITE filename content)

这个命令用于将指定的内容写入文件。例如:

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/output.txt "Hello, CMake!")

以上是 file 命令的一些常见用法,还有其他更多的子命令和选项,可以在 CMake 官方文档中查看更详细的信息:
CMake - file Command

add_library

在 CMake 中,add_library 命令用于定义和构建一个库。这个命令的基本语法如下:

add_library(<library_name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

其中:

  • <library_name> 是库的名称,可以在后续的 target_link_libraries 命令中使用这个名称引用这个库。
  • [STATIC | SHARED | MODULE] 用于指定库的类型,可以是静态库(STATIC,默认),共享库(SHARED),或模块库(MODULE)。
  • [EXCLUDE_FROM_ALL] 是一个可选项,如果指定了,将把这个库从构建过程的默认目标中排除。

以下是一些 add_library 命令的用法示例:

1. 添加静态库:

add_library(my_static_lib STATIC source1.cpp source2.cpp)

2. 添加共享库:

add_library(my_shared_lib SHARED source1.cpp source2.cpp)

3. 添加模块库:

add_library(my_module_lib MODULE source1.cpp source2.cpp)

4. 添加源文件到现有库:

add_library(my_static_lib STATIC source1.cpp)
add_library(my_shared_lib SHARED source2.cpp)

# 添加 source2.cpp 到 my_static_lib 和 my_shared_lib
target_sources(my_static_lib PRIVATE source2.cpp)
target_sources(my_shared_lib PRIVATE source2.cpp)

在上述示例中,my_static_libmy_shared_lib 是库的名称,source1.cppsource2.cpp 是库的源文件。

可以在 CMake 官方文档中查看更详细的信息:
CMake - add_library

add_subdirectory

add_subdirectory的使用

target_sources

target_sources 命令用于将源文件添加到一个已经存在的 CMake 目标(例如,可执行文件、库)。这个命令的基本语法如下:

target_sources(target_name
    PRIVATE source1 [source2 ...]
    PUBLIC source3 [source4 ...]
    INTERFACE source5 [source6 ...]
)
  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • PRIVATE, PUBLIC, 和 INTERFACE 是关键字,用于指定添加源文件的属性。

PRIVATE, PUBLIC, 和 INTERFACE 关键字分别表示:

  • PRIVATE: 源文件只会在目标的编译和链接阶段中可见,不会传递给依赖此目标的其他目标。
  • PUBLIC: 源文件会在目标的编译和链接阶段中可见,并且会传递给依赖此目标的其他目标。
  • INTERFACE: 源文件不会被添加到目标的编译和链接阶段中,但会传递给依赖此目标的其他目标。

以下是一些 target_sources 命令的使用示例:

# 添加私有源文件到目标
target_sources(my_executable PRIVATE source1.cpp source2.cpp)

# 添加公共源文件到目标
target_sources(my_library PUBLIC source3.cpp source4.cpp)

# 添加接口源文件到目标
target_sources(my_interface_library INTERFACE source5.cpp source6.cpp)

在上述示例中,my_executablemy_library、和 my_interface_library 是目标的名称,source1.cppsource6.cpp 是源文件的名称。

target_sources 命令使得在 CMakeLists.txt 文件中添加源文件更加灵活,可以将源文件与目标关联起来,而不是直接将它们列在 add_executableadd_library 命令中。这样可以更容易地组织代码,并且在不同目标之间共享源文件。

target_include_directories

target_include_directories 用于向一个目标(例如可执行文件或库)添加头文件目录。这个命令的基本语法如下:

target_include_directories(target_name
    [SYSTEM] [BEFORE]
    INTERFACE|PUBLIC|PRIVATE
    [items1...]
    [INTERFACE|PUBLIC|PRIVATE
    [items2]...]
)

其中:

  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • SYSTEM 关键字用于将目录标记为系统目录,通常用于禁止特定编译器的警告。
  • BEFORE 关键字用于将目录添加到当前目录列表的前面,而不是后面。

INTERFACE, PUBLIC, 和 PRIVATE 关键字的含义与 target_sources 中的相同:

  • INTERFACE: 目录不会被添加到目标的编译和链接阶段中,但会传递给依赖此目标的其他目标。
  • PUBLIC: 目录会在目标的编译和链接阶段中可见,并会传递给依赖此目标的其他目标。
  • PRIVATE: 目录只会在目标的编译和链接阶段中可见,不会传递给依赖此目标的其他目标。

以下是一些 target_include_directories 命令的使用示例:

# 添加私有头文件目录到目标
target_include_directories(my_executable PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)

# 添加公共头文件目录到目标
target_include_directories(my_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

# 添加接口头文件目录到目标
target_include_directories(my_interface_library INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)

在上述示例中,my_executablemy_librarymy_interface_library 是目标的名称,${CMAKE_CURRENT_SOURCE_DIR}/include 是头文件目录的路径。

target_include_directories 的主要目的是确保正确的头文件路径在编译和链接阶段中可用,并且能够传递给依赖此目标的其他目标。这有助于更好地组织项目中的头文件和确保正确的构建过程。

target_link_libraries

target_link_libraries 是 CMake 中的一个关键命令,用于指定一个目标(例如可执行文件或库)所依赖的其他库。这个命令的基本语法如下:

target_link_libraries(target_name
    item1
    item2
    ...
)

其中:

  • target_name 是目标的名称,可以是可执行文件或库的名称,由 add_executableadd_library 命令定义。
  • item1, item2, … 是目标所依赖的其他库或库的名称。

以下是一些 target_link_libraries 命令的使用示例:

1. 链接到其他库:

# 链接到名为 my_library 的库
target_link_libraries(my_executable my_library)

2. 链接到多个库:

# 链接到名为 my_library1 和 my_library2 的库
target_link_libraries(my_executable my_library1 my_library2)

3. 链接到系统库:

# 链接到系统库,例如 pthread
target_link_libraries(my_executable pthread)

4. 链接到第三方库:

# 链接到第三方库,例如 Boost
target_link_libraries(my_executable Boost::filesystem)

5. 链接到其他目标:

# 链接到另一个目标
target_link_libraries(my_executable my_other_target)

6. 指定链接选项:

# 指定链接选项
target_link_libraries(my_executable PRIVATE -Wl,-rpath,/custom/library/path)

上述示例中,my_executable 是目标的名称,my_library, my_library1, my_library2, pthread, Boost::filesystem, my_other_target 是目标依赖的库或目标。

target_link_libraries 命令用于确保在链接目标时正确地包含所需的库。这对于确保可执行文件或库在构建和运行时都能正确链接到依赖项非常重要。

PUBLIC关键字

下面以target_link_libraries 为例,分析PUBLIC关键字。

target_link_libraries 命令中的 PUBLIC 关键字用于指定库的依赖关系,并将这些依赖关系传递给依赖于当前目标的其他目标。用于确保在链接时包含正确的依赖项。

基本语法如下:

target_link_libraries(target_name
    PUBLIC item1
    PUBLIC item2
    ...
)

使用 PUBLIC 关键字的效果是,item1, item2, … 这些库将不仅会被链接到当前目标,还会传递给依赖于当前目标的其他目标。

示例:

# 定义一个库
add_library(my_library STATIC my_library.cpp)

# 定义一个可执行文件,链接到 my_library
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PUBLIC my_library)

示例中,my_executable 依赖于 my_library,而且 my_library 中的依赖项也会传递给 my_executable

使用 PUBLIC 关键字还允许在 INTERFACEPRIVATE 之间共享依赖关系。例如,PUBLIC 的依赖项既会被当前目标使用,也会被依赖于当前目标的其他目标使用。

参考

https://cmake.org/documentation/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林树杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值