cmake

本文详细介绍CMake的安装升级、多版本管理方法,并列举了大量常用命令及其参数详解,包括脚本命令、项目命令等,帮助读者掌握CMake的高级用法。

cmake升级及多版本管理

  1. 查看原有的cmake:

    cmake --version
    which cmake
    >>> /usr/bin/cmake
    
  2. 下载要装的cmake源文件,解压并进入,使用已有的cmake安装

    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=/usr/local/cmake/cmake-3.20.6 ..
    # 或不使用cmake安装,将bootstrap中的cmake_default_prefix="/usr/local"改为cmake_default_prefix="/usr/local/cmake/cmake-3.20.6"
    make
    sudo make install
    cmake --version
    
  3. .bashrc中指定cmake版本

    export PATH=/usr/local/cmake/cmake-3.20.6/bin:$PATH
    

    链接cmake

    sudo ln -sf /usr/local/cmake/cmake-3.20.5/bin/* /usr/bin/
    

CMake常用变量

变量
CMAKE_SOURCE_DIR工程最顶层CMakeLists.txt文件所在目录
CMAKE_CURRENT_SOURCE_DIR当前编译的CMakeLists.txt文件所在目录
PROJECT_SOURCE_DIR当前工程的CMakeLists.txt文件所在目录
<PROJECT-NAME>_SOURCE_DIR工程中PROJECT-NAME工程的CMakeLists.txt文件所在目录

CMake常用命令速查

cmake命令可分为脚本命令、项目命令、CTest 命令、已弃用的命令

1. 脚本命令

脚本命令始终可用。

1.1 find_package

用于查找和加载外部库

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER])
参数
描述
<PackageName>要查找的库的名称,例如Qt、Boost、OpenCV等。
[version]可选参数,默认用于指定所需的库的最低版本。可以使用EXACT关键字来强制匹配特定版本。
[EXACT]可选参数,用于强制匹配特定版本的库。
[QUIET]可选参数,用于在查找过程中禁止显示详细信息。
[MODULE]可选参数,用于指示查找的是CMake模块而不是包。
[REQUIRED]可选参数,用于指示库是必需的。如果找不到库,CMake将报错退出。
[[COMPONENTS] [components...]]可选参数,用于指定库的组件。例如,Qt库的组件可以是Widgets、Network、Quick等。
[OPTIONAL_COMPONENTS components...]可选参数,用于指定可选的库组件。
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]可选参数,用于指定注册表视图。
[GLOBAL]可选参数,用于指示全局查找。
[NO_POLICY_SCOPE]可选参数,用于指示不使用策略作用域。
[BYPASS_PROVIDER]可选参数,用于绕过提供者。

1.2 find_library

用于查找和加载库文件

find_library (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
参数
描述
<VAR>用于保存命令执行结果的变量名。
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]要查找的库文件名或多个可能的文件名。NAMES_PER_DIR表示在每个目录中查找所有指定的文件名。
[HINTS [path | ENV var]...]指定额外的搜索路径,可以是目录路径或环境变量。
[PATHS [path | ENV var]...]指定搜索路径,优先级高于默认路径。
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]指定在Windows平台上查询注册表的视图。
[PATH_SUFFIXES suffix1 [suffix2 ...]]指定在每个目录位置下要检查的附加子目录。
[VALIDATOR function]指定一个函数,用于验证每个候选项。
[DOC "cache documentation string"]用于设置缓存文档字符串。
[NO_CACHE]禁用缓存。
[REQUIRED]指示文件是必需的。
[NO_DEFAULT_PATH]不使用默认路径。
[NO_PACKAGE_ROOT_PATH]不使用包根路径。
[NO_CMAKE_PATH]不使用CMake路径。
[NO_CMAKE_ENVIRONMENT_PATH]不使用环境变量路径。
[NO_SYSTEM_ENVIRONMENT_PATH]不使用系统环境变量路径。
[NO_CMAKE_SYSTEM_PATH]不使用CMake系统路径。
[NO_CMAKE_INSTALL_PREFIX]不使用CMake安装前缀。
[CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH]设置根路径模式。

1.3 find_path

用于查找包含特定文件的目录路径

find_path (
          <VAR>
          name | NAMES name1 [name2 ...]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
参数
描述
<VAR>用于保存命令执行结果的变量名。
name | NAMES name1 [name2 ...]要查找的文件名或多个可能的文件名。
[HINTS [path | ENV var]...]指定额外的搜索路径,可以是目录路径或环境变量。
[PATHS [path | ENV var]...]指定搜索路径,优先级高于默认路径。
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]指定在Windows平台上查询注册表的视图。
[PATH_SUFFIXES suffix1 [suffix2 ...]]指定在每个目录位置下要检查的附加子目录。
[VALIDATOR function]指定一个函数,用于验证每个候选项。
[DOC "cache documentation string"]用于设置缓存文档字符串。
[NO_CACHE]禁用缓存。
[REQUIRED]指示文件是必需的。
[NO_DEFAULT_PATH]不使用默认路径。
[NO_PACKAGE_ROOT_PATH]不使用包根路径。
[NO_CMAKE_PATH]不使用CMake路径。
[NO_CMAKE_ENVIRONMENT_PATH]不使用环境变量路径。
[NO_SYSTEM_ENVIRONMENT_PATH]不使用系统环境变量路径。
[NO_CMAKE_SYSTEM_PATH]不使用CMake系统路径。
[NO_CMAKE_INSTALL_PREFIX]不使用CMake安装前缀。
[CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH]设置根路径模式。

1.4 list

用于处理列表,包括读取、搜索、修改和排序

读取描述
list(LENGTH <list> <out-var>)获取列表的长度,并将结果存储在变量中。
list(GET <list> <element index> [<index> ...] <out-var>)获取列表中指定索引位置的元素,并将结果存储在变量中。
list(JOIN <list> <glue> <out-var>)将列表中的元素用指定的分隔符连接起来,并将结果存储在变量中。
list(SUBLIST <list> <begin> <length> <out-var>)获取列表的子列表,从指定的索引开始,指定长度,并将结果存储在变量中。
搜索描述
list(FIND <list> <value> <out-var>)在列表中搜索指定的值,并将其索引存储在变量中。
修改
描述
list(APPEND <list> [<element>...])将元素添加到列表的末尾。
list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)根据正则表达式筛选列表中的元素。
list(INSERT <list> <index> [<element>...])在指定索引位置插入元素到列表中。
list(POP_BACK <list> [<out-var>...])从列表的末尾弹出元素。
list(POP_FRONT <list> [<out-var>...])从列表的开头弹出元素。
list(PREPEND <list> [<element>...])将元素添加到列表的开头。
list(REMOVE_ITEM <list> <value>...)从列表中移除指定的值。
list(REMOVE_AT <list> <index>...)从列表中移除指定索引位置的元素。
list(REMOVE_DUPLICATES <list>)移除列表中的重复元素。
list(TRANSFORM <list> <ACTION> [...])对列表中的元素进行转换操作。
排序
描述
list(REVERSE <list>)反转列表中的元素顺序。
list(SORT <list> [...])对列表中的元素进行排序。

1.5 include

用于在CMake脚本中包含其他文件或模块。

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])
参数
描述
<file|module>要包含的文件或模块的名称。
[OPTIONAL]可选参数,表示如果文件不存在也不会报错。
[RESULT_VARIABLE <var>]可选参数,用于将结果存储在变量中。
[NO_POLICY_SCOPE]可选参数,用于指示不使用策略作用域。

2. 项目命令

项目命令仅在项目中可用。

2.1 include_directories

用于向编译器提供一组包含目录。

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
参数
描述
[AFTER|BEFORE]可选参数,用于指定包含目录的添加位置。AFTER表示在已有目录之后添加,BEFORE表示在已有目录之前添加。
[SYSTEM]可选参数,用于指示这些目录是系统级别的,而不是项目级别的。
dir1 [dir2 ...]要添加到包含路径的目录列表。

请根据您的项目需求使用这些参数来设置包含目录。

2.2 link_directories

用于向链接器提供一组库文件搜索路径。

link_directories([AFTER|BEFORE] directory1 [directory2 ...])
参数描述
[AFTER|BEFORE]可选参数,用于指定链接路径的添加位置。AFTER表示在已有路径之后添加,BEFORE表示在已有路径之前添加。
directory1 [directory2 ...]要添加到链接路径的目录列表。

2.3 target_include_directories

用于为指定目标(target)添加头文件搜索路径

target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
参数描述
<target>要添加头文件搜索路径的目标的名称。
[SYSTEM]可选参数,用于指示这些路径是系统级别的,而不是项目级别的。
[AFTER|BEFORE]可选参数,用于指定添加路径的位置。AFTER表示在已有路径之后添加,BEFORE表示在已有路径之前添加。
<INTERFACE|PUBLIC|PRIVATE>指定添加路径的属性。
[items1...]要添加的头文件搜索路径列表。
[items2...]可选参数,用于添加更多的头文件搜索路径。

2.4 link_libraries

用于指定要链接到整个项目的库

link_libraries([item1 [item2 [...]]]
               [[debug|optimized|general] <item>] ...)

2.5 target_link_libraries

用于将库链接到指定的目标(target)

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
参数
描述
<target>要链接的目标的名称。
<PRIVATE|PUBLIC|INTERFACE>指定链接的属性:
PRIVATE - 链接的库只对当前目标有效。 不会传递给依赖于当前目标的其他目标。
PUBLIC - 链接的库对当前目标和依赖于当前目标的其他目标都有效。 会传递给其他目标。
INTERFACE - 链接的库只对依赖于当前目标的其他目标有效。 不会传递给当前目标。
<item>...要链接的库或目标的名称。

2.6 include_directories、link_directories、link_libraries与target_include_directories的区别与联系

命令描述
include_directories用于向编译器提供一组包含目录。这些目录将在预处理器查找头文件时被搜索。
link_directories用于向链接器提供一组库文件搜索路径。这些路径将在链接时查找库文件。
link_libraries用于指定要链接到目标的库。
target_include_directories用于为指定目标(target)添加头文件搜索路径。这是目标范围的设置,只影响特定目标的编译过程。
方面区别联系
作用对象target_include_directories只作用于指定的目标。include_directorieslink_directorieslink_libraries作用于整个项目,影响所有目标。
路径类型link_libraries设置的是要链接到目标的库。include_directories设置的是头文件的搜索路径。 link_directories设置的是库文件的链接路径。 target_include_directories设置的是特定目标的头文件搜索路径。

2.7 add_executable

用于定义一个可执行对象

# 普通
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])
# 导入
add_executable(<name> IMPORTED [GLOBAL])
# 别名
add_executable(<name> ALIAS <target>)
参数描述
<name>要创建的可执行目标的名称。
[WIN32]可选参数,用于指示在Windows上创建一个GUI应用程序。
[MACOSX_BUNDLE]可选参数,用于指示在macOS上创建一个应用程序捆绑包。
[EXCLUDE_FROM_ALL]可选参数,用于指示将目标排除在构建过程之外。
[source1] [source2 ...]源文件列表,用于构建可执行目标。
IMPORTED用于创建一个导入的目标,表示目标不由当前项目构建,而是由其他项目或外部提供。
ALIAS <target>用于创建一个目标别名,允许在构建过程中使用不同的名称引用相同的目标。

2.8 add_library

创建一个库

# 普通
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])
# 对象
add_library(<name> OBJECT [<source>...])
# 接口
add_library(<name> INTERFACE)
# 导入
add_library(<name> <type> IMPORTED [GLOBAL])
# 别名
add_library(<name> ALIAS <target>)
参数描述
<name>要创建的库目标的名称。
[STATIC | SHARED | MODULE]可选参数,用于指定库的类型:
- STATIC:创建一个静态库。
- SHARED:创建一个共享库(动态库)。
- MODULE:创建一个模块库(在某些平台上的特定类型)。
[EXCLUDE_FROM_ALL]可选参数,用于指示将目标排除在构建过程之外。
[<source>...]源文件列表,用于构建库。
OBJECT创建一个对象库目标。这是一种特殊类型的库,不会生成实际的库文件,但可以在其他目标中使用。
INTERFACE创建一个接口库目标。这是一种特殊类型的库,不会生成实际的库文件,只包含头文件和编译选项。
<type> IMPORTED [GLOBAL]创建一个导入的目标,表示目标不由当前项目构建,而是由其他项目或外部提供。<type>STATIC, SHARED, MODULE, UNKNOWN其中之一
ALIAS <target><target>创建一个目标别名,允许在构建过程中使用不同的名称引用相同的目标。

2.9 add_dependencies

使顶层目标 <target> 依赖于其他顶层目标,确保在构建 <target> 之前,其他目标已经构建完毕。

add_dependencies(<target> [<target-dependency>]...)

顶层目标是由 add_executable()add_library()add_custom_target() 等命令创建的目标(但不包括由 CMake 生成的像 install 这样的目标)。

2.10 add_definitions

将-D定义标志添加到源文件的编译中。

add_definitions(-DFOO -DBAR ...)

向当前目录中的目标添加编译器命令行的定义,无论是在调用此命令之前还是之后添加的,以及在之后添加的子目录中的目标。此命令可用于添加任何标志,但旨在添加预处理器定义。

注意:此命令已被替代:
使用add_compile_definitions()添加预处理器定义。
使用include_directories()添加包含目录。
使用add_compile_options()添加其他选项。

2.11 install

用于在CMake构建过程中安装目标、文件、目录、脚本、代码等

install(TARGETS <target>... [...])
install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])
install(RUNTIME_DEPENDENCY_SET <set-name> [...])
命令描述
install(TARGETS <target>... [...])安装指定的构建目标(例如可执行文件、库)。
install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])安装导入的运行时构件。
install({FILES | PROGRAMS} <file>... [...])安装指定的文件或程序。
install(DIRECTORY <dir>... [...])安装指定的目录及其内容。
install(SCRIPT <file> [...])安装指定的脚本文件。
install(CODE <code> [...])在安装过程中执行指定的CMake代码。
install(EXPORT <export-name> [...])安装指定的导出配置。
install(RUNTIME_DEPENDENCY_SET <set-name> [...])安装指定的运行时依赖集。
07-27
### CMake 使用教程、安装配置及常见问题解决方案 #### 安装 CMake 在不同的操作系统中,CMake 的安装方式有所不同。以下是一些常见的安装方法: ##### Linux 系统(以 Ubuntu 为例) 1. **离线安装** 可以从 [CMake 官网](https://cmake.org/download/) 下载适用于 Linux 的压缩包(如 `cmake-x.x.x-linux-x86_64.tar.gz`),然后进行手动安装: ```bash tar -xzvf cmake-x.x.x-linux-x86_64.tar.gz ``` 2. **配置环境变量** 将 CMake 的 `bin` 目录添加到系统环境变量中,以便全局使用: ```bash export PATH=/path/to/cmake/bin:$PATH ``` 可以将上述命令添加到 `~/.bashrc` 或 `~/.zshrc` 文件中,以便每次启动终端时自动加载: ```bash echo 'export PATH=/path/to/cmake/bin:$PATH' >> ~/.bashrc source ~/.bashrc ``` 3. **验证安装** 使用以下命令确认 CMake 是否安装成功: ```bash cmake --version ``` 如果输出 CMake版本号,则表示安装成功[^1]。 ##### Windows 系统 1. 从 [CMake 官网](https://cmake.org/download/) 下载 Windows 安装包(`.msi` 文件)。 2. 运行安装程序,并选择将 CMake 添加到系统环境变量中。 3. 打开命令提示符(CMD)或 PowerShell,输入以下命令验证安装: ```bash cmake --version ``` ##### macOS 系统 可以使用 Homebrew 安装 CMake: ```bash brew install cmake ``` 验证安装: ```bash cmake --version ``` #### 配置 CMake 项目 CMake 项目的核心是 `CMakeLists.txt` 文件,它定义了项目的构建规则。以下是一个简单的 CMake 项目配置示例: ```cmake # 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.10) # 定义项目名称 project(HelloCMake) # 添加可执行文件目标 add_executable(hello main.cpp) ``` 1. **创建构建目录** 通常建议在项目根目录下创建一个 `build` 子目录用于存放构建生成的文件: ```bash mkdir build cd build ``` 2. **生成构建文件** 在构建目录中运行 CMake,生成 Makefile 或其他构建系统所需的文件: ```bash cmake .. ``` 3. **编译项目** 使用 `make` 命令进行编译(适用于 Linux/macOS): ```bash make ``` 或者使用 Visual Studio 打开 `.sln` 文件进行编译(适用于 Windows)。 #### 常见问题及解决方法 1. **CMake 找不到编译器** - **问题描述**:CMake 在配置过程中提示找不到编译器。 - **解决方法**:确保系统中已安装编译器(如 GCC、Clang 或 MSVC),并且编译器的路径已添加到系统环境变量中。 2. **CMakeLists.txt 文件语法错误** - **问题描述**:CMake 配置失败,提示语法错误。 - **解决方法**:检查 `CMakeLists.txt` 文件中的语法是否正确,特别是命令的大小写和参数顺序。 3. **找不到依赖库** - **问题描述**:编译过程中提示找不到某些依赖库。 - **解决方法**:确保所有依赖库已正确安装,并且在 `CMakeLists.txt` 中使用 `find_package()` 或 `include_directories()` 正确引用。 4. **Android Studio 中使用 CMake** - **问题描述**:在 Android Studio 中配置 CMake 时遇到问题。 - **解决方法**:可以使用 Android Studio 自带的 CMake 支持,创建一个支持 C++ 的项目,查看生成的 `CMakeLists.txt` 文件,确保路径和依赖项配置正确[^5]。 #### 学习资源 - **《CMake + Practice》**:这是一篇适合初学者的中文入门教程,适合了解 CMake 的基本概念和使用方法[^2]。 - **官方文档**:[CMake 官方文档](https://cmake.org/cmake/help/latest/) 是深入了解 CMake 各种命令和高级用法的最佳资源。 - **实践项目**:通过实际项目学习 CMake 的使用,尤其是复杂的项目结构和依赖管理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值