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. 指定库文件路径
link_directories
target_link_directories
6. 链接库文件
link_libraries
target_link_libraries
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_NAME
、PROJECT_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
- 功能:为目标添加头文件搜索路径。
- 优点:
- 模块化设计,只对指定目标生效。
- 支持
PUBLIC
、PRIVATE
和INTERFACE
关键字,控制依赖传递。
- 缺点:
- 需要明确指定目标,稍微复杂。
- 推荐做法:
- 推荐用于现代 CMake 项目。
- 示例:
target_include_directories(MyTarget PUBLIC include)
5. 指定库文件路径
link_directories
link_directories(<dir1> <dir2> ...)
- 功能:全局添加库文件搜索路径。
- 优点:
- 简单易用,适用于小型项目。
- 缺点:
- 全局生效,可能导致命名冲突或污染。
- 推荐做法:
- 适用于小型项目或快速原型开发。
- 示例:
link_directories(lib)
target_link_directories
- 功能:为目标添加库文件搜索路径。
- 优点:
- 模块化设计,只对指定目标生效。
- 支持
PUBLIC
、PRIVATE
和INTERFACE
关键字,控制依赖传递。
- 缺点:
- 需要明确指定目标,稍微复杂。
- 推荐做法:
- 推荐用于现代 CMake 项目。
- 示例:
target_link_directories(MyTarget PUBLIC lib)
6. 链接库文件
link_libraries
- 功能:全局链接库文件。
- 优点:
- 简单易用,适用于小型项目。
- 缺点:
- 全局生效,可能导致命名冲突或污染。
- 推荐做法:
- 适用于小型项目或快速原型开发。
- 示例:
link_libraries(mylib)
target_link_libraries
target_link_libraries(<target> [<lib1> <lib2> ...])
- 功能:为目标链接库文件。
- 优点:
- 模块化设计,只对指定目标生效。
- 支持
PUBLIC
、PRIVATE
和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> ...)
- 功能:为目标添加编译选项。
- 优点:
- 模块化设计,只对指定目标生效。
- 支持
PUBLIC
、PRIVATE
和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> ...
- 优点:
- 可以为目标添加编译定义,用于控制编译行为。
- 可以使用
INTERFACE
、PUBLIC
和PRIVATE
参数来控制定义的可见性。
- 缺点:
- 如果定义过多,可能会使代码难以理解。
- 推荐做法:
- 使用有意义的定义名称,提高代码的可读性。
- 使用
INTERFACE
、PUBLIC
和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] "消息内容")
- 优点:
- 可以输出不同级别的消息,方便调试和跟踪构建过程。
- 可以使用
STATUS
、WARNING
、AUTHOR_WARNING
、SEND_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.PUBLIC
、PRIVATE
和 INTERFACE
关键字
在 CMake 中,PUBLIC
、PRIVATE
和 INTERFACE
关键字用于控制目标属性的可见性和传播。这些关键字主要用于 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
,你可以控制目标的各种行为和特性,例如:
主要作用:
-
配置目标的构建过程:
- 输出路径: 指定生成的可执行文件或库的输出目录。
- 文件名: 修改生成的文件名。
- 链接库: 指定目标需要链接的库。
- 编译选项: 添加或修改编译器的选项。
- 链接选项: 添加或修改链接器的选项。
- 预处理器定义: 定义预处理器宏。
- 包含目录: 指定头文件的搜索路径。
- 源文件: 添加或删除源文件。
-
控制目标的行为:
- 类型: 设置目标的类型(例如,
EXECUTABLE
,SHARED_LIBRARY
,STATIC_LIBRARY
)。 - 安装规则: 定义如何安装目标。
- 依赖关系: 指定目标依赖的其他目标。
- 调试信息: 控制是否生成调试信息。
- 运行时库: 指定运行时库的类型。
- 类型: 设置目标的类型(例如,
-
提供元数据:
- 版本信息: 设置目标的版本号。
- 描述信息: 提供目标的描述。
- 自定义属性: 添加自定义的属性,供其他 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
)
解释:
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")
: 设置安装前缀,即安装的根目录。这里我们将其设置为构建目录下的install
文件夹。install(TARGETS libA libB libC DESTINATION lib)
: 安装libA
,libB
和libC
库到lib
目录下。install(TARGETS main DESTINATION bin)
: 安装main
可执行文件到bin
目录下。install(DIRECTORY libA/include/ libB/include/ libC/include/ DESTINATION include)
: 安装libA
,libB
和libC
的头文件目录到include
目录下。
编译和安装:
- 在
project
目录下创建一个build
目录:mkdir build
- 进入
build
目录:cd build
- 运行 CMake:
cmake ..
- 编译:
make
- 安装:
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
目录下。 - 库文件
libA
,libB
和libC
被安装到了lib
目录下。 - 头文件
libA.h
,libB.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
:- 含义: 系统管理员可执行文件目录。
- 默认值: s
bin
(相对于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从入门到精通的文章有很多不再赘述( 此处附带一篇优秀的博文链接:一个简单例子,完全入门CMake语法与CMakeList编写 )。 本文主要列举 CMake 中常用命令的详细说明、优缺点分析以及推荐做法,以更好地理解和灵…...
Mybatis是如何进行分页的?
大家好,我是锋哥。今天分享关于【Mybatis是如何进行分页的?】面试题。希望对大家有帮助; Mybatis是如何进行分页的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 实现分页的方式有很多种,最常见…...
推动知识共享的在线知识库实施与优化指南
内容概要 在当今迅速发展的数字化时代,在线知识库的实施显得尤为重要。它不仅为企业提供了高效的信息存储与共享平台,还能够有效促进团队成员之间的协作与知识传递。通过集中管理企业内的各类知识资源,在线知识库帮助员工快速查找所需信息&a…...
【最后203篇系列】007 使用APS搭建本地定时任务
说明 最大的好处是方便。 其实所有任务的源头,应该都是通过定时的方式,在每个时隙发起轮询。当然在任务的后续传递中,可以通过CallBack或者WebHook的方式,以事件的形态进行。这样可以避免长任务执行的过程中进行等待和轮询。 总结…...
为AI聊天工具添加一个知识系统 之78 详细设计之19 正则表达式 之6
本文要点 要点 本项目设计的正则表达式 是一个 动态正则匹配框架。它是一个谓词系统:谓词 是运动,主语是“维度”,表语是 语言处理。主语的一个 双动结构。 Reg三大功能 语法验证、语义检查和 语用检验,三者 :语义约…...
三天急速通关JavaWeb基础知识:Day 1 后端基础知识
三天急速通关JavaWeb基础知识:Day 1 后端基础知识 0 文章说明1 Http1.1 介绍1.2 通信过程1.3 报文 Message1.3.1 请求报文 Request Message1.3.2 响应报文 Response Message 2 XML2.1 介绍2.2 利用Java解析XML 3 Tomcat3.1 介绍3.2 Tomcat的安装与配置3.3 Tomcat的项…...
代理模式 -- 学习笔记
代理模式学习笔记 什么是代理? 代理是一种设计模式,用户可以通过代理操作,而真正去进行处理的是我们的目标对象,代理可以在方法增强(如:记录日志,添加事务,监控等) 拿一…...
前端-Rollup
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…...
EtherCAT主站IGH-- 21 -- IGH之fsm_reboot.h/c文件解析
EtherCAT主站IGH-- 21 -- IGH之fsm_reboot.h/c文件解析 0 预览一 该文件功能`fsm_reboot.c` 文件功能函数预览二 函数功能介绍`fsm_reboot.c` 中主要函数的作用1. `ec_fsm_reboot_init`2. `ec_fsm_reboot_clear`3. `ec_fsm_reboot_single`4. `ec_fsm_reboot_all`5. `ec_fsm_reb…...
【NLP251】NLP RNN 系列网络
NLP251 系列主要记录从NLP基础网络结构到知识图谱的学习 1.原理及网络结构 1.1RNN 在Yoshua Bengio论文中( http://proceedings.mlr.press/v28/pascanu13.pdf )证明了梯度求导的一部分环节是一个指数模型…...
数据分析系列--④RapidMiner进行关联分析(案例)
一、核心概念 1.1项集(Itemset) 1.2规则(Rule) 1.3支持度(Support) 1.3.1 支持度的定义 1.3.2 支持度的意义 1.3.3 支持度的应用 1.3.4 支持度的示例 1.3.5 支持度的调整 1.3.6 支持度与其他指标的…...
深度学习:基于MindNLP的RAG应用开发
什么是RAG? RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合检索(Retrieval)和生成(Generation)的技术,旨在提升大语言模型(LLM)生…...
Hive安装教程
Hive安装教程 文章目录 Hive安装教程写在前面安装下载安装部署安装Hive启动并使用Hive MySQL安装检查当前系统是否安装过MySQL安装初始化数据库 Hive元数据配置到MySQL拷贝驱动配置Metastore到MySQL再次启动Hive 写在前面 Linux版本:CentOS7.5Hive版本:…...
安卓逆向之脱壳-认识一下动态加载 双亲委派(二)
一:动态加载与双亲委派模型 在 Java 和 Android 中,ClassLoader 是一个非常重要的组件,负责将 .class 文件或 .dex 文件的字节码加载到内存中,供程序使用。在这其中,有两种关键的概念需要深入理解:动态加载…...
全程Kali linux---CTFshow misc入门(14-24)
第十四题: dd命令:dd是一个用于复制和转换数据的命令,它可以对文件、设备等进行操作,在数据备份、转换格式等场景经常使用。 ifmisc14.jpg:if表示 “input file”(输入文件),这里指…...
学习数据结构(3)顺序表
1.动态顺序表的实现 (1)初始化 (2)扩容 (3)头部插入 (4)尾部插入 (5)头部删除 (这里注意要保证有效数据个数不为0) (6&a…...
知识体系、知识管理角度的赚钱思考
从知识管理和知识体系的角度出发,赚钱的问题思考清单可以帮助你系统地梳理和优化自己在财富创造方面的策略。 以下是一个详细的清单,涵盖从知识获取、技能提升到实际应用的各个环节,帮助你在赚钱的道路上更加高效和有条理。 一、赚钱的目标与…...
(done) ABI 相关知识补充:内核线程切换、用户线程切换、用户内核切换需要保存哪些寄存器?
由于操作系统和编译器约定了 ABI,如下: 编译器在对 C 语言编译时,会自动 caller 标注的寄存器进行保存恢复。保存的步骤通常发生在进入函数的时候,恢复的步骤通常发生在从函数返回的时候。 内核线程切换需要保存的寄存器&#…...
QT6 + CMAKE编译OPENCV3.9
参考文档 [1] https://blog.csdn.net/rjkf_css/article/details/135676077 前提条件 配置好相关运行环境:QT6、OPENCV3.9的sources文件 OPENCV下载网页:https://opencv.org/releases/ QT6下载教程:https://blog.csdn.net/caoshangpa/article…...
Linux 常用命令——系统设置篇(保姆级说明)
系统设置类 显示当前运行的进程(ps) ps [options] [--help]# 查找指定进程格式: ps -ef | grep 进程关键字# 显示进程信息 ps -A 参数: -A 列出所有的进程 -w 显示加宽可以显示较多的资讯 -au 显示较详细的资讯 -aux 显示所有包…...
完美世界前端面试题及参考答案
如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...
Vue3笔记——(三)hooks、路由
015 hooks 作用:使得代码更加模块化和可维护 Person.vue <template><div><h2>当前求和{{ sum }}</h2><button click"addFn">点我sum1</button></div> </template> <script setup lang"ts"…...
网络安全大模型和人工智能场景及应用理解
本文通过通俗易懂的方式的进行阐述,大家读完觉得有帮助记得及时关注和点赞!!! 一、网络安全大模型的概述 网络安全大模型是一种用于识别和应对各种网络安全威胁的模型。它通过分析网络数据包、网络行为等信息,识别潜在…...
python-leetcode-从中序与后序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right r…...
NLP模型大对比:Transformer > RNN > n-gram
结论 Transformer 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异: 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的"侦探"依赖距离只能看前…...
MySQL查询优化(三):深度解读 MySQL客户端和服务端协议
如果需要从 MySQL 服务端获得很高的性能,最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些,大部分的查询优化是有据可循的,从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程: 客户端…...
[STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器
一、高级定时器简介 高级定时器的简介在前面一章已经介绍过,可以点击下面链接了解,在这里进行一些补充。 [STM32 - 野火] - - - 固件库学习笔记 - - -十二.基本定时器 1.1 功能简介 1、高级定时器可以向上/向下/两边计数,还独有一个重复计…...
Antd React Form使用Radio嵌套多个Select和Input的处理
使用Antd React Form使用Radio会遇到嵌套多个Select和Input的处理,需要多层嵌套和处理默认事件和冒泡,具体实现过程直接上代码。 实现效果布局如下图 代码 <Formname"basic"form{form}labelWrap{...formItemLayoutSpan(5, 19)}onFinish{on…...
固有频率与模态分析
目录 引言 1. 固有频率:物体的“天生节奏” 1.1 定义 1.2 关键特点 1.3 实际意义 2. 有限元中的模态分析:给结构“体检振动” 2.1 模态分析的意义 2.2 实际案例 2.2.1 桥梁模态分析 2.2.2 飞机机翼模态分析 2.2.3 具体事例 3. 模态分析的工具…...
视频多模态模型——视频版ViT
大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》,2021由google 提出用于视频处理的视觉 Transformer 模型,在视频多模态领域有…...
2859.计算K置位下标对应元素的和
示例 1:输入:nums [5,10,1,5,2], k 1 输出:13 解释:下标的二进制表示是: 0 0002 1 0012 2 0102 3 0112 4 1002 下标 1、2 和 4 在其二进制表示中都存在 k 1 个置位。 因此,答案为 nums[1] nums[…...
Redis 教程
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 它通常被称为数据结构服务器&…...
2024 CVPR Highlight Learning-Feedback
图像增强 Towards Robust Event-guided Low-Light Image Enhancement: A Large-Scale Real-World Event-Image Dataset and Novel Approach 解决的主要问题是低光照条件下的图像增强 通过多尺度整体融合分支提取事件和图像的结构和纹理信息,并引入信噪比࿰…...
maven、npm、pip、yum官方镜像修改文档
文章目录 Maven阿里云网易华为腾讯云 Npm淘宝腾讯云 pip清华源阿里中科大华科 Yum 由于各博客繁杂,本文旨在记录各常见镜像官网,及其配置文档。常用镜像及配置可评论后加入 Maven 阿里云 官方文档 setting.xml <mirror><id>aliyunmaven&l…...
UE求职Demo开发日志#15 思路与任务梳理、找需要的资源
1 思路梳理 因为有点无从下手,就梳理下最终形态. 基地的建设我是想单独一个场景,同一个关卡中小怪会每次来都会刷,小解密一次性的,关键的Boss和精英怪不会重复刷,同时场景里放一些资源可收集,基地建设锁定区…...
设置jmeter外观颜色
设置jmeter外观颜色 方法: 步骤一、点击顶部选项 ->外观,这里提供了不同的主题,可选自己喜欢的风格。 步骤二、选择后,弹框提示点击Yes。...
《一文读懂!Q-learning状态-动作值函数的直观理解》
在人工智能的强化学习领域,Q-learning算法是一颗耀眼的明星,被广泛应用于机器人控制、游戏AI开发、自动驾驶等诸多前沿领域。而想要真正掌握Q-learning算法,理解其核心概念——状态 - 动作值函数,是绕不开的关键一步。这篇文章就带…...
Angular 2 表单深度解析
Angular 2 表单深度解析 引言 Angular 2作为现代前端开发的框架之一,以其灵活性和强大的功能赢得了众多开发者的青睐。在Angular 2中,表单处理是其中一个重要且复杂的部分。本文将深入解析Angular 2的表单,从基础知识到高级应用,旨在帮助开发者更好地理解和运用Angular 2…...
使用kitty terminal遇到的‘xterm-kitty‘: unknown terminal type.
解决办法 方式一 export TERMxterm-256color使永久生效 echo export TERMxterm-256color >> ~/.zshrc # 如果用 zsh,如果使用的是bash就修改为bashrc source ~/.zshrc #同理如果是ssh下遇到该问题,参考 https://sw.kovidgoyal.net/kitty/faq/…...
Dest1ny漏洞库:用友 U8 Cloud ReleaseRepMngAction SQL 注入漏洞(CNVD-2024-33023)
大家好,今天是Dest1ny漏洞库的专题!! 会时不时发送新的漏洞资讯!! 大家多多关注,多多点赞!!! 0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚…...
代码随想录|动态规划 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
300.最长递增子序列 题目 参考文章 思路:dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度 因为没有连续,所以每一个元素都要比较,从而得到结果 两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾, 要不然这个比…...
Flutter_学习记录_导航和其他
Flutter 的导航页面跳转,是通过组件Navigator 和 组件MaterialPageRoute来实现的,Navigator提供了很多个方法,但是目前,我只记录我学习过程中接触到的方法: Navigator.push(), 跳转下一个页面Navigator.pop(), 返回上一…...
【信息系统项目管理师-选择真题】2006下半年综合知识答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...
面向对象编程简史
注:本文为 “面向对象编程简史” 相关文章合辑。 英文引文,机翻未校。 Brief history of Object-Oriented Programming 面向对象编程简史 Tue, May 14, 2024 Throughout its history, object-oriented programming (OOP) has undergone significant …...
快速提升网站收录:内容创作的艺术
本文来自:百万收录网 原文链接:https://www.baiwanshoulu.com/15.html 快速提升网站收录,内容创作是关键。以下是一些关于内容创作以提升网站收录的艺术性建议: 一、关键词研究与优化 选择长尾关键词:进行深入的关键…...
高速PCB设计指南3——PCB 传输线和受控阻抗
高速PCB设计指南3——PCB 传输线和受控阻抗 1. 传输线1.1 传输线的定义1.2 传输线的分类1.3 互为传输线的情况 2. 均匀传输线的特性阻抗3. PCB中受控阻抗结构3.1 微带线(Microstrip)3.2 带状线(Stripline) 4 阻抗控制方法5. 阻抗控…...
python实现一个完整的智能教室能耗监测与管理系统的实现方案
以下是一个完整的智能教室能耗监测与管理系统的实现方案,主要使用Python语言,涵盖深度学习模型研发、教室场景适应性分析、系统架构设计、前端展示、后端服务以及测试评估等方面。 1. 数据准备 首先,需要收集教室的照片数据集,并…...
【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测
🔥【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测 📅 发布日期:2025年01月29日(大年初一) 在这个辞旧迎新的美好时刻,我们迎来了充满希望的2025年,也是十二生肖中的蛇…...
woocommerce独立站与wordpress独立站的最大区别是什么
WooCommerce独立站与WordPress独立站的最大区别在于它们的功能定位和使用场景。 WordPress是一个开源的内容管理系统(CMS),最初是作为博客平台发展起来的,但现在已经演变为一个功能丰富的网站构建工具。它主要用于创建动态网站,提供广泛的定…...
docker安装MySQL8:docker离线安装MySQL、docker在线安装MySQL、MySQL镜像下载、MySQL配置、MySQL命令
一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull mysql:8.0.41 2、离线包下载 两种方式: 方式一: -)在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -)导出 # 导出镜…...