[cmake]cmake命令之install

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

一、命令简介

intall()命令为工程生成安装规则,同一个源文件目录下的安装规则按照intall()命令的调用顺序在安装时(也就是使用make install时)执行。

intall()命令有多个形式,其中有一些是针对文件和目标对象定义安装选项。下面介绍该命令的几个通用选项:

  • DESTINATION

指定文件将要安装的目录,可以是相对路径也可以是绝对路径。

如果是相对路径,会以CMAKE_INSTALL_PREFIX变量(Unix/Linux下默认值是/usr/localWindows下的默认值是C:/Program Files/${PROJECT_NAME})内容为前缀。类Unix系统下可以在安装时通过DESTDIR环境变量(参考DESTDIR,备注:DESTDIRDESTination DIRectory的缩写)重定位整个安装路径。例如文件的安装前缀默认是/usr/local/,当执行make DESTDIR=/package/stage install命令后,安装前缀会变为/package/stage/usr/local

如果是绝对路径,会直接使用该路径作为安装路径,不会做任何改动。

因为cpackcpack可执行文件是一个CMake打包程序,它可以以各种格式生成安装程序和源程序包)安装生成器不支持绝对路径,要使用相对路径。没有必要使用预置的CMAKE_INSTALL_PREFIX变量来生成绝对路径,因为只要DESTINATION指定的是相对路径,那么会自动使用CMAKE_INSTALL_PREFIX变量作为前缀。

  • PERMISSIONS

为安装文件指定权限,合法的权限选择有:OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, WORLD_READ, WORLD_WRITE, WORLD_EXECUTE, SETUID, SETGID,在有些平台,该选项会被忽略,无法起作用。

  • CONFIGURATIONS

为安装规则指定构建配置(例如DebugRelease等),CONFIGURATIONS只会使用紧跟它的值,如果要指定多个构建配置,需要使用install()命令多次,例如:分别指定Debug配置和Release配置:

install(TARGETS target CONFIGURATIONS Debug RUNTIME DESTINATION Debug/bin)
install(TARGETS target CONFIGURATIONS Release RUNTIME DESTINATION Release/bin)
注意:CONFIGURATIONS需要放在RUNTIME DESTINATION之前。

  • COMPONENT

指定与安装规则关联的安装组件名称,例如runtimedevelopment。在指定组件安装期间,只有与给定组件名称关联的安装规则才会被执行。除非使用EXCLUDE_FROM_ALL选项,否则会在完整安装过程中安装所有组件。

未指定该选项,则会创建一个默认的组件名Unspecified,可以通过CMAKE_INSTALL_DEFAULT_COMPONENT_NAME变量来改变默认的组件名。

  • EXCLUDE_FROM_ALL

3.6版本新增。在完整安装过程中,指定排除掉的文件。排除的文件只会被安装在特定的组件中。

  • RENAME

如果想在安装过程中,使用与原文件不同的文件名,可以通过该选项来指定安装文件的名字,重命名只允许应用于单个文件的安装命令。

  • OPTIONAL

该选项指明当被安装的文件不存在时,不会当做错误处理。

不同版本的变更点:

3.1版本新增:安装文件命令在安装期间可以打印信息,使用CMAKE_INSTALL_MESSAGE变量可以控制打印哪些信息。

3.11版本新增:install()中的许多选项会隐式创建安装文件路径中保包含的目录。这些被创建的目录的权限可以通过CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS来指定,否则在类Unix系统会根据uname规则来创建,Windows系统不受影响。

