install

在安装时指定要运行的规则。

概要

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(PACKAGE_INFO <package-name> [...])
install(RUNTIME_DEPENDENCY_SET <set-name> [...])

简介

此命令生成项目的安装规则。在源目录内通过调用 install() 命令指定的安装规则在安装过程中按顺序执行。

版本 3.14 中已更改: 通过调用 add_subdirectory() 命令添加到子目录中的安装规则与父目录中的规则交错,以声明的顺序运行(请参阅策略 CMP0082)。

版本 3.22 中已更改: 环境变量 CMAKE_INSTALL_MODE 可以覆盖 install() 的默认复制行为。

版本 3.31 中已更改: 项目可以启用 INSTALL_PARALLEL 来启用并行安装。在使用并行安装时,通过调用 add_subdirectory() 命令添加的子目录会独立安装,并且不同子目录中添加的安装规则的运行顺序不保证。

通用选项

此命令有多种签名。其中一些定义了文件和目标的安装选项。此处涵盖了多个签名通用的选项,但它们仅对指定这些选项的签名有效。通用选项是

DESTINATION <dir>

指定要安装文件的磁盘目录。<dir> 应为相对路径。允许使用绝对路径,但不推荐。

当给出相对路径时,它相对于 CMAKE_INSTALL_PREFIX 变量的值进行解释。可以使用 DESTDIR 机制在安装时重新定位前缀,该机制在 CMAKE_INSTALL_PREFIX 变量文档中进行了说明。

由于绝对路径在 cmake --install 命令的 --prefix 选项或 cpack 安装程序生成器中不起作用,因此强烈建议在整个项目中都使用相对路径,以获得包维护者的最佳支持。特别是,没有必要通过在前面加上 CMAKE_INSTALL_PREFIX 来使路径绝对;如果 DESTINATION 是相对路径,则默认使用此前缀。

如果给出绝对路径(带有前导斜杠或驱动器号),则按原样使用。

版本 3.31 中已更改: <dir> 将根据 cmake_path() 命令的 规范化规则 进行规范化。

PERMISSIONS <permission>...

指定安装文件的权限。有效权限是 OWNER_READOWNER_WRITEOWNER_EXECUTEGROUP_READGROUP_WRITEGROUP_EXECUTEWORLD_READWORLD_WRITEWORLD_EXECUTESETUIDSETGID。在某些平台上不适用的权限将被忽略。

如果此选项在单个调用中多次使用,则其权限列表会累加。如果 install(TARGETS) 调用使用 <artifact-kind> 参数,则为每种工件类型累加一个单独的权限列表。

CONFIGURATIONS <config>...

指定安装规则适用的构建配置列表(Debug、Release 等)。

如果此选项在单个调用中多次使用,则其配置列表会累加。如果 install(TARGETS) 调用使用 <artifact-kind> 参数,则为每种工件类型累加一个单独的配置列表。

COMPONENT <component>

指定与安装规则关联的安装组件名称,例如 RuntimeDevelopment。在特定组件的安装过程中,只会执行与给定组件名称关联的安装规则。在完整安装过程中,所有组件都会被安装,除非被标记为 EXCLUDE_FROM_ALL。如果未提供 COMPONENT,则会创建一个名为“Unspecified”的默认组件。默认组件名称可以通过 CMAKE_INSTALL_DEFAULT_COMPONENT_NAME 变量控制。

安装组件随后可由 cmake --install 命令的 --component 选项和 CPackComponent 模块使用。全局目标 list_install_components 列出所有可用组件。

EXCLUDE_FROM_ALL

3.6 版本新增。

指定文件不包含在完整安装中,仅作为组件特定安装的一部分进行安装

OPTIONAL

指定要安装的文件不存在时不会出错。

版本 3.1 中已添加: 安装文件的命令签名可能会在安装过程中打印消息。使用 CMAKE_INSTALL_MESSAGE 变量来控制打印哪些消息。

版本 3.11 中已添加: install() 的许多变体都会隐式创建包含已安装文件的目录。如果设置了 CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS,则这些目录将以指定的权限创建。否则,它们将根据类 Unix 平台上的 uname 规则创建。Windows 平台不受影响。

签名

install(TARGETS <target>... [...])

安装目标 输出工件 和相关文件

install(TARGETS <target>... [EXPORT <export-name>]
        [RUNTIME_DEPENDENCIES <arg>...|RUNTIME_DEPENDENCY_SET <set-name>]
        [<artifact-option>...]
        [<artifact-kind> <artifact-option>...]...
        [INCLUDES DESTINATION [<dir> ...]]
        )

其中 <artifact-option>... 组可能包含

[DESTINATION <dir>]
[PERMISSIONS <permission>...]
[CONFIGURATIONS <config>...]
[COMPONENT <component>]
[NAMELINK_COMPONENT <component>]
[OPTIONAL] [EXCLUDE_FROM_ALL]
[NAMELINK_ONLY|NAMELINK_SKIP]

第一个 <artifact-option>... 组适用于没有在同一调用中稍后指定专用组的目标 输出工件

每个 <artifact-kind> <artifact-option>... 组适用于指定工件类型的 输出工件

ARCHIVE

此类型的目标工件包括

  • 静态库(macOS 上标记为 FRAMEWORK 的除外,见下文);

  • DLL 导入库(在所有基于 Windows 的系统上,包括 Cygwin;它们具有扩展名 .lib,与进入 RUNTIME.dll 库相对);

  • 在 AIX 上,使用 ENABLE_EXPORTS 启用的可执行文件创建的链接器导入文件

  • 在 macOS 上,使用 ENABLE_EXPORTS 启用的共享库创建的链接器导入文件(macOS 上标记为 FRAMEWORK 的除外,见下文)。

LIBRARY

此类型的目标工件包括

  • 共享库,除了

    • DLL(这些进入 RUNTIME,见下文),

    • 在 macOS 上标记为 FRAMEWORK(见下文)时。

