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/local
,Windows
下的默认值是C:/Program Files/${PROJECT_NAME}
)内容为前缀。类Unix
系统下可以在安装时通过DESTDIR
环境变量(参考DESTDIR,备注:DESTDIR
是DESTination DIRectory
的缩写)重定位整个安装路径。例如文件的安装前缀默认是/usr/local/
,当执行make DESTDIR=/package/stage install
命令后,安装前缀会变为/package/stage/usr/local
。
如果是绝对路径,会直接使用该路径作为安装路径,不会做任何改动。
因为cpack
(cpack
可执行文件是一个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
为安装规则指定构建配置(例如Debug
、Release
等),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
指定与安装规则关联的安装组件名称,例如runtime
或development
。在指定组件安装期间,只有与给定组件名称关联的安装规则才会被执行。除非使用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
目标)
OBJECTS
(3.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_HEADER
和PRIVATE_HEADER
类似,但是作用于RESOURCE
文件
FILE_SET <set>
(3.23
版本新增):
- 文件集合通过
target_sources(FILE_SET)
命令定义,如果文件集合<set>
存在并且是PUBLIC
或INTERFACE
,那么集合中的文件会被安装到目的路径。相对文件集合基路径的目录结果会被保留,例如文件集合的基路径是/XXX/YYY
,在文件集合中的某个文件路径为/XXX/YYY/myinstalldir/myfile.h
,那么在安装目的路径下,会按照myinstalldir/myfile.h
目录结构进行安装。
上述目标
类型的个数可以指定0
个、1
个或多个。当目标
类型指定多个,每个指定的目标
类型后的安装选项只会作用于该目标
或文件类型;当指定0
个目标
类型,则安装选项会作用于所有的目标
类型;当指定1
个目标
类型时,则安装选项只对该指定的目标
类型生效。
对于常规的可执行文件、静态库文件、共享库文件,DESTINATION
安装选项不是必须的,因为在未提供DESTINATION
选项时,会从变量GNUInstallDirs
获取一个默认值,如果该变量也未定义,会设置为内置的默认值。对于PUBLIC_HEADER
和PRIVATE_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.1
。lib<name>.so.1
为so
库名,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
)
在上面的例子中,有两种目标
类型:LIBRARY
和PUBLIC_HEADER
,其中LIBRARY
下包含Libraries
组件和Development
组件,PUBLIC_HEADER
下包含Development
组件。
- 如果仅仅选择安装
Development
组件,那么会安装头文件和名称链接文件,但不会安装库文件。(此时安装的名称链接是悬空的,没有实际的库文件可以指向,因此链接器会找不到库文件)。- 如果仅仅选择安装
Libraries
组件,那么会安装库文件,但不会安装头文件和名称链接文件。
该选项的典型应用场景是包管理器,将运行时包和开发包分开。例如,在Debian
系统,库文件为运行时包,而头文件和名称链接是开发包(意味着不安装也不会影响系统运行,但是如果需要基于该库做开发,那么需要头文件和名称链接)。
-
NAMELINK_ONLY
该选项会导致在安装库目标时,只安装名称链接文件。在没有名称链接的平台或者库文件未带版本号,则该选项不起任何作用。并且该选项只能用于LIBRARY
目标下,否则会出错。
当指定NAMELINK_ONLY
,NAMELINK_COMPONENT
和COMPONENT
都可以用来指定名称链接的安装,但是更推荐使用COMPONENT
。
-
NAMELINK_SKIP
该选项与NAMELINK_ONLY
起到相反的作用,当安装库目标时,只会安装库文件,而不会安装名称链接。如果NAMELINK_SKIP
和NAMELINK_ONLY
同时使用,那么库文件和名称链接都会安装。在没有名称链接的平台或者库文件未带版本号,该选项会安装库文件,该选项只能用于LIBRARY
目标下,否则会出错。
当指定NAMELINK_SKIP
,NAMELINK_COMPONENT
不起作用,因此不建议同时使用NAMELINK_SKIP
和NAMELINK_COMPONENT
。
-
EXPORT
该选项将安装目标文件与与名为<export-name>
的导出关联起来。该选项必须出现在任何其他安装目标选项之前。若要安装导出文件本身,需要调用install(EXPORT)
命令。如果使用了EXPORT
选项,并且目标包含了PUBLIC
或INTERFACE
文件集合,他们必须指定FILE_SET
选项,所有与目标关联的PUBLIC
或INTERFACE
文件集合都包含在导出中。
-
INCLUDES DESTINATION
当时用install(EXPORT)
命令导出时,该选项指定了会被添加到<targets>
目标属性INTERFACE_INCLUDE_DIRECTORIES
的目录列表。如果是相对路径,会被当成相对于$<INSTALL_PREFIX>
的路径。
-
RUNTIME_DEPENDENCY_SET
3.21
版本新增。该选项会将安装可执行文件、共享库、模块目标时的所有运行时依赖添加到指定的运行时依赖集合。运行时依赖集合可以通过install(RUNTIME_DEPENDENCY_SET)
安装。
RUNTIME_DEPENDENCY_SET
与RUNTIME_DEPENDENCIES
是互斥的。
-
RUNTIME_DEPENDENCIES
3.21
版本新增。该选项会将安装可执行文件、共享库、模块目标时的所有运行时依赖与目标一起安装。使用RUNTIME
, LIBRARY
,FRAMEWORK
以及通用的参数来决定安装这些依赖的的属性(例如DESTINATION
、COMPONENT
等)。
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)
命令中指定一个或多个目标属性。一个目标也可能被多次安装到不同的位置。以一个例子来说明一下:
假设需要安装
myExe
、mySharedLib
、myStaticLib
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
指定导入目标运行时构件的安装规则。当工程需要将外部的可执行文件或模块绑定到内部的安装,就需要使用它。LIBRARY
, RUNTIME
, FRAMEWORK
, BUNDLE
这些选项与前面安装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_WRITE
, OWNER_READ
, GROUP_READ
, ORLD_READ
(也就是644
)。
PROGRAMS
和FILES
的区别只在默认安装文件的权限上,除了OWNER_WRITE
, OWNER_READ
, GROUP_READ
, ORLD_READ
,PROGRAMS
也包含了OWNER_EXECUTE
, GROUP_EXECUTE
, WORLD_EXECUTE
权限,(也就是PROGRAMS
的默认权限是755
)。PROGRAMS
安装的对象是非目标(target
)的程序,例如shell
脚本。
files...
列表可以使用发生器表达式(语法为$<...>
),但是必须为全路径。
TYPE
和DESTINATION
必须提供一个(不需要同时提供)。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_PERMISSIONS
和DIRECTORY_PERMISSIONS
选项分别指定了安装到目标路径的文件和目录的权限。如果指定了USE_SOURCE_PERMISSIONS
未指定FILE_PERMISSIONS
选项,那么安装的文件权限会从原目录结果拷贝。如果未指定权限,那么文件的权限会按照FILES
命令的默认权限(也就是644
),目录的权限会安装PROGRAMS
命令的默认权限(也就是755
)。
3.1
新增:当指定MESSAGE_NEVER
选项,文件安装状态输出信息会被禁止。
可以通过PATTERN
或REGEX
选项来控制安装目录的颗粒度,这些匹配选项会指定通配符选项或者正则表达式来匹配输入目录的文件和目录。他们可以用来将某些选项(见下文)应用于遇到的目录和文件子集。与表达式匹配的是每个输入文件或目录的全路径。PATTERN
仅仅匹配文件名,模式匹配发生在全路径最后文件名部分(文件名前需要带/
);REGEX
则会匹配全路径的任何一个部分,但可以使用/
或$
来模拟REGEX
的行为。
默认情况下所有文件和目录都会被安装,FILES_MATCHING
选项必须出现在第一个匹配选项之前,以禁止安装未被任何表达式匹配的文件(不包括目录)。例如:
install(DIRECTORY src/ DESTINATION doc/myproj FILES_MATCHING PATTERN "*.png")
会从原文件树中提取图像文件并安装到目标路径。
跟随PATTERN
或REGEX
也可以使用一些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
会被排除不会安装到目第路径。
TYPE
和DESTINATION
两个选项需要提供一个(且只能提供一个),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
文件要求每个导出的组件顺序呈现。例如,一个工程可能定义Runtime
和Development
两个组件,其中Runtime
中包含动态库文件,Development
中包含静态库和头文件。导出集合通常也是Development
的一部分,但是它会从Runtime
和Development
两个组件中导出目标。因此Development
组件安装时,Runtime
组件也需要被安装,反过来不成立。如果安装Development
组件时未安装Runtime
,尝试链接的工程会出现构建错误。像APT
、RPM
等包管理器,通常会将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)
仅支持在Windows
、Linux
和macOS
系统下收集运行时依赖,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
系统下的安装路径前缀,上文有介绍该变量的用法和效果。