跳转到内容
新建笔记

CMake

CMake 保姆级教程(上) | CMake 保姆级教程(下) | CMake官方教程 | Cmake中文实战教程 | Modern CMake 简体中文版 | vscode-cmake | Visual Studio 中的 CMake 项目

img
终端窗口
# cmake 构建方式1
cmake..
cmake -G Ninja ..

(1)project() 命令用于定义项目名称和语言,并且可以影响后续命令的行为,包括如何解析工具链文件。 这里是为什么 project() 应该在前的原因:

  1. 项目上下文:project() 命令初始化了项目上下文,包括项目名称和使用的语言。这为后续的命令提供了必要的上下文信息。
  2. 命令依赖:一些CMake命令可能依赖于项目命令设置的上下文。例如,某些命令可能需要知道项目名称或使用的编程语言。
  3. CMake模块和脚本:在project()之后调用的命令可以访问项目特定的变量和设置,这可能会影响到工具链文件的解析和应用。
  4. CMake缓存:project() 命令可能会影响CMake缓存的设置,这可能会间接影响工具链文件中的设置。
  5. CMake版本:从CMake 3.0开始,project() 命令提供了一种标准化的方式来设置项目信息,包括版本和所需的CMake版本。

(2)cmake关系

  1. 一个CMakeLists.txt,可以包含多个目标,多个目标可以独立,可以依赖,但是要保证依赖项先构建;
  2. target_source是朝目标中添加源文件,add_executable命令是用来创建一个新的可执行文件目标的,它需要至少一个源文件作为参数。然而,这并不意味着在add_executable命令执行后,就不能再向该目标添加源文件了。target_sources命令就是用来在add_executable或add_library命令之后,向已经创建的目标添加更多源文件的。这样做的好处是,你可以在多个地方添加源文件到同一个目标,而不需要一开始就知道所有的源文件。这对于大型项目或者源文件在多个目录中的项目非常有用。
阶段操作描述CMake代码示例
project()之前设置CMake最低版本要求cmake_minimum_required(VERSION 3.10)
定义宏和变量set(MY_VARIABLE "some_value")
设置CMake政策cmake_policy(SET CMP0054 NEW)
指定工具链文件set(CMAKE_TOOLCHAIN_FILE path/to/toolchain.cmake)
条件逻辑if(MY_CONDITION) ... endif()
project()之后定义项目信息project(MyProject VERSION 1.0 LANGUAGES CXX)
包含其他CMake文件或模块include(OtherCMakeFile)
定义源文件列表set(SOURCES main.cpp utils.cpp)
添加编译器定义add_definitions(-DDEBUG)
设置编译选项target_compile_options(my_target PRIVATE -Wall)
链接库到目标target_link_libraries(my_target some_library)
创建可执行文件或库add_executable(my_executable ${SOURCES})
设置目标属性set_target_properties(my_target PROPERTIES OUTPUT_NAME "my_output")
设置安装规则install(TARGETS my_executable RUNTIME DESTINATION bin)
添加测试enable_testing()
add_test(NAME MyTest COMMAND my_executable)
设置包信息set(CPACK_PACKAGE_VERSION "1.0.0")
配置文件生成configure_file(config.h.in config.h)
处理项目依赖项find_package(RequiredDependency REQUIRED)
自定义命令和规则add_custom_command(TARGET my_target POST_BUILD COMMAND ...)
设置CPack参数set(CPACK_GENERATOR "DEB")
使用project()设置的变量message(STATUS "Project version: ${PROJECT_VERSION}")

(2)指定编译器

# 设置C和C++编译器的路径
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/g++")