3.14版本的变更点:通过add_subdirectory()命令添加的子目录,子目录的安装规则,会被插入到父目录安装规则中,与父目录的安装规则按照申明的顺序执行。(可以参考CMP0082

3.22版本的变更点:环境变量CMKE_INSTALL_MODE可以重新指定intall()的拷贝行为。

二、命令使用
2.1 install()命令的调用过程

1、编写一个静态库 --- 已完成
2、编写一个可执行文件 --- 已完成
3、将静态库和可执行文件安装到不同目录(尽可能多的演示install命令)
4、通过提供cmake文件,让库的使用者能找到该库(可以参考find_library或find_package命令) --- 已完成
5、执行cmake install安装库和可执行文件 --- 已完成
6、编写测试程序,使用安装之后的库 --- 已完成

三、命令详解
3.1 安装目标

命令的格式为:

install(TARGETS targets... [EXPORT <export-name>]
        [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
         [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...]
        [INCLUDES DESTINATION [<dir> ...]]
        )

  • TARGETS

TARGETS指定安装目标的规则,这里的目标有如下几种:
ARCHIVE

  • 静态库(例外情况:在macOS系统下标记为FRAMEWORK目标的除外)
  • DLL导入库(在所有的基于Windows系统包括Cygwin,它们使用.lib扩展名称。相比之下.dll库是RUNTIME目标下包含的)
  • AIX系统,可以通过使能ENABLE_EXPORTS来为可执行文件创建链接器导入文件

LIBRARY

  • 共享库(两种例外情况:属于RUNTIME目标下的DLLs以及,macOS下属于FRAMEWORK目标下的)

RUNTIME

  • 可执行文件(例外情况:在macOS系统下标记为MACOSX_BUNDLE目标的除外)
  • DLLs(在所有的基于Windows系统包括Cygwin,注意附带的导入库属于ARCHIVE目标)

OBJECTS3.9版本新增):

  • 关联到对象库的对象文件

FRAMEWORK

  • macOS系统下,被标记为FRAMEWORK特性的的静态库和共享库都会被当做FRAMEWORK目标

BUNDLE

  • macOS系统下,被标记为MACOSX_BUNDLE特性的可执行文件会被当做BUNDLE目标

PUBLIC_HEADER

  • 在非Apple平台,与库相关的PUBLIC_HEADER文件会被安装到PUBLIC_HEADER指定的目录中。因此在Apple平台,FRAMEWORK库会忽略该参数,相关文件会被安装到合适的框架目录下

PRIVATE_HEADER

  • PUBLIC_HEADER类似,但是作用于PRIVATE_HEADER文件

RESOURCE

  • PUBLIC_HEADERPRIVATE_HEADER类似,但是作用于RESOURCE文件

FILE_SET <set>3.23版本新增):

  • 文件集合通过target_sources(FILE_SET)命令定义,如果文件集合<set>存在并且是PUBLICINTERFACE,那么集合中的文件会被安装到目的路径。相对文件集合基路径的目录结果会被保留,例如文件集合的基路径是/XXX/YYY,在文件集合中的某个文件路径为/XXX/YYY/myinstalldir/myfile.h,那么在安装目的路径下,会按照myinstalldir/myfile.h目录结构进行安装。

上述目标类型的个数可以指定0个、1个或多个。当目标类型指定多个,每个指定的目标类型后的安装选项只会作用于该目标或文件类型;当指定0目标类型,则安装选项会作用于所有的目标类型;当指定1目标类型时,则安装选项只对该指定的目标类型生效。

对于常规的可执行文件、静态库文件、共享库文件,DESTINATION安装选项不是必须的,因为在未提供DESTINATION选项时,会从变量GNUInstallDirs获取一个默认值,如果该变量也未定义,会设置为内置的默认值。对于PUBLIC_HEADERPRIVATE_HEADER指定与安装目标关联的公共头文件、私有头文件、文件集合,也是一样的规则。一般来说,模块库、Apple捆绑包、框架需要提供安装路径。接口和对象库可以不提供安装路径,但是他们的处理会有差别。

下表显示了当未提供安装目录选项时,不同目标类型关联的变量和内置默认值。

目标类型GNUInstallDirs变量内置默认值
RUNTIME${CMAKE_INSTALL_BINDIR}bin
LIBRARY${CMAKE_INSTALL_BINDIR}lib
ARCHIVE${CMAKE_INSTALL_BINDIR}lib
PRIVATE_HEADER${CMAKE_INSTALL_INCLUDEDIR}include
PUBLIC_HEADER${CMAKE_INSTALL_INCLUDEDIR}include
FILE_SET (头文件类型)${CMAKE_INSTALL_INCLUDEDIR}include
  • NAMELINK_COMPONENT

3.12版本新增,在一些系统下,通常会有一个符号链接指向一个带版本号的共享库,例如:lib<name>.so -> lib<name>.so.1lib<name>.so.1so库名,lib<name>.so即为名称链接,指向实际的so库。这样就允许使用链接器使用-l<name>来找到真实的lib<name>.so.1库。NAMELINK_COMPONENT选项影响的就是共享库名称链接组件的安装。

来看一个例子:

install(TARGETS mylib
        LIBRARY
          COMPONENT Libraries
          NAMELINK_COMPONENT Development
        PUBLIC_HEADER
          COMPONENT Development
       )