RUNTIME

此类型的目标工件包括

  • 可执行文件(macOS 上标记为 MACOSX_BUNDLE 的除外,见下文的 BUNDLE);

  • DLL(在所有基于 Windows 的系统上,包括 Cygwin;请注意,配套的导入库是 ARCHIVE 类型的)。

OBJECTS

版本 3.9 中添加。

对象库关联的目标文件。

FRAMEWORK

标记有 FRAMEWORK 属性的静态库和共享库在 macOS 上都被视为 FRAMEWORK 目标。

BUNDLE

标记有 MACOSX_BUNDLE 属性的可执行文件在 macOS 上被视为 BUNDLE 目标。

PUBLIC_HEADER

与库关联的任何 PUBLIC_HEADER 文件都会安装到非 Apple 平台上的 PUBLIC_HEADER 参数指定的目录。此参数定义的规则对于 Apple 平台上的 FRAMEWORK 库将被忽略,因为相关文件会安装到框架文件夹内的适当位置。请参阅 PUBLIC_HEADER 获取详细信息。

PRIVATE_HEADER

PUBLIC_HEADER 类似,但用于 PRIVATE_HEADER 文件。请参阅 PRIVATE_HEADER 获取详细信息。

RESOURCE

PUBLIC_HEADERPRIVATE_HEADER 类似,但用于 RESOURCE 文件。请参阅 RESOURCE 获取详细信息。

FILE_SET <set-name>

在版本 3.23 中添加。

文件集通过 target_sources(FILE_SET) 命令定义。如果文件集 <set-name> 存在且为 PUBLICINTERFACE,则该集中的任何文件都将安装在目标位置(见下文)。将保留相对于文件集基本目录的目录结构。例如,添加到文件集的文件 /blah/include/myproj/here.h,其基本目录为 /blah/include,将被安装到目标下方 myproj/here.h

CXX_MODULES_BMI

版本 3.28 新增。

来自 CXX_MODULES 类型文件集的 PUBLIC 源的任何模块文件都将安装到指定 DESTINATION。所有模块都直接放置在目标位置,因为没有从模块名称派生目录结构。可以使用空的 DESTINATION 来禁止安装这些文件(用于通用代码)。

对于常规可执行文件、静态库和共享库,不要求 DESTINATION 参数。对于这些目标类型,当省略 DESTINATION 时,将从 GNUInstallDirs 的相应变量获取默认目标位置,或者在未定义该变量时设置为内置默认值。文件集以及通过 PUBLIC_HEADERPRIVATE_HEADER 目标属性与已安装目标关联的公共和私有头文件也是如此。模块库、Apple 包和框架始终需要提供目标位置。可以省略接口库和对象库的目标位置,但它们的处理方式不同(请参阅本节末尾关于此主题的讨论)。

对于 DLL 平台上的共享库,如果未指定 RUNTIMEARCHIVE 目标位置,则 RUNTIMEARCHIVE 组件都将安装到它们的默认目标位置。如果指定了 RUNTIMEARCHIVE 目标位置,则该组件将安装到该目标位置,而另一个组件不被安装。如果同时指定了 RUNTIMEARCHIVE 目标位置,则两个组件都将安装到它们各自的目标位置。

下表显示了目标类型及其关联的变量和内置默认值,当未给出目标位置时适用

目标类型

GNUInstallDirs 变量

内置默认值

RUNTIME

${CMAKE_INSTALL_BINDIR}

bin

LIBRARY

${CMAKE_INSTALL_LIBDIR}

lib

ARCHIVE

${CMAKE_INSTALL_LIBDIR}

lib

PRIVATE_HEADER

${CMAKE_INSTALL_INCLUDEDIR}

include

PUBLIC_HEADER

${CMAKE_INSTALL_INCLUDEDIR}

include

FILE_SET(类型 HEADERS

${CMAKE_INSTALL_INCLUDEDIR}

include

希望遵循将头文件安装到项目特定子目录的常见做法的项目,可能更倾向于使用具有适当路径和基本目录的文件集。否则,它们必须提供 DESTINATION 而不是依赖上述选项(见下例)。

为了使包符合分发文件系统布局策略,如果项目必须指定 DESTINATION,强烈建议它们使用以适当的相对 GNUInstallDirs 变量开头的路径。这允许包维护者通过设置适当的缓存变量来控制安装目标位置。以下示例演示了如何在不使用文件集的情况下,将静态库安装到 GNUInstallDirs 提供的默认目标位置,但其头文件安装到项目特定的子目录中。

add_library(mylib STATIC ...)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER mylib.h)
include(GNUInstallDirs)
install(TARGETS mylib
        PUBLIC_HEADER
          DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproj
)

除了上面列出的 通用选项 之外,每个目标还可以接受以下附加参数

NAMELINK_COMPONENT

3.12 版本新增。

在某些平台上,版本化的共享库有一个符号链接,例如

lib<name>.so -> lib<name>.so.1

其中 lib<name>.so.1 是库的 soname,lib<name>.so 是一个“namelink”,允许链接器在给定 -l<name> 时找到该库。NAMELINK_COMPONENT 选项类似于 COMPONENT 选项,但它会更改共享库 namelink 的安装组件(如果生成了 namelink)。如果未指定,则默认为 COMPONENT 的值。在 LIBRARY 块之外使用此参数是错误的。

版本 3.27 中已更改: 此参数也可用于 ARCHIVE 块,以管理在 macOS 上为启用了 ENABLE_EXPORTS 的共享库创建的链接器导入文件。

请参阅 示例:安装具有每个工件组件的目标 以获取使用 NAMELINK_COMPONENT 的示例。

此选项通常用于具有单独运行时包和开发包的包管理器。例如,在 Debian 系统上,库应位于运行时包中,而头文件和 namelink 应位于开发包中。

有关创建版本化共享库的详细信息,请参阅 VERSIONSOVERSION 目标属性。