终端窗口
cmake -G "MinGW Makefiles" -DCMAKE_MAKE_PROGRAM="D:/program/MinGW/bin/make.exe" -S . -B build
`-G "MinGW Makefiles"`:这个选项告诉CMake使用MinGW Makefiles作为构建系统。
`-S`选项后面跟随的是源代码目录的路径 .
`-B`选项后面跟随的是构建目录的路径
命令说明代码示例
project()定义项目名称和所需的CMake最低版本。project(MyProject VERSION 1.0 LANGUAGES CXX)
cmake_minimum_required()指定工程需要的CMake的最低版本。cmake_minimum_required(VERSION 3.10)
add_executable()创建一个可执行文件目标。add_executable(my_executable main.cpp)
add_library()创建一个库目标。add_library(my_library STATIC my_library.cpp)
target_sources()向目标添加源文件。target_sources(my_executable PRIVATE source.cpp)
target_link_libraries()为目标链接库。target_link_libraries(my_executable PRIVATE my_library)
include_directories()添加头文件搜索路径。include_directories(include)
target_include_directories()为目标添加头文件搜索路径。target_include_directories(my_executable PUBLIC include)
file(GLOB...)收集与模式匹配的文件。file(GLOB SOURCES "*.cpp")
add_compile_options()为目标添加编译选项。add_compile_options(-Wall -Wextra)
set()设置变量的值。set(MY_VARIABLE "my_value")
list(append )
find_package()查找并加载外部依赖包的配置。find_package(Threads REQUIRED)
enable_language()启用一种编程语言。enable_language(CXX)
set_property()设置指定目标的属性。set_property(TARGET my_executable PROPERTY CXX_STANDARD 14)
add_custom_command()向目标添加自定义命令。add_custom_command(TARGET my_executable POST_BUILD COMMAND echo "Build finished")
add_custom_target()创建自定义目标。add_custom_target(my_custom_target COMMAND echo "Doing something")
install()定义如何安装目标或文件。install(TARGETS my_executable RUNTIME DESTINATION bin)
if(), elseif(), else()条件语句,用于基于条件执行不同的命令。if(MY_CONDITION) add_definitions(-DCONDITION_TRUE) endif()
configure_file()复制文件到另一个位置并替换变量。configure_file(config.h.in config.h @ONLY)
configure_file(${include} ${PROJECT_INCLUDE_DIR} COPYONLY)
execute_process()执行一个外部命令并捕获输出。execute_process(COMMAND ls OUTPUT_VARIABLE output)
变量名称详细说明
CMAKE_SOURCE_DIR指向包含顶层CMakeLists.txt的项目的源代码根目录。在项目中任何位置,这个变量都指向同一路径。
CMAKE_BINARY_DIR指向当前的构建(输出)目录,即执行CMake命令时所在的目录。
CMAKE_CURRENT_SOURCE_DIR指向当前正在处理的CMakeLists.txt文件所在的相对路径。用于确定当前子项目的源文件位置。
CMAKE_CURRENT_BINARY_DIR对应于CMAKE_CURRENT_SOURCE_DIR,但是是构建时的二进制目录。
PROJECT_SOURCE_DIR当使用project()命令定义项目时设置,指向项目的源代码根目录。
PROJECT_BINARY_DIR对应于PROJECT_SOURCE_DIR,但是是项目的构建目录。
CMAKE_CACHE包含CMake缓存的完整路径和文件名,这个缓存文件存储了所有变量的值和选项。
CMAKE_CACHE_DEFAULT_DIR存储CMake默认缓存的目录,通常在首次运行CMake时使用。
CMAKE_CACHE_FILE存储CMake缓存的文件名,默认为CMakeCache.txt。
CMAKE_COMMAND完整路径到CMake的可执行文件,可以用来在脚本中调用CMake本身。
CMAKE_CTEST_COMMAND路径到CTest工具,用于测试驱动。
CMAKE_MAKE_PROGRAM指定的make工具(如make或ninja)的完整路径。
CMAKE_PROJECT_NAMEproject()命令中定义的项目名称。
CMAKE_PROJECT_VERSIONproject()命令中定义的项目版本信息。
EXECUTABLE_OUTPUT_PATH指定所有添加的可执行文件的输出路径。可以通过set()命令在CMakeLists.txt中修改。
LIBRARY_OUTPUT_PATH指定所有添加的库文件的输出路径。可以通过set()命令在CMakeLists.txt中修改。
CMAKE_RUNTIME_OUTPUT_DIRECTORY包含所有运行时输出文件(如可执行文件和动态库)的基础目录。
CMAKE_LIBRARY_OUTPUT_DIRECTORY包含所有库输出文件(如静态库和动态库)的基础目录。
CMAKE_ARCHIVE_OUTPUT_DIRECTORY包含所有静态库输出文件的基础目录。
CMAKE_BUILD_TYPE指定当前选择的配置类型(如Debug、Release、RelWithDebInfo等)。
CMAKE_SYSTEM_NAME目标系统的名称,这可以影响CMake选择的文件和工具链。
CMAKE_SYSTEM_PROCESSOR目标系统的处理器名称,可以用来定制特定于处理器的构建选项。
CMAKE_SYSTEM一个包含系统名称和处理器的组合的字符串,用于指定目标系统。
CMAKE_C_COMPILER指定的C编译器的路径,如果没有指定,则使用CMake检测到的默认编译器。
CMAKE_CXX_COMPILER指定的C++编译器的路径,如果没有指定,则使用CMake检测到的默认编译器。
CMAKE_Fortran_COMPILER指定的Fortran编译器的路径,如果没有指定,则使用CMake检测到的默认编译器。
CMAKE_EXPORT_COMPILE_COMMANDS选项的作用是生成 compile_commands.json 文件,该文件包含了编译每个源文件的详细命令。这对使用一些需要了解编译细节的工具和 IDE(例如 Clang 静态分析工具或一些代码补全插件)非常有用
关键字作用域说明链接属性说明示例
PRIVATE私有:仅用于编译指定目标,不会传递给依赖该目标的其他目标。静态库:不导出任何符号。
动态库:不导出符号给依赖者。
target_sources(my_lib PRIVATE source_file.cpp)
PUBLIC公共:用于编译指定目标,同时传递给依赖该目标的其他目标。静态库:导出符号给依赖者。
动态库:导出符号给依赖者。
target_link_libraries(my_exe PUBLIC my_lib)
INTERFACE接口:不用于编译指定目标,但会传递给依赖该目标的其他目标。仅适用于动态库:导出符号给依赖者,但不链接库。target_link_libraries(my_exe INTERFACE my_lib)