当前位置: 首页 > news >正文

CMake常用命令指南(CMakeList.txt)

CMakeList从入门到精通的文章有很多不再赘述( 此处附带一篇优秀的博文链接:一个简单例子,完全入门CMake语法与CMakeList编写 )。

本文主要列举 CMake 中常用命令的详细说明、优缺点分析以及推荐做法,以更好地理解和灵活使用这些命令。

目录

1. 版本控制

cmake_minimum_required

2. 项目定义project

3. 指定源文件

set

AUX_SOURCE_DIRECTORY

file(GLOB)

4. 指定头文件路径

include_directories

target_include_directories

5. 指定库文件路径

6. 链接库文件

7. 编译选项

add_compile_options

target_compile_options

8.构建子目录

add_subdirectory

9.定义可执行文件

add_executable

10.定义库文件目标

add_library

11.为目标添加编译定义

target_compile_definitions

12.定义可配置选项

option

13.输出消息到控制台

message

14.PUBLIC、PRIVATE 和 INTERFACE 关键字

PUBLIC:

PRIVATE:

INTERFACE:

总结

15设置target属性 SET_TARGET_PROPERTIES

16.文件安装INSTALL

语法:

说明:

一些用法举例:

17.CMake常用路径说明

核心安装路径变量:

构建路径相关变量:

其他常用路径变量:

修改安装路径:

注意:


1. 版本控制

cmake_minimum_required

  • 功能: 指定 CMake 的最低版本要求。
  • 优点:
    • 确保项目使用的 CMake 版本满足要求,避免因版本不兼容导致的问题。
  • 缺点:
    • 无明显缺点。
  • 推荐做法:
    • 始终在 CMakeLists.txt 的开头添加此命令,并使用项目所需的最低版本。
    • 示例:
cmake_minimum_required(VERSION 3.15)

2. 项目定义project

project(<PROJECT-NAME> [LANGUAGES] [C] [CXX] [Fortran] ...)
  • 功能:定义项目名称和使用的编程语言。
  • 优点
    • 自动设置一些默认变量(如 PROJECT_NAMEPROJECT_SOURCE_DIR 等)。
    • 支持多语言项目。
  • 缺点
    • 如果未指定语言,CMake 会默认启用所有支持的语言,可能导致不必要的配置。
  • 推荐做法
    • 明确指定项目名称和语言。
    • 示例
      project(MyProject LANGUAGES C CXX)

3. 指定源文件

set

set(<variable> <value>)
  • 功能:定义变量并赋值,常用于指定源文件列表。
  • 优点
    • 简单直观,适合手动指定源文件。
  • 缺点
    • 需要手动维护源文件列表,容易遗漏或重复。
  • 推荐做法
    • 适用于小型项目或源文件数量较少的情况。
    • 示例:
set(SRC_FILES main.cpp utils.cpp)

AUX_SOURCE_DIRECTORY

AUX_SOURCE_DIRECTORY(<dir> <variable>)
  • 功能:自动扫描指定目录下的源文件并存储到变量中。
  • 优点
    • 自动收集源文件,减少手动维护的工作量。
  • 缺点
    • 无法过滤特定文件类型,可能包含不需要的文件。
    • 不推荐在现代 CMake 中使用。
  • 推荐做法
    • 适用于快速原型开发,但不推荐用于正式项目。
    • 示例:
AUX_SOURCE_DIRECTORY(../src SRC_MAIN)
AUX_SOURCE_DIRECTORY(../src/client SRC_CL)
AUX_SOURCE_DIRECTORY(../src/server SRC_SR)
AUX_SOURCE_DIRECTORY(../src/utils SRC_UTILS)

file(GLOB)

file(GLOB <variable> <pattern>)
  • 功能:通过通配符匹配文件并存储到变量中。
  • 优点
    • 灵活,支持通配符匹配。
  • 缺点
    • 不会自动检测新增或删除的文件,可能导致构建系统不一致。
  • 推荐做法
    • 适用于动态生成文件或快速原型开发,但不推荐用于正式项目。
    • 示例:
file(GLOB SRC_FILES "src/*.cpp")
FILE(GLOB scripts sh/*.sh)
INSTALL(FILES ${scripts}DESTINATION share/scripts
)

4. 指定头文件路径

include_directories

include_directories([AFTER|BEFORE] [SYSTEM] <dir1> <dir2> ...)
  • 功能:全局添加头文件搜索路径。
  • 优点
    • 简单易用,适用于小型项目。
  • 缺点
    • 全局生效,可能导致命名冲突或污染。
  • 推荐做法
    • 适用于小型项目或快速原型开发。
    • 示例:
include_directories(include)
include_directories(../libs/include)

target_include_directories

  • 功能:为目标添加头文件搜索路径。
  • 优点
    • 模块化设计,只对指定目标生效。
    • 支持 PUBLICPRIVATE 和 INTERFACE 关键字,控制依赖传递。
  • 缺点
    • 需要明确指定目标,稍微复杂。
  • 推荐做法
    • 推荐用于现代 CMake 项目。
    • 示例:
target_include_directories(MyTarget PUBLIC include)

5. 指定库文件路径

link_directories(<dir1> <dir2> ...)
  • 功能:全局添加库文件搜索路径。
  • 优点
    • 简单易用,适用于小型项目。
  • 缺点
    • 全局生效,可能导致命名冲突或污染。
  • 推荐做法
    • 适用于小型项目或快速原型开发。
    • 示例:
link_directories(lib)
  • 功能:为目标添加库文件搜索路径。
  • 优点
    • 模块化设计,只对指定目标生效。
    • 支持 PUBLICPRIVATE 和 INTERFACE 关键字,控制依赖传递。
  • 缺点
    • 需要明确指定目标,稍微复杂。
  • 推荐做法
    • 推荐用于现代 CMake 项目。
    • 示例:
target_link_directories(MyTarget PUBLIC lib)

6. 链接库文件

  • 功能:全局链接库文件。
  • 优点
    • 简单易用,适用于小型项目。
  • 缺点
    • 全局生效,可能导致命名冲突或污染。
  • 推荐做法
    • 适用于小型项目或快速原型开发。
    • 示例:
link_libraries(mylib)
target_link_libraries(<target> [<lib1> <lib2> ...])
  • 功能:为目标链接库文件。
  • 优点
    • 模块化设计,只对指定目标生效。
    • 支持 PUBLICPRIVATE 和 INTERFACE 关键字,控制依赖传递。
  • 缺点
    • 需要明确指定目标,稍微复杂。
  • 推荐做法
    • 推荐用于现代 CMake 项目。
    • 示例:
target_link_libraries(MyTarget PUBLIC mylib)

7. 编译选项

add_compile_options

add_compile_options(<option1> <option2> ...)
  • 功能:全局添加编译选项。
  • 优点
    • 简单易用,适用于小型项目。
  • 缺点
    • 全局生效,可能导致不必要的选项传递。
  • 推荐做法
    • 适用于小型项目或快速原型开发。
    • 示例:
add_compile_options(-Wall -Wextra)

target_compile_options

target_compile_options(<target> [BEFORE] <INTERFACE|PUBLIC|PRIVATE> <option1> <option2> ...)
  • 功能:为目标添加编译选项。
  • 优点
    • 模块化设计,只对指定目标生效。
    • 支持 PUBLICPRIVATE 和 INTERFACE 关键字,控制依赖传递。
  • 缺点
    • 需要明确指定目标,稍微复杂。
  • 推荐做法
    • 推荐用于现代 CMake 项目。
    • 示例:
target_compile_options(MyTarget PRIVATE -Wall -Wextra)

8.构建子目录

add_subdirectory

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
  • 功能:将子目录添加到构建过程中。
  • 优点:
    • 支持模块化项目结构,将代码组织成多个子目录。
    • 允许在子目录中定义独立的构建规则。
    • 可以使用 EXCLUDE_FROM_ALL 参数来排除子目录,使其不参与默认的构建过程。
  • 缺点:
    • 子目录中的 CMakeLists.txt 文件会影响父目录的构建,需要注意作用域。
    • 如果子目录的构建规则不正确,可能会导致整个构建失败。
  • 推荐做法:
    • 将相关的代码组织到子目录中,提高代码的可维护性。
    • 在子目录中编写独立的 CMakeLists.txt 文件,定义子目录的构建规则。
    • 避免在子目录中修改父目录的变量或目标,除非有明确的需求。
    • 尽量使用相对路径来引用子目录。
    • 示例:
add_subdirectory(src/mylib)
add_subdirectory(test test_build)

9.定义可执行文件

add_executable

add_executable(target [source1] [source2] [...])
  • 作用: 将子目录添加到构建过程中。
  • 优点:
    • 定义可执行文件的构建规则。
    • 可以指定源文件列表。
    • 可以使用 WIN32 和 MACOSX_BUNDLE 参数来创建特定平台的应用程序。
  • 缺点:
    • 需要手动指定源文件列表,如果源文件较多,可能会比较繁琐。
  • 推荐做法:
    • 使用 file(GLOB) 或 file(GLOB_RECURSE) 来自动查找源文件。
    • 将源文件组织到不同的目录中,提高代码的可维护性。
    • 使用 target_link_libraries 来链接库文件。
    • 示例:
add_executable(my_app src/main.cpp src/utils.cpp)

10.定义库文件目标

add_library

add_library(target [STATIC|SHARED|MODULE] [source1] [source2] [...])
  • 优点:
    • 定义库文件的构建规则。
    • 可以指定库的类型(静态库、动态库、模块库)。
    • 可以指定源文件列表。
  • 缺点:
    • 需要手动指定源文件列表,如果源文件较多,可能会比较繁琐。
  • 推荐做法:
    • 使用 file(GLOB) 或 file(GLOB_RECURSE) 来自动查找源文件。
    • 将源文件组织到不同的目录中,提高代码的可维护性。
    • 使用 target_include_directories 来指定头文件搜索路径。
    • 使用 target_link_libraries 来链接其他库文件。
    • 示例:
add_library(mylib SHARED src/mylib.cpp src/mylib_utils.cpp)
add_library(mylib_static STATIC src/mylib.cpp src/mylib_utils.cpp)

11.为目标添加编译定义

target_compile_definitions

target_compile_definitions(<目标名> [INTERFACE | PUBLIC | PRIVATE] <定义1> <定义2> ...
  • 优点:
    • 可以为目标添加编译定义,用于控制编译行为。
    • 可以使用 INTERFACEPUBLIC 和 PRIVATE 参数来控制定义的可见性。
  • 缺点:
    • 如果定义过多,可能会使代码难以理解。
  • 推荐做法:
    • 使用有意义的定义名称,提高代码的可读性。
    • 使用 INTERFACEPUBLIC 和 PRIVATE 参数来控制定义的可见性,避免定义冲突。
    • 尽量使用 option 命令来定义编译选项,而不是直接使用编译定义。
    • 示例
target_compile_definitions(my_app PRIVATE DEBUG_MODE)
target_compile_definitions(mylib PUBLIC MY_LIB_VERSION="1.0.0")

12.定义可配置选项

option

option(<选项名> "<描述>" [ON|OFF])
  • 优点:
    • 可以定义可配置的选项,允许用户在构建时选择不同的配置。
    • 可以使用 ON 和 OFF 参数来设置默认值。
    • 可以使用 if 语句来根据选项的值执行不同的操作。
  • 缺点:
    • 需要手动处理选项的值,例如使用 if 语句。
  • 推荐做法:
    • 使用有意义的选项名称,提高代码的可读性。
    • 为选项提供详细的描述,方便用户理解选项的作用。
    • 使用 if 语句来根据选项的值执行不同的操作。
    • 尽量使用 option 命令来定义编译选项,而不是直接使用编译定义。
    • 示例:
option(ENABLE_DEBUG "Enable debug mode" OFF)
if(ENABLE_DEBUG)message(STATUS "Debug mode is enabled")target_compile_definitions(my_app PRIVATE DEBUG_MODE)
endif()

13.输出消息到控制台

message

message([STATUS|WARNING|AUTHOR_WARNING|SEND_ERROR|FATAL_ERROR] "消息内容")
  • 优点:
    • 可以输出不同级别的消息,方便调试和跟踪构建过程。
    • 可以使用 STATUSWARNINGAUTHOR_WARNINGSEND_ERROR 和 FATAL_ERROR 参数来指定消息的级别。
  • 缺点:
    • 消息输出过多可能会影响构建速度。
  • 推荐做法:
    • 使用 STATUS 级别来输出构建过程中的信息。
    • 使用 WARNING 级别来输出警告信息。
    • 使用 FATAL_ERROR 级别来输出错误信息,并终止构建过程。
    • 避免输出过多的消息,以免影响构建速度。
    • 示例:
message(STATUS "Building project...")
message(WARNING "This is a warning message")
message(FATAL_ERROR "An error occurred")

14.PUBLICPRIVATE 和 INTERFACE 关键字

在 CMake 中,PUBLICPRIVATEINTERFACE 关键字用于控制目标属性的可见性和传播。这些关键字主要用于 target_include_directories()target_compile_definitions()target_link_libraries() 等命令中。

PUBLIC:

  • 当一个目标使用 PUBLIC 关键字时,该目标的属性(包括头文件路径、编译定义和链接库)会被传播到依赖它的其他目标。
add_library(mylib STATIC mylib.cpp)
target_include_directories(mylib PUBLIC include)

在这种情况下,任何链接到 mylib 的目标都会继承 include 目录作为其头文件搜索路径。

PRIVATE:

  • 当一个目标使用 PRIVATE 关键字时,该目标的属性只会应用于该目标本身,不会传播到依赖它的其他目标。
    add_library(mylib STATIC mylib.cpp)
    target_include_directories(mylib PRIVATE include)
    

    在这种情况下,只有 mylib 自身会使用 include 目录作为头文件搜索路径,而依赖 mylib 的其他目标不会继承这个路径。

INTERFACE:

  • 当一个目标使用 INTERFACE 关键字时,该目标的属性不会应用于该目标本身,而是会传播到依赖它的其他目标。
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include)

在这种情况下,任何链接到 mylib 的目标都会继承 include 目录作为其头文件搜索路径,但 mylib 本身并不使用这个路径。

总结

  • PRIVATE:仅对当前目标有效。
  • PUBLIC:对当前目标和所有依赖于该目标的目标有效。
  • INTERFACE:对当前目标无效,仅对依赖于该目标的目标有效。

通过合理使用这三个关键字,可以更好地管理目标之间的依赖关系和可见性,从而提高项目的可维护性和可重用性。

15设置target属性 SET_TARGET_PROPERTIES

SET_TARGET_PROPERTIES 是 CMake 中一个非常重要的命令,用于设置目标(target)的属性。目标可以是可执行文件、库、自定义命令等。通过 SET_TARGET_PROPERTIES,你可以控制目标的各种行为和特性,例如:

主要作用:

  1. 配置目标的构建过程:

    • 输出路径: 指定生成的可执行文件或库的输出目录。
    • 文件名: 修改生成的文件名。
    • 链接库: 指定目标需要链接的库。
    • 编译选项: 添加或修改编译器的选项。
    • 链接选项: 添加或修改链接器的选项。
    • 预处理器定义: 定义预处理器宏。
    • 包含目录: 指定头文件的搜索路径。
    • 源文件: 添加或删除源文件。
  2. 控制目标的行为:

    • 类型: 设置目标的类型(例如,EXECUTABLESHARED_LIBRARYSTATIC_LIBRARY)。
    • 安装规则: 定义如何安装目标。
    • 依赖关系: 指定目标依赖的其他目标。
    • 调试信息: 控制是否生成调试信息。
    • 运行时库: 指定运行时库的类型。
  3. 提供元数据:

    • 版本信息: 设置目标的版本号。
    • 描述信息: 提供目标的描述。
    • 自定义属性: 添加自定义的属性,供其他 CMake 代码使用。
SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIESproperty1 value1property2 value2...
)
  • target1 target2 ...: 要设置属性的目标列表。
  • PROPERTIES: 关键字,表示接下来是属性列表。
  • property1 value1: 要设置的属性及其对应的值。

常用属性示例:

  • OUTPUT_NAME: 指定输出文件名(不包含扩展名)。
  • OUTPUT_DIRECTORY: 指定输出目录。
  • PREFIX: 指定输出文件名的前缀。
  • SUFFIX: 指定输出文件名的后缀。
  • COMPILE_DEFINITIONS: 定义预处理器宏。
  • COMPILE_OPTIONS: 添加编译选项。
  • INCLUDE_DIRECTORIES: 指定头文件搜索路径。
  • LINK_DIRECTORIES: 指定库文件搜索路径。
  • LINK_LIBRARIES: 指定需要链接的库。
  • RUNTIME_OUTPUT_DIRECTORY: 指定运行时输出目录(例如,DLL)。
  • VERSION: 设置目标的版本号。
  • SOVERSION: 设置共享库的 SOVERSION。
  • INSTALL_NAME_DIR: 设置 macOS 上的安装名称目录。
  • DEBUG_POSTFIX: 设置调试版本输出文件名的后缀。
  • RELEASE_POSTFIX: 设置发布版本输出文件名的后缀。
  • POSITION_INDEPENDENT_CODE: 控制是否生成位置无关代码(PIC)。
  • CXX_STANDARD: 设置 C++ 标准。
  • C_STANDARD: 设置 C 标准。
  • CMAKE_CXX_FLAGS: 设置 C++ 编译选项。
  • CMAKE_C_FLAGS: 设置 C 编译选项。
  • CMAKE_EXE_LINKER_FLAGS: 设置可执行文件的链接选项。
  • CMAKE_SHARED_LINKER_FLAGS: 设置共享库的链接选项。
  • CMAKE_STATIC_LINKER_FLAGS: 设置静态库的链接选项。

示例:

# 创建一个可执行文件
add_executable(my_app main.cpp)# 设置可执行文件的属性
set_target_properties(my_app PROPERTIESOUTPUT_NAME "my_program"  # 输出文件名为 my_programOUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" # 输出到 bin 目录COMPILE_DEFINITIONS "DEBUG_MODE" # 定义 DEBUG_MODE 宏INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include" # 添加头文件搜索路径LINK_LIBRARIES "mylib" # 链接 mylib 库
)# 创建一个共享库
add_library(mylib SHARED mylib.cpp)# 设置共享库的属性
set_target_properties(mylib PROPERTIESVERSION 1.0.0SOVERSION 1OUTPUT_NAME "mylib"OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"POSITION_INDEPENDENT_CODE TRUE
)

SET_TARGET_PROPERTIES 是 CMake 中一个非常强大的工具,它允许你精细地控制目标的构建过程和行为。通过合理地使用 SET_TARGET_PROPERTIES,你可以构建出更加灵活、可配置和易于维护的项目。

理解并熟练运用 SET_TARGET_PROPERTIES 是编写高效 CMake 构建脚本的关键。建议查阅 CMake 官方文档以获取更详细的属性列表和使用方法。

16.文件安装INSTALL

install 命令用于指定在项目安装时需要复制的文件、目录和目标(例如库、可执行文件)。它允许你将构建好的项目部署到指定的位置,以便其他用户或系统可以使用。

语法:

install([TARGETS <target1> [<target2> ...]][FILES <file1> [<file2> ...]][DIRECTORY <dir1> [<dir2> ...]][PROGRAMS <program1> [<program2> ...]][SCRIPT <script1> [<script2> ...]][EXPORT <export_name>][DESTINATION <destination_dir>][COMPONENT <component_name>][PERMISSIONS <permissions>][CONFIGURATIONS <config1> [<config2> ...]][RENAME <old_name> <new_name>][OPTIONAL][...])

常用选项

  • TARGETS: 指定要安装的目标(例如库、可执行文件)。
  • FILES: 指定要安装的文件。
  • DIRECTORY: 指定要安装的目录。
  • DESTINATION: 指定安装的目标目录。
  • COMPONENT: 指定安装的组件,用于更精细的安装控制。
  • PERMISSIONS: 指定安装文件的权限。
  • CONFIGURATIONS: 指定只在特定构建配置下安装。
  • RENAME: 在安装时重命名文件。
  • OPTIONAL: 如果指定的文件或目标不存在,则忽略安装。

说明:

目录结构:

project/
├── CMakeLists.txt
├── libA/
│   ├── include/
│   │   └── libA.h
│   └── src/
│       └── libA.cpp
├── libB/
│   ├── include/
│   │   └── libB.h
│   └── src/
│       └── libB.cpp
└── libC/├── include/│   └── libC.h└── src/└── libC.cpp

CMakeList.txt

cmake_minimum_required(VERSION 3.10)
project(Example)# libA
add_library(libAsrc/libA/src/libA.cpp
)
target_include_directories(libAPUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libA/include>$<INSTALL_INTERFACE:include>
)# libB
add_library(libBsrc/libB/src/libB.cpp
)
target_link_libraries(libBPUBLIClibA
)
target_include_directories(libBPUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libB/include>$<INSTALL_INTERFACE:include>
)# libC
add_library(libCsrc/libC/src/libC.cpp
)
target_link_libraries(libCPRIVATElibB
)
target_include_directories(libCPRIVATE$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libC/include>$<INSTALL_INTERFACE:include>
)# 可执行文件
add_executable(main src/main.cpp)
target_link_libraries(mainPRIVATElibC
)# 安装规则
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")install(TARGETS libA libB libCDESTINATION lib
)install(TARGETS mainDESTINATION bin
)install(DIRECTORY libA/include/ libB/include/ libC/include/DESTINATION include
)

解释:

  1. set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install"): 设置安装前缀,即安装的根目录。这里我们将其设置为构建目录下的 install 文件夹。
  2. install(TARGETS libA libB libC DESTINATION lib): 安装 libAlibB 和 libC 库到 lib 目录下。
  3. install(TARGETS main DESTINATION bin): 安装 main 可执行文件到 bin 目录下。
  4. install(DIRECTORY libA/include/ libB/include/ libC/include/ DESTINATION include): 安装 libAlibB 和 libC 的头文件目录到 include 目录下。

编译和安装:

  1. 在 project 目录下创建一个 build 目录:mkdir build
  2. 进入 build 目录:cd build
  3. 运行 CMake:cmake ..
  4. 编译:make
  5. 安装:make install

安装后的目录结构(在 build/install 目录下):

install/
├── bin/
│   └── main
├── include/
│   ├── libA.h
│   ├── libB.h
│   └── libC.h
└── lib/├── liblibA.so (或 liblibA.dylib 或 liblibA.a)├── liblibB.so (或 liblibB.dylib 或 liblibB.a)└── liblibC.so (或 liblibC.dylib 或 liblibC.a)
  • 可执行文件 main 被安装到了 bin 目录下。
  • 库文件 libAlibB 和 libC 被安装到了 lib 目录下。
  • 头文件 libA.hlibB.h 和 libC.h 被安装到了 include 目录下。

一些用法举例:

安装单个文件:

install(FILES my_config.ini DESTINATION etc)

安装目录并保留目录结构:

install(DIRECTORY data/ DESTINATION share/data)

安装脚本:

install(PROGRAMS my_script.sh DESTINATION bin)

安装时重命名文件:

install(FILES my_config.ini DESTINATION etc RENAME my_app_config.ini)

指定安装权限:

install(PROGRAMS my_script.sh DESTINATION bin PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ
)

install 命令是 CMake 中非常重要的一个命令,它允许你定义如何将构建好的项目部署到指定的位置。通过灵活使用 install 命令的各种选项,你可以实现复杂的安装需求。

17.CMake常用路径说明

以下是一些在 CMakeLists.txt 中常用的默认路径变量(主要针对 Linux 环境,但很多也适用于其他 Unix-like 系统),以及它们的含义和常见用法:

核心安装路径变量:

  • CMAKE_INSTALL_PREFIX:

    • 含义: 安装路径的前缀,通常是 /usr/usr/local, 或自定义路径(安装根目录,所有路径均基于此目录展开)。
    • 默认值: 通常是 /usr/local
    • 用法: 所有其他安装路径变量都基于此路径。
    • 示例: 
cmake -DCMAKE_INSTALL_PREFIX=/opt/my_app .. (在配置时指定安装前缀)
  • CMAKE_INSTALL_BINDIR:

    • 含义: 安装可执行文件的目录(用户可执行文件目录(如 myapp))。
    • 默认值: bin (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/bin
    • 用法: 用于 install(TARGETS ... DESTINATION ...) 命令。
    • 示例: 
install(TARGETS my_app DESTINATION ${CMAKE_INSTALL_BINDIR})
  • CMAKE_INSTALL_SBINDIR:

    • 含义: 系统管理员可执行文件目录。
    • 默认值: sbin (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/sbin
    • 用法: 用于 install(TARGETS ... DESTINATION ...) 命令。
    • 示例: 同CMAKE_INSTALL_BINDIR:,略。
  • CMAKE_INSTALL_LIBDIR:

    • 含义: 安装库文件的目录。
    • 默认值: lib (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/lib
    • 用法: 用于 install(TARGETS ... DESTINATION ...) 命令。
    • 示例: 
install(TARGETS mylib DESTINATION ${CMAKE_INSTALL_LIBDIR})
  • CMAKE_INSTALL_INCLUDEDIR:

    • 含义: 安装头文件的目录。
    • 默认值: include (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/include
    • 用法: 用于 install(FILES ... DESTINATION ...) 命令。
    • 示例: 
install(FILES myheader.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
  • CMAKE_INSTALL_DATADIR:

    • 含义: 安装数据文件的目录。
    • 默认值: share (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/share
    • 用法: 用于 install(FILES ... DESTINATION ...) 命令。
    • 示例: 
install(FILES myconfig.ini DESTINATION ${CMAKE_INSTALL_DATADIR})
  • CMAKE_INSTALL_DOCDIR:

    • 含义: 安装文档文件的目录。
    • 默认值: share/doc (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/share/doc
    • 用法: 用于 install(FILES ... DESTINATION ...) 命令。
    • 示例: 
install(FILES README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
  • CMAKE_INSTALL_SYSCONFDIR:

    • 含义: 安装系统配置文件的目录。
    • 默认值: etc (相对于 CMAKE_INSTALL_PREFIX),例如 /usr/local/etc
    • 用法: 用于 install(FILES ... DESTINATION ...) 命令。
    • 示例: 
install(FILES myconfig.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR})

构建路径相关变量:

  • CMAKE_BINARY_DIR:

    • 含义: 构建目录的绝对路径(如build)。
    • 默认值: 通常是你在执行 cmake 命令时指定的构建目录。
    • 用法: 用于引用构建过程中生成的文件。
    • 示例: 
message("Build directory: ${CMAKE_BINARY_DIR}")
  • CMAKE_SOURCE_DIR:

    • 含义: 源代码目录的绝对路径(项目根目录)。
    • 默认值: 通常是包含顶层 CMakeLists.txt 文件的目录。
    • 用法: 用于引用源代码中的文件。
    • 示例: 
include_directories(${CMAKE_SOURCE_DIR}/include)
  • CMAKE_CURRENT_BINARY_DIR:

    • 含义: 当前正在处理的 CMakeLists.txt 文件所在的构建目录。
    • 默认值: 相对于 CMAKE_BINARY_DIR 的路径。
    • 用法: 用于引用当前构建目录下的文件。
    • 示例: 
add_executable(my_app ${CMAKE_CURRENT_BINARY_DIR}/main.o)
  • CMAKE_CURRENT_SOURCE_DIR:

    • 含义: 当前正在处理的 CMakeLists.txt 文件所在的源代码目录。
    • 默认值: 相对于 CMAKE_SOURCE_DIR 的路径。
    • 用法: 用于引用当前源代码目录下的文件。
    • 示例: 
add_executable(my_app ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)

PROJECT_BINARY_DIR项目构建目录(等同于 CMAKE_BINARY_DIR
PROJECT_SOURCE_DIR项目源码目录(等同于 CMAKE_SOURCE_DIR

其他常用路径变量:

  • CMAKE_MODULE_PATH:

    • 含义: CMake 模块的搜索路径列表。
    • 默认值: CMake 默认模块路径。
    • 用法: 用于查找自定义的 CMake 模块。
    • 示例: 
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules")
  • CMAKE_PREFIX_PATH:

    • 含义: 查找依赖库的路径列表。
    • 默认值: 系统默认路径。
    • 用法: 用于 find_package 命令。
    • 示例: 
list(APPEND CMAKE_PREFIX_PATH "/opt/my_libs")
  • CMAKE_LIBRARY_PATH:

    • 含义: 链接器搜索库文件的路径列表。
    • 默认值: 系统默认路径。
    • 用法: 用于指定链接器搜索库的路径。
    • 示例: 
list(APPEND CMAKE_LIBRARY_PATH "/opt/my_libs/lib")
  • CMAKE_INCLUDE_PATH:

    • 含义: 编译器搜索头文件的路径列表。
    • 默认值: 系统默认路径。
    • 用法: 用于指定编译器搜索头文件的路径。
    • 示例: 
list(APPEND CMAKE_INCLUDE_PATH "/opt/my_libs/include")

修改安装路径:

在某些情况下,我们并不想安装到默认路径,可以通过修改安装路径前缀来达到。其他路径修改也可以参考。

临时修改(命令行覆盖)

在运行 cmake 命令时,通过 -D 参数直接指定新的路径(优先级最高):

cmake -B build -DCMAKE_INSTALL_PREFIX=/your/custom/path

永久修改(修改 CMakeLists.txt)

# 在 CMakeLists.txt 开头附近添加:
# 语法:set(VARIABLE VALUE CACHE TYPE "Description" FORCE)
set(CMAKE_INSTALL_PREFIX "/your/default/path" CACHE PATH "Installation directory" FORCE)
  • CACHE PATH:将变量标记为可缓存(用户可通过命令行修改)。

  • FORCE:强制覆盖已有值(确保你的默认值生效)。

注意:

  • 可配置性: 这些变量通常可以通过 CMake 的命令行选项(例如 -DCMAKE_INSTALL_PREFIX=/opt/my_app)或在 CMakeLists.txt 文件中进行修改。
  • 相对路径: 在 install 命令中,DESTINATION 参数可以使用相对路径,这些路径是相对于 CMAKE_INSTALL_PREFIX 的。
  • 平台差异: 虽然这些变量在 Linux 环境下很常见,但在其他操作系统(如 Windows 或 macOS)上,它们的默认值可能会有所不同。
  • 查阅文档: CMake 的官方文档提供了最权威和详细的变量信息,建议查阅以获取更全面的了解。

相关文章:

CMake常用命令指南(CMakeList.txt)

CMakeList从入门到精通的文章有很多不再赘述&#xff08; 此处附带一篇优秀的博文链接&#xff1a;一个简单例子&#xff0c;完全入门CMake语法与CMakeList编写 &#xff09;。 本文主要列举 CMake 中常用命令的详细说明、优缺点分析以及推荐做法&#xff0c;以更好地理解和灵…...

【回溯+剪枝】找出所有子集的异或总和再求和 全排列Ⅱ

文章目录 1863. 找出所有子集的异或总和再求和解题思路&#xff1a;子集问题解法&#xff08;回溯 剪枝&#xff09;47. 全排列 II解题思路&#xff1a;排序 回溯 剪枝 1863. 找出所有子集的异或总和再求和 1863. 找出所有子集的异或总和再求和 一个数组的 异或总和 定义为…...

中国技术突破对国际格局的多维影响与回应

链接地址&#xff1a; https://download.csdn.net/download/wanggang130532/90323798https://download.csdn.net/download/wanggang130532/90323798...

【漫话机器学习系列】068.网格搜索(GridSearch)

网格搜索&#xff08;Grid Search&#xff09; 网格搜索&#xff08;Grid Search&#xff09;是一种用于优化机器学习模型超参数的技术。它通过系统地遍历给定的参数组合&#xff0c;找出使模型性能达到最优的参数配置。 网格搜索的核心思想 定义参数网格 创建一个包含超参数值…...

元宇宙下的Facebook:虚拟现实与社交的结合

随着科技的不断进步&#xff0c;虚拟现实&#xff08;VR&#xff09;技术逐渐从科幻走入现实&#xff0c;成为人们探索未来社交方式的重要工具。在这一浪潮中&#xff0c;Facebook&#xff08;现为Meta&#xff09;作为全球领先的社交平台&#xff0c;正在积极布局虚拟现实和元…...

记忆力训练day08

写作头脑风暴训练 1 集体的头脑风暴&#xff1a; 2 一个人的头脑风暴 没事&#xff0c;你说老师我还没有摸到门道&#xff0c;你去做&#xff0c;做的时候你就会知道什么叫做头脑风暴。记住&#xff0c;不要用脑子就在感觉里面&#xff0c;你究竟想给人呈现一种什么样的文章&am…...

崇州市街子古镇正月初一繁华剪影

今天是蛇年正月初一&#xff0c;下午笔者步出家门&#xff0c;逛到了崇州市街子古镇井水街&#xff0c;想看看景象如何。结果看到的是车水马龙、人流如织&#xff0c;繁花似锦&#xff0c;热闹非凡&#xff0c;原来今天开始预订此地摆下的长街宴。心里高兴&#xff0c;便用手机…...

websocket webworker教程及应用

WebSocket 和 Web Workers 是两种不同的 Web 技术&#xff0c;分别用于实现实时通信和后台线程处理。以下是它们的简要教程&#xff1a; WebSocket 教程 1. 什么是 WebSocket&#xff1f; WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务器主动向客户端推…...

【后端】Flask

长期更新&#xff0c;建议关注收藏点赞&#xff01; 实例1 Jinja2 是 Flask 和 Django 使用的 模板引擎&#xff0c;它允许你在 HTML 中嵌入 Python 代码&#xff0c;以动态生成页面内容。Jinja2 语法类似于 Django 模板&#xff0c;并支持变量、条件判断、循环、过滤器等。 fr…...

【cran Archive R包的安装方式】

cran Archive R包的安装方式 添加链接描述 1.包被cran移除 2.包要求的R语言版本与你电脑上的版本不相符 ad archive包的网址或者是下载到工作目录下&#xff0c;ad等于文件名 install,packages(ad repos NULL)...

如何用matlab画一条蛇

文章目录 源代码运行结果代码说明结果 源代码 % 画蛇的代码 % 2025-01-28/Ver1 % 清空环境 clc; clear; close all;% 定义蛇的身体坐标 t linspace(0, 4*pi, 100); % 参数化变量 x t; % x坐标 y sin(t) 0.5 * sin(3*t); % y坐标&#xff0c;形成更复…...

Greenplum临时表未清除导致库龄过高处理

1.问题 Greenplum集群segment后台日志报错 2.回收库龄 master上执行 vacuumdb -F -d cxy vacuumdb -F -d template1 vacuumdb -F -d rptdb 3.回收完成后检查 仍然发现segment还是有库龄报警警告信息发出 4.检查 4.1 在master上检查库年龄 SELECT datname, datfrozen…...

【Linux】gdb——Linux调试器

gdb使用背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 gdb使用方法 首先进入gdb gdb test_glist显示代码 断点 b 行…...

C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed

目录 四种操纵符简要介绍 setprecision基本用法 setfill的基本用法 fixed的基本用法 setw基本用法 以下是一些常见的用法和示例&#xff1a; 1. 设置字段宽度和填充字符 2. 设置字段宽度和对齐方式 3. 设置字段宽度和精度 4. 设置字段宽度和填充字符&#xff0c;结合…...

C++ ——— 学习并使用 priority_queue 类

目录 何为 priority_queue 类 学习并使用 priority_queue 类 实例化一个 priority_queue 类对象 插入数据 遍历堆&#xff08;默认是大堆&#xff09; 通过改变实例化的模板参数修改为小堆 何为 priority_queue 类 priority_queue 类为 优先级队列&#xff0c;其本质就是…...

基础项目实战——3D赛车(c++)

目录 前言一、渲染引擎二、关闭事件三、梯形绘制四、轨道绘制五、边缘绘制六、草坪绘制七、前后移动八、左右移动​九、曲线轨道​十、课山坡轨道​十一、循环轨道​十二、背景展示​十三、引入速度​十四、物品绘制​十五、课数字路障​十六、分数展示​十七、重新生成​十八、…...

ODP(OBProxy)路由初探

OBProxy路由策略 Primary Zone 路由 官方声明默认情况&#xff0c;会将租户请求发送到租户的 primary zone 所在的机器上&#xff0c;通过 Primary Zone 路由可以尽量发往主副本&#xff0c;方便快速寻找 Leader 副本。另外&#xff0c;设置primary zone 也会在一定成都上减少…...

从零推导线性回归:最小二乘法与梯度下降的数学原理

​ 欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 本文所有内容相关代码都可在以下仓库中找到&#xff1a; Github-MachineLearning 1 线性回归 1.1 什么是线性回归 线性回归是一种用来预测和分析数据之间关系的工具。它的核心思想是找到一条直…...

计算机网络__基础知识问答

Question: 1&#xff09;在计算机网络的5层结构中&#xff0c;每一层的功能大概是什么&#xff1f; 2&#xff09;交换机的功能&#xff1f;https://www.bilibili.com/video/BV1na4y1L7Ev 3&#xff09;路由器的功能&#xff1f;https://www.bilibili.com/video/BV1hv411k7n…...

第 5 章:声音与音乐系统

5.1 声音效果的应用 在游戏中&#xff0c;声音效果是增强游戏沉浸感和趣味性的重要元素。Pygame 提供了强大的音频处理功能&#xff0c;使得添加各种声音效果变得相对简单。声音效果可以包括角色的动作音效&#xff0c;如跳跃、攻击、受伤时的声音&#xff1b;环境音效&#x…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...