在上面的例子中,有两种目标类型:LIBRARYPUBLIC_HEADER,其中LIBRARY下包含Libraries组件和Development组件,PUBLIC_HEADER下包含Development组件。

  • 如果仅仅选择安装Development组件,那么会安装头文件和名称链接文件,但不会安装库文件。(此时安装的名称链接是悬空的,没有实际的库文件可以指向,因此链接器会找不到库文件)。
  • 如果仅仅选择安装Libraries组件,那么会安装库文件,但不会安装头文件和名称链接文件。

该选项的典型应用场景是包管理器,将运行时包和开发包分开。例如,在Debian系统,库文件为运行时包,而头文件和名称链接是开发包(意味着不安装也不会影响系统运行,但是如果需要基于该库做开发,那么需要头文件和名称链接)。

  • NAMELINK_ONLY

该选项会导致在安装库目标时,只安装名称链接文件。在没有名称链接的平台或者库文件未带版本号,则该选项不起任何作用。并且该选项只能用于LIBRARY目标下,否则会出错。

当指定NAMELINK_ONLYNAMELINK_COMPONENTCOMPONENT都可以用来指定名称链接的安装,但是更推荐使用COMPONENT

  • NAMELINK_SKIP

该选项与NAMELINK_ONLY起到相反的作用,当安装库目标时,只会安装库文件,而不会安装名称链接。如果NAMELINK_SKIPNAMELINK_ONLY同时使用,那么库文件和名称链接都会安装。在没有名称链接的平台或者库文件未带版本号,该选项会安装库文件,该选项只能用于LIBRARY目标下,否则会出错。

当指定NAMELINK_SKIPNAMELINK_COMPONENT不起作用,因此不建议同时使用NAMELINK_SKIPNAMELINK_COMPONENT

  • EXPORT

该选项将安装目标文件与与名为<export-name>的导出关联起来。该选项必须出现在任何其他安装目标选项之前。若要安装导出文件本身,需要调用install(EXPORT)命令。如果使用了EXPORT选项,并且目标包含了PUBLICINTERFACE文件集合,他们必须指定FILE_SET选项,所有与目标关联的PUBLICINTERFACE文件集合都包含在导出中。

  • INCLUDES DESTINATION

当时用install(EXPORT)命令导出时,该选项指定了会被添加到<targets>目标属性INTERFACE_INCLUDE_DIRECTORIES的目录列表。如果是相对路径,会被当成相对于$<INSTALL_PREFIX>的路径。

  • RUNTIME_DEPENDENCY_SET

3.21版本新增。该选项会将安装可执行文件、共享库、模块目标时的所有运行时依赖添加到指定的运行时依赖集合。运行时依赖集合可以通过install(RUNTIME_DEPENDENCY_SET)安装。

RUNTIME_DEPENDENCY_SETRUNTIME_DEPENDENCIES是互斥的。

  • RUNTIME_DEPENDENCIES

3.21版本新增。该选项会将安装可执行文件、共享库、模块目标时的所有运行时依赖与目标一起安装。使用RUNTIMELIBRARYFRAMEWORK以及通用的参数来决定安装这些依赖的的属性(例如DESTINATIONCOMPONENT等)。

RUNTIME_DEPENDENCIES在语义上等价于以下命令:

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

<set-name>是随机产生的集合名称,args...install(RUNTIME_DEPENDENCY_SET)支持的选项,有如下取值:

  • DIRECTORIES
  • PRE_INCLUDE_REGEXES
  • PRE_EXCLUDE_REGEXES
  • POST_INCLUDE_REGEXES
  • POST_EXCLUDE_REGEXES
  • POST_INCLUDE_FILES
  • POST_EXCLUDE_FILES

可以在单个的install(TARGETS)命令中指定一个或多个目标属性。一个目标也可能被多次安装到不同的位置。以一个例子来说明一下:

假设需要安装myExemySharedLibmyStaticLib

install(TARGETS myExe mySharedLib myStaticLib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib/static)
install(TARGETS mySharedLib DESTINATION /some/full/path)

上述代码会将myExe安装到<prefix>/bin,将myStaticLib安装到<prefix>/lib/static。在非DLL平台,mySharedLib会被安装到<prefix>/lib/some/full/path;在DLL平台,mySharedLib动态链接库会被安装到<prefix>/lib/some/full/path,其导入库会被安装到<prefix>/lib/static/some/full/path

3.3版本新增:DESTINATION参数可以使用生成器表达式(用$<...>来定义)。