NAMELINK_ONLY

此选项导致仅安装 namelink(当库目标被安装时)。在没有 namelink 的版本化共享库的平台上,或者当库未版本化时,NAMELINK_ONLY 选项不安装任何内容。在 LIBRARY 块之外使用此参数是错误的。

版本 3.27 中已更改: 此参数也可用于 ARCHIVE 块,以管理在 macOS 上为启用了 ENABLE_EXPORTS 的共享库创建的链接器导入文件。

当给出 NAMELINK_ONLY 时,可以使用 NAMELINK_COMPONENTCOMPONENT 来指定 namelink 的安装组件,但通常应优先使用 COMPONENT

NAMELINK_SKIP

类似于 NAMELINK_ONLY,但效果相反:当安装库目标时,它会安装除 namelink 之外的库文件。当未给出 NAMELINK_ONLYNAMELINK_SKIP 时,会安装两个部分。在没有 namelink 的版本化共享库的平台上,或者当库未版本化时,NAMELINK_SKIP 会安装库。在 LIBRARY 块之外使用此参数是错误的。

版本 3.27 中已更改: 此参数也可用于 ARCHIVE 块,以管理在 macOS 上为启用了 ENABLE_EXPORTS 的共享库创建的链接器导入文件。

如果指定了 NAMELINK_SKIP,则 NAMELINK_COMPONENT 无效。不建议将 NAMELINK_SKIPNAMELINK_COMPONENT 结合使用。

install(TARGETS) 命令还可以接受以下顶层选项

EXPORT

此选项将安装的目标文件与名为 <export-name> 的导出关联起来。它必须出现在任何目标选项之前。要实际安装导出文件本身,请调用 install(EXPORT),如下文所述。请参阅 EXPORT_NAME 目标属性的文档以更改导出目标的名称。

如果使用 EXPORT 并且目标包含 PUBLICINTERFACE 文件集,则所有这些都必须使用 FILE_SET 参数指定。目标关联的所有 PUBLICINTERFACE 文件集都将包含在导出中。

INCLUDES DESTINATION

此选项指定一个目录列表,该列表将添加到 <targets> 在通过 install(EXPORT) 命令导出时,其 INTERFACE_INCLUDE_DIRECTORIES 目标属性中。如果指定了相对路径,则它相对于 $<INSTALL_PREFIX>

install() 各子命令的其他 DESTINATION 参数不同,INCLUDES DESTINATION 后的路径按原样使用。它们不会被规范化,也不会假定为已规范化,尽管建议使用规范化形式提供(请参阅 规范化)。

RUNTIME_DEPENDENCY_SET <set-name>

3.21 版本新增。

此选项导致已安装的可执行文件、共享库和模块目标的所有运行时依赖项被添加到指定的运行时依赖项集中。然后可以使用 install(RUNTIME_DEPENDENCY_SET) 命令安装此集。

此关键字和 RUNTIME_DEPENDENCIES 关键字是互斥的。

RUNTIME_DEPENDENCIES <arg>...

3.21 版本新增。

此选项导致已安装的可执行文件、共享库和模块目标的所有运行时依赖项与目标本身一起安装。RUNTIMELIBRARYFRAMEWORK 和通用参数用于确定这些依赖项安装的属性(DESTINATIONCOMPONENT 等)。

RUNTIME_DEPENDENCIES 在语义上等同于以下调用对

install(TARGETS ... RUNTIME_DEPENDENCY_SET <set-name>)
install(RUNTIME_DEPENDENCY_SET <set-name> <arg>...)

其中 <set-name> 将是一个随机生成的集名称。<arg>... 可以包括 install(RUNTIME_DEPENDENCY_SET) 命令支持的以下任何关键字

  • DIRECTORIES

  • PRE_INCLUDE_REGEXES

  • PRE_EXCLUDE_REGEXES

  • POST_INCLUDE_REGEXES

  • POST_EXCLUDE_REGEXES

  • POST_INCLUDE_FILES

  • POST_EXCLUDE_FILES

关键字 RUNTIME_DEPENDENCIESRUNTIME_DEPENDENCY_SET 是互斥的。

可以列出接口库作为要安装的目标。它们不安装任何工件,但会包含在相关的 EXPORT 中。如果列出了对象库但未为其对象文件指定目标位置,则它们将作为接口库导出。这足以满足其他链接到对象库的目标的传递使用要求。

安装具有 EXCLUDE_FROM_ALL 目标属性设置为 TRUE 的目标具有未定义的行为。

版本 3.3 中已添加: 作为 DESTINATION 参数给出的安装目标可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

版本 3.13 中已添加: install(TARGETS) 可以安装在其他目录中创建的目标。在使用此类跨目录安装规则时,从子目录运行 make install(或类似命令)不能保证其他目录中的目标是最新的。您可以使用 target_link_libraries()add_dependencies() 来确保在运行子目录特定的安装规则之前构建这些目录外的目标。

install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])

3.21 版本新增。

安装导入目标的文件运行时工件

install(IMPORTED_RUNTIME_ARTIFACTS <target>...
        [RUNTIME_DEPENDENCY_SET <set-name>]
        [[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
         [DESTINATION <dir>]
         [PERMISSIONS <permission>...]
         [CONFIGURATIONS <config>...]
         [COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
        ] [...]
        )

`IMPORTED_RUNTIME_ARTIFACTS` 形式指定安装导入目标的运行时工件的规则。项目可以这样做,如果它们想将外部可执行文件或模块捆绑到它们的安装中。`LIBRARY`、`RUNTIME`、`FRAMEWORK` 和 `BUNDLE` 参数的语义与 `TARGETS` 模式中的相同。只有导入目标的文件运行时工件会被安装(除了 `FRAMEWORK` 库、`MACOSX_BUNDLE` 可执行文件和 `BUNDLE` CFBundles 的情况)。例如,与 DLL 关联的头文件和导入库不会被安装。对于 `FRAMEWORK` 库、`MACOSX_BUNDLE` 可执行文件和 `BUNDLE` CFBundles,将安装整个目录。

`RUNTIME_DEPENDENCY_SET` 选项会将导入的 targets 的运行时工件(可执行文件、共享库和模块库)添加到 `` 运行时依赖集中。然后可以使用 `install(RUNTIME_DEPENDENCY_SET)` 命令安装此集。

install(FILES <file>... [...])
install(PROGRAMS <program>... [...])

注意

如果安装头文件,请考虑使用由 target_sources(FILE_SET) 定义的文件集。文件集将头文件与目标关联,并在目标安装时一起安装。

安装文件或程序

install(<FILES|PROGRAMS> <file>...
        TYPE <type> | DESTINATION <dir>
        [PERMISSIONS <permission>...]
        [CONFIGURATIONS <config>...]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

`FILES` 形式指定项目文件的安装规则。作为相对路径给出的文件名是相对于当前源目录解释的。默认情况下,此形式安装的文件将获得 OWNER_WRITEOWNER_READGROUP_READWORLD_READ 权限,如果未给出 PERMISSIONS 参数。

`PROGRAMS` 形式与 `FILES` 形式相同,只是已安装文件的默认权限还包括 OWNER_EXECUTEGROUP_EXECUTEWORLD_EXECUTE。此形式用于安装非目标程序,例如 shell 脚本。使用 `TARGETS` 形式安装项目中构建的目标。

传递给 FILESPROGRAMSfiles... 列表可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。但是,如果任何项以生成器表达式开头,则它必须求值为一个完整路径。

可选的 RENAME <name> 参数用于指定一个与原始文件名不同的已安装文件名。仅当命令安装单个文件时才允许重命名。

必须提供 TYPEDESTINATION,但不能同时提供两者。TYPE 参数指定正在安装的文件的通用文件类型。然后将自动设置目标位置,方法是采用 GNUInstallDirs 的相应变量,或者如果未定义该变量,则使用内置默认值。下表显示了支持的文件类型及其相应的变量和内置默认值。项目可以提供 DESTINATION 参数而不是文件类型,如果它们希望显式定义安装目标位置。

TYPE 参数

GNUInstallDirs 变量

内置默认值

BIN

${CMAKE_INSTALL_BINDIR}

bin

SBIN

${CMAKE_INSTALL_SBINDIR}

sbin

LIB

${CMAKE_INSTALL_LIBDIR}

lib

INCLUDE

${CMAKE_INSTALL_INCLUDEDIR}

include

SYSCONF

${CMAKE_INSTALL_SYSCONFDIR}

etc

SHAREDSTATE

${CMAKE_INSTALL_SHARESTATEDIR}

com

LOCALSTATE

${CMAKE_INSTALL_LOCALSTATEDIR}

var

RUNSTATE

${CMAKE_INSTALL_RUNSTATEDIR}

<LOCALSTATE dir>/run

DATA

${CMAKE_INSTALL_DATADIR}

<DATAROOT dir>

INFO

${CMAKE_INSTALL_INFODIR}

<DATAROOT dir>/info

LOCALE

${CMAKE_INSTALL_LOCALEDIR}

<DATAROOT dir>/locale

MAN

${CMAKE_INSTALL_MANDIR}

<DATAROOT dir>/man

DOC

${CMAKE_INSTALL_DOCDIR}

<DATAROOT dir>/doc

LIBEXEC

${CMAKE_INSTALL_LIBEXECDIR}

libexec

希望遵循将头文件安装到项目特定子目录的常见做法的项目,需要提供一个目标位置,而不是依赖上述选项。使用文件集作为头文件而不是 install(FILES) 会更好(请参阅 target_sources(FILE_SET))。

请注意,某些类型的内置默认值使用 DATAROOT 目录作为前缀。DATAROOT 前缀的计算方式与类型类似,变量为 CMAKE_INSTALL_DATAROOTDIR,内置默认值为 share。您不能将 DATAROOT 用作 TYPE 参数;请使用 DATA

为了使包符合分发文件系统布局策略,如果项目必须指定 DESTINATION,强烈建议它们使用以适当的相对 GNUInstallDirs 变量开头的路径。这允许包维护者通过设置适当的缓存变量来控制安装目标位置。以下示例演示了如何在安装图像到项目特定的文档子目录时遵循此建议

include(GNUInstallDirs)
install(FILES logo.png
        DESTINATION ${CMAKE_INSTALL_DOCDIR}/myproj
)

版本 3.4 中已添加: 作为 DESTINATION 参数给出的安装目标可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

版本 3.20 中已添加: 作为 RENAME 参数给出的安装重命名可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

版本 3.31 中已添加: TYPE 参数现在支持 LIBEXEC 类型。

install(DIRECTORY <dir>... [...])

注意

要安装目录的头文件子树,请考虑使用由 target_sources(FILE_SET) 定义的文件集。文件集不仅保留目录结构,还将头文件与目标关联,并在目标安装时一起安装。

安装一个或多个目录的内容

install(DIRECTORY <dir>...
        TYPE <type> | DESTINATION <dir>
        [FILE_PERMISSIONS <permission>...]
        [DIRECTORY_PERMISSIONS <permission>...]
        [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
        [CONFIGURATIONS <config>...]
        [COMPONENT <component>] [EXCLUDE_FROM_ALL]
        [FILES_MATCHING]
        [<match-rule> <match-option>...]...
        )

`DIRECTORY` 形式将一个或多个目录的内容安装到指定的目标位置。目录结构将按原样复制到目标位置。

必须提供 TYPEDESTINATION,但不能同时提供两者。如果未提供权限,则文件将获得命令的 FILES 形式中指定的默认权限,目录将获得命令的 PROGRAMS 形式中指定的默认权限。

选项包括

<dir>...

要安装的目录列表。

每个目录名称的最后一个组件将被追加到目标目录,但末尾的斜杠可用于避免此行为,因为它会使最后一个组件为空。作为相对路径给出的目录名称是相对于当前源目录解释的。如果未给出输入目录名称,则将创建目标目录,但不会在其中安装任何内容。

版本 3.5 中已添加: <dir>... 列表可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

TYPE <type>

指定列出的目录中正在安装的文件的通用文件类型。然后将自动设置目标位置,方法是采用 GNUInstallDirs 的相应变量,或者如果未定义该变量,则使用内置默认值。下表显示了支持的文件类型及其相应的变量和内置默认值。项目可以提供 DESTINATION 参数而不是文件类型,如果它们希望显式定义安装目标位置。

TYPE 参数

GNUInstallDirs 变量

内置默认值

BIN

${CMAKE_INSTALL_BINDIR}

bin

SBIN

${CMAKE_INSTALL_SBINDIR}

sbin

LIB

${CMAKE_INSTALL_LIBDIR}

lib

INCLUDE

${CMAKE_INSTALL_INCLUDEDIR}

include

SYSCONF

${CMAKE_INSTALL_SYSCONFDIR}

etc

SHAREDSTATE

${CMAKE_INSTALL_SHARESTATEDIR}

com

LOCALSTATE

${CMAKE_INSTALL_LOCALSTATEDIR}

var

RUNSTATE

${CMAKE_INSTALL_RUNSTATEDIR}

<LOCALSTATE dir>/run

DATA

${CMAKE_INSTALL_DATADIR}

<DATAROOT dir>

INFO

${CMAKE_INSTALL_INFODIR}

<DATAROOT dir>/info

LOCALE

${CMAKE_INSTALL_LOCALEDIR}

<DATAROOT dir>/locale

MAN

${CMAKE_INSTALL_MANDIR}

<DATAROOT dir>/man

DOC

${CMAKE_INSTALL_DOCDIR}

<DATAROOT dir>/doc

LIBEXEC

${CMAKE_INSTALL_LIBEXECDIR}

libexec

请注意,某些类型的内置默认值使用 DATAROOT 目录作为前缀。DATAROOT 前缀的计算方式与类型类似,变量为 CMAKE_INSTALL_DATAROOTDIR,内置默认值为 share。您不能将 DATAROOT 用作 TYPE 参数;请使用 DATA

版本 3.31 中已添加: LIBEXEC 类型。

DESTINATION <dir>

目标目录,如 通用选项 中所述。

为了使包符合分发文件系统布局策略,如果项目必须指定 DESTINATION,强烈建议它们使用以适当的相对 GNUInstallDirs 变量开头的路径。这允许包维护者通过设置适当的缓存变量来控制安装目标位置。

版本 3.4 中已添加: 目标 <dir> 可以使用“生成器表达式”,语法为 $<...>。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

FILE_PERMISSIONS <permission>...

指定赋予目标位置文件的权限,其中 <permission> 名称在 通用选项 中有所说明。

DIRECTORY_PERMISSIONS <permission>...

指定赋予目标位置目录的权限,其中 <permission> 名称在 通用选项 中有所说明。

USE_SOURCE_PERMISSIONS

如果指定了此选项,并且未指定 FILE_PERMISSIONS,则文件权限将从源目录结构中复制。

MESSAGE_NEVER

版本 3.1 中新增。

禁用文件安装状态输出。

FILES_MATCHING

此选项可以放在第一个 <match-rule> 之前,以禁止安装不匹配任何表达式的文件(但不包括目录)。例如,代码

install(DIRECTORY src/ DESTINATION doc/myproj
        FILES_MATCHING PATTERN "*.png")

将从源树中提取并安装图像。

<match-rule> <match-option>...

可以使用规则以精细粒度控制目录的安装,这些规则匹配输入目录中遇到的目录或文件。它们可用于将某些选项(见下文)应用于匹配的文件和目录的子集。所有文件和目录都会被安装,无论它们是否被匹配,除非给出上述 FILES_MATCHING 选项。

每个输入文件或目录的完整路径(使用正斜杠)都可以与 <match-rule> 匹配

PATTERN <pattern>

使用 globbing 模式匹配完整文件名。完整路径中匹配模式的部分必须出现在文件名末尾,并且前面有一个斜杠(该斜杠不属于模式)。

REGEX <regex>

使用正则表达式匹配文件完整路径的任何部分。可以使用 /$ 将匹配限制在路径末尾。

每个 <match-rule> 后面可以跟 <match-option> 参数。匹配选项适用于规则匹配的文件或目录。匹配选项是

EXCLUDE

将匹配的文件或目录排除在安装之外。

PERMISSIONS <permission>...

覆盖匹配的文件或目录的权限设置。

例如,以下代码:

install(DIRECTORY icons scripts/ DESTINATION share/myproj
        PATTERN "CVS" EXCLUDE
        PATTERN "scripts/*"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                    GROUP_EXECUTE GROUP_READ)

将 `icons` 目录安装到 `share/myproj/icons`,将 `scripts` 目录安装到 `share/myproj`。图标将获得默认文件权限,脚本将获得特定权限,任何 `CVS` 目录将被排除。

install(SCRIPT <file> [...])
install(CODE <code> [...])

在安装期间调用 CMake 脚本或代码

install([[SCRIPT <file>] [CODE <code>]]
        [ALL_COMPONENTS | COMPONENT <component>]
        [EXCLUDE_FROM_ALL] [...])

`SCRIPT` 形式将在安装期间调用给定的 CMake 脚本文件。如果脚本文件名是相对路径,它将相对于当前源目录进行解释。CODE 形式将在安装期间调用给定的 CMake 代码。代码指定为双引号字符串中的单个参数。例如,代码

install(CODE "message(\"Sample install message.\")")

将在安装期间打印消息。

版本 3.21 中已添加: 当给出 ALL_COMPONENTS 选项时,自定义安装脚本代码将为组件特定安装的每个组件执行。此选项与 COMPONENT 选项互斥。

版本 3.14 中已添加: <file><code> 可以使用“生成器表达式”,语法为 $<...>(对于 <file>,这指的是文件名中的用法,而不是文件内容)。有关可用表达式,请参阅 cmake-generator-expressions(7) 手册。

install(EXPORT <export-name> [...])

安装一个 CMake 文件,为依赖项目导出目标

install(EXPORT <export-name> DESTINATION <dir>
        [NAMESPACE <namespace>] [FILE <name>.cmake]
        [PERMISSIONS <permission>...]
        [CONFIGURATIONS <config>...]
        [CXX_MODULES_DIRECTORY <directory>]
        [EXPORT_LINK_INTERFACE_LIBRARIES]
        [COMPONENT <component>]
        [EXCLUDE_FROM_ALL]
        [EXPORT_PACKAGE_DEPENDENCIES])
install(EXPORT_ANDROID_MK <export-name> DESTINATION <dir> [...])

`EXPORT` 形式生成并安装一个 CMake 文件,其中包含将安装树中的目标导入到另一个项目中的代码。目标安装通过上面文档化的 install(TARGETS) 签名的 EXPORT 选项与导出 <export-name> 相关联。NAMESPACE 选项会将 `` 添加到导入文件中目标名称的前面。默认情况下,生成的文件的名称将是 `.cmake`,但可以使用 `FILE` 选项指定不同的名称。传递给 `FILE` 选项的值必须是带有 `.cmake` 扩展名的文件名。

如果给出了 CONFIGURATIONS 选项,则仅在安装命名配置之一时安装该文件。此外,生成的导入文件将仅引用匹配的目标配置。请参阅 CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> 变量以将依赖项目的配置映射到已安装的配置。如果存在 EXPORT_LINK_INTERFACE_LIBRARIES 关键字,则在策略 CMP0022NEW 时,将导出与 `(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?` 匹配的属性的内容。

注意

已安装的 `.cmake` 文件可能附带额外的每个配置的 `-*.cmake` 文件,供 globbing 加载。不要使用与包名称相同的导出名称,同时安装 `-config.cmake` 文件,否则后者可能会被 glob 错误匹配并加载。

当给出 COMPONENT 选项时,列出的 `` 隐式依赖于导出集中提到的所有组件。导出的 `.cmake` 文件将要求导出此集中的每个组件都存在,以便依赖项目能够正确构建。例如,一个项目可能定义了 `Runtime` 和 `Development` 组件,共享库进入 `Runtime` 组件,静态库和头文件进入 `Development` 组件。导出集通常也是 `Development` 组件的一部分,但它将导出 `Runtime` 和 `Development` 两个组件的目标。因此,如果安装了 `Development` 组件,则需要安装 `Runtime` 组件,反之则不然。如果安装了 `Development` 组件但未安装 `Runtime` 组件,则尝试与之链接的依赖项目将出现构建错误。像 APT 和 RPM 这样的包管理器通常通过在包元数据中将 `Runtime` 组件列为 `Development` 组件的依赖项来处理此问题,从而确保在存在头文件和 CMake 导出文件的情况下始终安装库。

版本 3.7 中已添加: 除了 CMake 语言文件外,还可以使用 `EXPORT_ANDROID_MK` 模式来指定导出到 Android NDK 构建系统。此模式接受与普通导出模式相同的选项。Android NDK 支持使用预构建库,包括静态库和共享库。这允许 CMake 构建项目的库,并使它们能够被 NDK 构建系统使用,同时包括使用这些库所需的传递依赖项、包含标志和定义。

CXX_MODULES_DIRECTORY

版本 3.28 新增。

指定一个子目录来存储导出集中的 C++ 模块信息。此目录将填充文件,这些文件会将必要的目标属性信息添加到相关目标中。请注意,如果没有这些信息,导出集中的任何 C++ 模块都将不支持在消费目标中导入。

EXPORT_PACKAGE_DEPENDENCIES

注意

实验性。受 CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES 控制。

指定应导出 find_dependency() 调用。如果指定了此参数,CMake 会检查导出集中的所有目标,并收集它们的 INTERFACE 链接目标。如果任何此类目标是使用 find_package() 找到的,或者具有 EXPORT_FIND_PACKAGE_NAME 属性集,并且该包依赖项未通过将 ENABLED OFF 传递给 export(SETUP) 禁用,那么将写入一个 find_dependency() 调用,其中包含目标相应的包名称、REQUIRED 参数以及 export(SETUP)EXTRA_ARGS 参数指定的任何附加参数。通过将 ENABLED ON 传递给 export(SETUP) 手动指定的任何包依赖项也将被添加,即使导出的目标不依赖于它们中的任何一个。

以下顺序写入 find_dependency() 调用

  1. export(SETUP) 中列出的任何包依赖项都按其首次指定的顺序写入,无论它们是否包含已导出目标的 INTERFACE 依赖项。

  2. 包含已导出目标的 INTERFACE 链接依赖项并且从未在 export(SETUP) 中指定的任何包依赖项将按其首次找到的顺序写入。

EXPORT` 形式有助于外部项目使用当前项目构建和安装的目标。例如,代码

install(TARGETS myexe EXPORT myproj DESTINATION bin)
install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
install(EXPORT_ANDROID_MK myproj DESTINATION share/ndk-modules)

会将可执行文件 myexe 安装到 `<prefix>/bin`,并将用于在文件 `<prefix>/lib/myproj/myproj.cmake` 和 `<prefix>/share/ndk-modules/Android.mk` 中导入它的代码。外部项目可以使用 include 命令加载此文件,并使用导入的目标名称 `mp_myexe` 从安装树中引用 `myexe` 可执行文件,就好像该目标在其自己的树中构建一样。

install(PACKAGE_INFO <package-name> [...])

在版本 3.31 中添加。

注意

实验性。受 CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO 控制。

安装一个 通用包规范 (Common Package Specification) 文件,为依赖项目导出目标

install(PACKAGE_INFO <package-name> EXPORT <export-name>
        [PROJECT <project-name>|NO_PROJECT_METADATA]
        [APPENDIX <appendix-name>]
        [DESTINATION <dir>]
        [LOWER_CASE_FILE]
        [VERSION <version>
         [COMPAT_VERSION <version>]
         [VERSION_SCHEMA <string>]]
        [DEFAULT_TARGETS <target>...]
        [DEFAULT_CONFIGURATIONS <config>...]
        [LICENSE <license-string>]
        [DEFAULT_LICENSE <license-string>]
        [DESCRIPTION <description-string>]
        [HOMEPAGE_URL <url-string>]
        [PERMISSIONS <permission>...]
        [CONFIGURATIONS <config>...]
        [COMPONENT <component>]
        [EXCLUDE_FROM_ALL])

PACKAGE_INFO 命令生成并安装一个通用的包规范文件,该文件描述已安装的目标,以便其他项目可以使用它们。目标安装通过上面文档中记录的 install(TARGETS) 命令签名的 EXPORT 选项与导出名 <export-name> 相关联。与 install(EXPORT) 不同,此信息不以 CMake 代码的形式表达,并且可以被 CMake 以外的工具使用。当导入到另一个 CMake 项目时,导入的目标将以 <package-name>:: 作为前缀。默认情况下,生成的文件将命名为 <package-name>[-<appendix-name>].cps。如果指定了 LOWER_CASE_FILE,则包名在磁盘上的表示(包括文件名和安装目标)将首先转换为小写。

如果未指定 DESTINATION,则使用特定于平台的默认值。

可以使用多个选项来指定包元数据

VERSION <version>

包的版本。 <version> 应符合指定的模式。有关包版本在使用者请求包时如何使用,请参阅 版本选择 (CPS)

COMPAT_VERSION <version>

包提供兼容性的最旧版本。

如果未指定,COMPAT_VERSION 将隐式等于包的 VERSION,这意味着不提供向后兼容性。

VERSION_SCHEMA <schema>

包的版本号(包括 VERSIONCOMPAT_VERSION)遵循的模式。虽然如果未提供此选项,则不会将任何模式写入 .cps 文件,但 CPS 指定在这种情况下假定模式为 simple。有关支持的模式列表以及更多详细信息,请参阅 version_schema,但请注意,该规范可能包含 CMake 不支持的模式。有关 find_package() 支持的模式列表,请参阅 版本选择 (CPS)

DEFAULT_TARGETS <target>...

当使用者请求链接到包名而不是特定组件时要使用的目标。

DEFAULT_CONFIGURATIONS <config>...

当不存在精确匹配或使用者配置到包可用配置的映射时,使用者应优先使用的配置的有序列表。如果未指定,CMake 将以未指定的顺序回退到包的可用配置。

LICENSE <license-string>

版本 4.2 中添加。

一个 System Package Data Exchange (SPDX) License Expression,它描述了整个项目的许可证,包括随项目分发的文档、资源或其他材料,以及软件构件。有关常用许可证及其标识符的列表,请参阅 SPDX 许可证列表

单个组件的许可证取自其各自目标的 SPDX_LICENSE 属性。

DEFAULT_LICENSE <license-string>

版本 4.2 中添加。

一个 System Package Data Exchange (SPDX) License Expression,它描述了任何未另行指定其许可证的组件的许可证。

DESCRIPTION <description-string>

在 4.1 版本中新增。

项目的说明性描述。建议此描述为相对较短的字符串,通常不超过几个词。

HOMEPAGE_URL <url-string>

在 4.1 版本中新增。

项目的说明性规范主页 URL。

默认情况下,如果指定的 <package-name> 与当前 CMake 的 PROJECT_NAME 匹配,则包元数据将从项目继承。 PROJECT <project-name> 选项可用于指定从中继承元数据的不同项目。如果指定了 NO_PROJECT_METADATA,则会自动禁用包元数据的继承。在任何情况下,在 install 命令中指定的任何元数据值都将具有优先权。

如果指定了 APPENDIX,则不会生成顶级包规范,而是将指定的 targets 作为附录导出到命名包。附录可用于将不常用的 targets(及其外部依赖项)与包的其余部分分开。这使得使用者可以忽略其不使用的 targets 的传递性依赖项,并且还允许单个逻辑“包”由多个构建树生成的构件组成。

附录不允许更改基本的包元数据;因此,PROJECTVERSIONCOMPAT_VERSIONVERSION_SCHEMADEFAULT_TARGETSDEFAULT_CONFIGURATIONS 的任何一项都不能与 APPENDIX 结合使用。此外,强烈建议在主包和任何附录之间保持 LOWER_CASE_FILE 的使用一致。

install(RUNTIME_DEPENDENCY_SET <set-name> [...])

3.21 版本新增。

安装运行时依赖项集

install(RUNTIME_DEPENDENCY_SET <set-name>
        [[LIBRARY|RUNTIME|FRAMEWORK]
         [DESTINATION <dir>]
         [PERMISSIONS <permission>...]
         [CONFIGURATIONS <config>...]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
        ] [...]
        [PRE_INCLUDE_REGEXES <regex>...]
        [PRE_EXCLUDE_REGEXES <regex>...]
        [POST_INCLUDE_REGEXES <regex>...]
        [POST_EXCLUDE_REGEXES <regex>...]
        [POST_INCLUDE_FILES <file>...]
        [POST_EXCLUDE_FILES <file>...]
        [DIRECTORIES <dir>...]
        )

安装先前由一个或多个 install(TARGETS)install(IMPORTED_RUNTIME_ARTIFACTS) 命令创建的运行时依赖项集。属于运行时依赖项集的目标的依赖项将安装到 RUNTIME 目标和组件(在 DLL 平台上),以及安装到 LIBRARY 目标和组件(在非 DLL 平台上)。macOS 框架将安装到 FRAMEWORK 目标和组件。构建树内构建的目标永远不会作为运行时依赖项安装,其自身依赖项也不会,除非这些目标本身已使用 install(TARGETS) 安装。

生成的安装脚本调用构建树文件上的 file(GET_RUNTIME_DEPENDENCIES) 来计算运行时依赖项。构建树可执行文件作为 EXECUTABLES 参数传递,构建树共享库作为 LIBRARIES 参数传递,构建树模块作为 MODULES 参数传递。在 macOS 上,如果其中一个可执行文件是 MACOSX_BUNDLE,则该可执行文件将作为 BUNDLE_EXECUTABLE 参数传递。在 macOS 上,运行时依赖项集中最多可以有一个这样的捆绑可执行文件。MACOSX_BUNDLE 属性对其他平台没有影响。请注意,file(GET_RUNTIME_DEPENDENCIES) 仅支持收集 Windows、Linux 和 macOS 平台的运行时依赖项,因此 install(RUNTIME_DEPENDENCY_SET) 也具有相同的限制。

以下子参数将作为相应的参数传递给 file(GET_RUNTIME_DEPENDENCIES)(对于提供非空目录列表、正则表达式或文件的参数)。它们都支持 生成器表达式

  • DIRECTORIES <dir>...

  • PRE_INCLUDE_REGEXES <regex>...

  • PRE_EXCLUDE_REGEXES <regex>...

  • POST_INCLUDE_REGEXES <regex>...

  • POST_EXCLUDE_REGEXES <regex>...

  • POST_INCLUDE_FILES <file>...

  • POST_EXCLUDE_FILES <file>...

注意

此命令取代了 install_targets() 命令以及 PRE_INSTALL_SCRIPTPOST_INSTALL_SCRIPT 目标属性。它还取代了 install_files()install_programs() 命令的 FILES 表单。这些安装规则相对于 install_targets()install_files()install_programs() 命令生成的安装规则的处理顺序未定义。

示例

示例:带有每构件组件的安装目标

考虑一个定义了不同构件类型的项目的项目

add_executable(myExe myExe.c)
add_library(myStaticLib STATIC myStaticLib.c)
target_sources(myStaticLib PUBLIC FILE_SET HEADERS FILES myStaticLib.h)
add_library(mySharedLib SHARED mySharedLib.c)
target_sources(mySharedLib PUBLIC FILE_SET HEADERS FILES mySharedLib.h)
set_property(TARGET mySharedLib PROPERTY SOVERSION 1)

我们可以调用 install(TARGETS) 并带上 <artifact-kind> 参数,为每种类型的构件指定不同的选项

install(TARGETS
          myExe
          mySharedLib
          myStaticLib
        RUNTIME           # Following options apply to runtime artifacts.
          COMPONENT Runtime
        LIBRARY           # Following options apply to library artifacts.
          COMPONENT Runtime
          NAMELINK_COMPONENT Development
        ARCHIVE           # Following options apply to archive artifacts.
          COMPONENT Development
          DESTINATION lib/static
        FILE_SET HEADERS  # Following options apply to file set HEADERS.
          COMPONENT Development
        )

这将

  • myExe 安装到 <prefix>/bin(默认的 RUNTIME 构件目标),作为 Runtime 组件的一部分。

  • 在非 DLL 平台上

    • libmySharedLib.so.1 安装到 <prefix>/lib(默认的 LIBRARY 构件目标),作为 Runtime 组件的一部分。

    • libmySharedLib.so “名称链接”(符号链接)安装到 <prefix>/lib(默认的 LIBRARY 构件目标),作为 Development 组件的一部分。

  • 在 DLL 平台上

    • mySharedLib.dll 安装到 <prefix>/bin(默认的 RUNTIME 构件目标),作为 Runtime 组件的一部分。

    • mySharedLib.lib 安装到 <prefix>/lib/static(指定的 ARCHIVE 构件目标),作为 Development 组件的一部分。

  • myStaticLib 安装到 <prefix>/lib/static(指定的 ARCHIVE 构件目标),作为 Development 组件的一部分。

  • mySharedLib.hmyStaticLib.h 安装到 <prefix>/include(类型为 HEADERS 的文件集的默认目标),作为 Development 组件的一部分。

示例:安装目标到每配置目标

每个 install(TARGETS) 调用最多将给定的目标 输出构件 安装到一个 DESTINATION,但安装规则本身可以根据 CONFIGURATIONS 选项进行过滤。为了将同一个构件安装到每个配置的不同目标,需要为每个配置调用一次。例如,代码

install(TARGETS myExe
        CONFIGURATIONS Debug
        RUNTIME
          DESTINATION Debug/bin
        )
install(TARGETS myExe
        CONFIGURATIONS Release
        RUNTIME
          DESTINATION Release/bin
        )

将在 Debug 配置中将 myExe 安装到 <prefix>/Debug/bin,在 Release 配置中安装到 <prefix>/Release/bin

生成的安装脚本

注意

不建议使用此功能。请考虑使用 cmake --install

install() 命令会在构建目录中生成一个文件 cmake_install.cmake,该文件由生成的安装目标和 CPack 内部使用。您也可以使用 cmake -P 手动调用此脚本。此脚本接受多个变量

COMPONENT

将此变量设置为仅安装单个 CPack 组件,而不是全部。例如,如果您只想安装 Development 组件,请运行 cmake -DCOMPONENT=Development -P cmake_install.cmake

BUILD_TYPE

如果您正在使用多配置生成器,请设置此变量来更改构建类型。例如,要使用 Debug 配置进行安装,请运行 cmake -DBUILD_TYPE=Debug -P cmake_install.cmake

DESTDIR

这是一个环境变量,而不是 CMake 变量。它允许您更改 UNIX 系统上的安装前缀。有关详细信息,请参阅 DESTDIR