3.13版本新增:install(TARGETS)可以安装在其他目录创建的目标,当使用这种交叉目录安装规则时,在子目录运行cmake install命令无法保证来自其他目录目标是最新的。可以使用target_link_libraries()add_dependencies()来保证这种目录外的目标在指定子目录运行安装规则前被执行构建。

3.2 安装导入运行时的构件

3.21版本新增,命令的格式为:

install(IMPORTED_RUNTIME_ARTIFACTS targets...
        [RUNTIME_DEPENDENCY_SET <set-name>]
        [[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
        ] [...]
        )

IMPORTED_RUNTIME_ARTIFACTS指定导入目标运行时构件的安装规则。当工程需要将外部的可执行文件或模块绑定到内部的安装,就需要使用它。LIBRARYRUNTIMEFRAMEWORKBUNDLE这些选项与前面安装TARGETS里面的介绍的语义相同。只有导入的运行是构件会被安装(FRAMEWORK库、MACOSX_BUNDLE可执行文件、BUNDLE CFBundles这三者除外)。例如:与DLL相关的导入库的头文件不会被安装。FRAMEWORK库、MACOSX_BUNDLE可执行文件、BUNDLE CFBundles这三种情况,整个目录都会被安装。

RUNTIME_DEPENDENCY_SET选项会将导入的可执行文件、共享库、模块库的运行时构件添加到<set-name>中,然后就可以使用install(RUNTIME_DEPENDENCY_SET)进行安装。

3.3 安装文件

命令的格式为:

install(<FILES|PROGRAMS> files...
        TYPE <type> | DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

注意:如果只是安装头文件,可以考虑使用target_sources(FILE_SET)中定义的文件集合命令替代。关联目标的头文件集合,会作为目标的一部分安装。

FILES指定了一个工程安装文件的规则。如果给定的文件是相对路径,那么会解析成当前源文件路径的相对路径。如果未指定PERMISSIONS参数,被安装的文件权限默认为OWNER_WRITEOWNER_READGROUP_READORLD_READ(也就是644)。

PROGRAMSFILES的区别只在默认安装文件的权限上,除了OWNER_WRITEOWNER_READGROUP_READORLD_READPROGRAMS也包含了OWNER_EXECUTEGROUP_EXECUTEWORLD_EXECUTE权限,(也就是PROGRAMS的默认权限是755)。PROGRAMS安装的对象是非目标(target)的程序,例如shell脚本。

files...列表可以使用发生器表达式(语法为$<...>),但是必须为全路径。

TYPEDESTINATION必须提供一个(不需要同时提供)。TYPE参数指定待安装文件的通用类型。根据不同的TYPE,会从对应的GNUInstallDirs变量获取安装目的路径,如果未提供GNUInstallDirs变量,会使用内建默认值。下表汇总了不同TYPE文件对应的GNUInstallDirs变量值和内建的默认值。

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

如果希望安装头文件到工程相关的子目录,那么需要提供一个安装目录而不是使用上表的目录。因此使用文件集合替代install(FILE)是更好的选择。

一些类型的内建默认值会使用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参数可以使用生成器表达式(用$<...>来定义)。

3.20新增:通过RENAME指定安装重命名也可以使用生成器表达式(用$<...>来定义)。

3.4 安装目录

命令的格式为:

install(DIRECTORY dirs...
        TYPE <type> | DESTINATION <dir>
        [FILE_PERMISSIONS permissions...]
        [DIRECTORY_PERMISSIONS permissions...]
        [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>] [EXCLUDE_FROM_ALL]
        [FILES_MATCHING]
        [[PATTERN <pattern> | REGEX <regex>]
         [EXCLUDE] [PERMISSIONS permissions...]] [...])

注意:如果是安装头文件目录子树,可以考虑使用target_sources(FILE_SET)中定义的文件集合命令替代。文件集合不仅仅是保持了目录结构,它也关联目标的头文件,会作为目标的一部分安装。

DIRECTORY安装一个或多个目录的内容到指定的目标路径,目录结构会原封不动的拷贝到目标路径。每个目录名称的最后一个组成部分会被拼接到目标路径,但是可以通过在末尾添加斜杠/来避免(因为尾部的/表明目录最后的组成部分是空)。如果目录名称是相对路径,那么该目录会解析成相对于当前源目录的路径。如果未给定输入目录名,那么目的路径会创建但是不会安装任何东西。FILE_PERMISSIONSDIRECTORY_PERMISSIONS选项分别指定了安装到目标路径的文件和目录的权限。如果指定了USE_SOURCE_PERMISSIONS未指定FILE_PERMISSIONS选项,那么安装的文件权限会从原目录结果拷贝。如果未指定权限,那么文件的权限会按照FILES命令的默认权限(也就是644),目录的权限会安装PROGRAMS命令的默认权限(也就是755)。

3.1新增:当指定MESSAGE_NEVER选项,文件安装状态输出信息会被禁止。

可以通过PATTERNREGEX选项来控制安装目录的颗粒度,这些匹配选项会指定通配符选项或者正则表达式来匹配输入目录的文件和目录。他们可以用来将某些选项(见下文)应用于遇到的目录和文件子集。与表达式匹配的是每个输入文件或目录的全路径。PATTERN仅仅匹配文件名,模式匹配发生在全路径最后文件名部分(文件名前需要带/);REGEX则会匹配全路径的任何一个部分,但可以使用/$来模拟REGEX的行为。

默认情况下所有文件和目录都会被安装,FILES_MATCHING选项必须出现在第一个匹配选项之前,以禁止安装未被任何表达式匹配的文件(不包括目录)。例如:

install(DIRECTORY src/ DESTINATION doc/myproj FILES_MATCHING PATTERN "*.png")
会从原文件树中提取图像文件并安装到目标路径。

跟随PATTERNREGEX也可以使用一些string(REGEX)中描述的选项,会用来匹配的文件或目录。EXCLUDE选项会跳过匹配的文件或者目录,PERMISSIONS则会重新定义匹配到的文件或目录的权限,例如:

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(目录的末尾的组成部分icons会被拷贝到目的路径),而scripts目录会被安装到share/myproj(scripts/最后的/意味着目录的最末尾的组成部分是空)。icons目录会按照默认权限安装,而scripts目录的内容会按照指定的权限安装,任何包含CVS会被排除不会安装到目第路径。

TYPEDESTINATION两个选项需要提供一个(且只能提供一个),TYPE指定了将会被安装到目标路径的通用文件类型,此时目的路径会从GNUInstallDirs变量中获取,当该变量没有定义则会从内置默认值中获取。也可以通过DESTINATION显示指定安装路径。下表显示了不同类型对应的GNUInstallDirs变量值和内建默认值:

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

一些类型的内建默认值会使用DATAROOT作为前缀,DATAROOT使用CMAKE_INSTALL_DATAROOTDIR变量(其内建默认值是share),不能直接使用DATAROOT作为TYPE参数,需要使用DATA

为了让包符合分布式文件系统布局策略,如果一个工程必须要指定DESTINATION,推荐的做法是使用合适的GNUInstallDirs变量作为前缀。这样会允许包的维护者通过合适的缓存变量设置来控制安装目录。

3.4新增:DESTINATION参数可以使用生成器表达式(用$<...>来定义)。

3.5新增:dirs...参数也可以使用生成器表达式。

3.5 定制安装逻辑

命令的格式为:

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>,此时引用的是文件名字而不是文件内容)。

3.6 安装导出

命令的格式为:

install(EXPORT <export-name> DESTINATION <dir>
        [NAMESPACE <namespace>] [[FILE <name>.cmake]|
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [EXPORT_LINK_INTERFACE_LIBRARIES]
        [COMPONENT <component>]
        [EXCLUDE_FROM_ALL])
install(EXPORT_ANDROID_MK <export-name> DESTINATION <dir> [...])

EXPORT将会生成并安装一个CMake文件,该CMake文件包含将目标从安装树导出信息到其他工程的代码。<export-name>关联的是使用install(TARGETS)命令中使用EXPORT选项指定的名称。

  • FILE:生成的CMake文件默认名为<export-name>.cmake,可以通过FILE指定其他名称,但必须是以.cmake为后缀的名称。
  • NAMESPACE:该选项会在写入导入文件中的信息前添加名称<namespace>
  • CONFIGURATIONS:指定该选项,仅当安装了其中一个命名配置时,才会安装导入文件,并且导入文件只会引用匹配的目标配置。
  • EXPORT_LINK_INTERFACE_LIBRARIES:匹配(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?属性的内容会被导出。
  • COMPONENT:指定该选项,其后列出的<component>会隐式依赖于导出集合中提到的所有组件。为了依赖的工程被合适的构建,导出的<name>.cmake文件要求每个导出的组件顺序呈现。例如,一个工程可能定义RuntimeDevelopment两个组件,其中Runtime中包含动态库文件,Development中包含静态库和头文件。导出集合通常也是Development的一部分,但是它会从RuntimeDevelopment两个组件中导出目标。因此Development组件安装时,Runtime组件也需要被安装,反过来不成立。如果安装Development组件时未安装Runtime,尝试链接的工程会出现构建错误。像APTRPM等包管理器,通常会将Runtime组件作为Development的依赖,在包的元数据中列出来,确保如果头文件和CMake导出文件存在时库文件被安装。

3.7新增:除了CMake语言文件,EXPORT_ANDROID_MK模式可以用来指定导出到andriod ndk构建系统,该模式接收的参数与普通的导出模式一致。Andriod NDK支持预构建静态或动态库。该模式允许cmake构建andriod ndk系统可用的库,包含使用库所需的标记或定义。

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将其导出。外部工程可以加载这些文件,通过使用导出目标mp_myexe,可以从安装树中包含并引用myexe可执行文件,就像myexe文件是外部工程构建的一样。

3.7 安装运行时依赖

3.21新增,命令的格式为:

install(RUNTIME_DEPENDENCY_SET <set-name>
        [[LIBRARY|RUNTIME|FRAMEWORK]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
        ] [...]
        [PRE_INCLUDE_REGEXES regexes...]
        [PRE_EXCLUDE_REGEXES regexes...]
        [POST_INCLUDE_REGEXES regexes...]
        [POST_EXCLUDE_REGEXES regexes...]
        [POST_INCLUDE_FILES files...]
        [POST_EXCLUDE_FILES files...]
        [DIRECTORIES directories...]
        )

安装通过一个或多个install(TARGETS)install(IMPORTED_RUNTIME_ARTIFACTS)命令创建的运行时的依赖集合。属于运行时依赖集合的目标依赖,在DLL平台被安装到RUNTIME目的路径,在非DLL平台下被安装到LIBRARY目的路径。macOS下的框架被安装到FRAMEWORK目的路径。通过生成树构建的目标,除非通过install(TARGETS)命令进行安装,否则它或者它的依赖不会作为运行时依赖被安装。
生成的安装脚本通过在生成树上调用file(GET_RUNTIME_DEPENDENCIES)来计算运行时依赖。生成树可执行文件通过EXECUTABLES参数传递,生成树共享库文件通过LIBRARIES参数传递,生成树模块通过MODULES参数传递。在macOS下,如果可执行文件的其中之一是MACOSX_BUNDLE,那么可执行文件通过BUNDLE_EXECUTABLE传递。file(GET_RUNTIME_DEPENDENCIES)仅支持在WindowsLinuxmacOS系统下收集运行时依赖,install(RUNTIME_DEPENDENCY_SET)也有同样的限制。

以下选项作为相关参数转发到file(GET_RUNTIME_DEPENDENCIES)命令:

  • DIRECTORIES <directories>
  • PRE_INCLUDE_REGEXES <regexes>
  • PRE_EXCLUDE_REGEXES <regexes>
  • POST_INCLUDE_REGEXES <regexes>
  • POST_EXCLUDE_REGEXES <regexes>
  • POST_INCLUDE_FILES <files>
  • POST_EXCLUDE_FILES <files>
生成安装脚本

注意:不推荐使用该特性,请使用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系统下的安装路径前缀,上文有介绍该变量的用法和效果。


附录:参考文件
  1. https://cmake.org/cmake/help/latest/command/install.html#command:install
  • 35
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
cmake install命令用于在编译目录中生成一个cmake_install.cmake的文件,该文件由安装程序或者CPack在安装时调用。 这个命令可以通过使用install()函数来手动调用,也可以使用cmake -P命令来进行手动调用。当手动调用时,可以选择使用一些参数。 在使用cmake时,常见的几个步骤包括:创建一个build目录,进入该目录,运行cmake命令,然后运行make命令进行编译,最后运行make install命令进行安装。 可以通过在命令行中输入以下命令来一次完成这些步骤:mkdir build && cd build && cmake .. && make && make install。 如果想了解更多关于cmake install命令的信息,可以参考这篇博客文章:<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [cmake(8):install命令详解](https://blog.csdn.net/rangfei/article/details/109304175)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [【CMakecmakeinstall指令](https://blog.csdn.net/qq_38410730/article/details/102837401)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值