我们承担ROS,FastDDS等通信中间件,C++,cmake等技术的项目开发和专业指导和培训,有10年+相关工作经验,质量有保证,如有需要请私信联系。
本文主要介绍install的用法。
执行cmake --build ./build --target install
之后,build下会按install规则安装一份,同时在install的DESTINATION指定的路径下也会安装一份。
公共选项
install有多个签名,这些签名公用的选项有以下:
DESTINATION
:指定文件要安装的目录,可以是相对路径或绝对路径。建议使用GNUInstallDirs
(参考这里)中的变量。如果路径不存在会自动创建。如果给的是相对路径,默认使用前缀CMAKE_INSTALL_PREFIX
(参考这里)作为前缀路径,即${CMAKE_INSTALL_PREFIX}/<your_path>
,指定路径不存在的话可以自动创建。注意,没有必要通过在CMAKE_INSTALL_PREFIX
前面添加路径来使路径绝对化;如果在cpack中使用,由于cpack安装器生成器不支持绝对路径,因此最好在整个过程中使用相对路径。cpack路径使用前缀CPACK_PACKAGING_INSTALL_PREFIX
COMPONENT
:指定一个与安装规则相关联的安装组件名,如"lib", "runtime"等,指定后就会只安装与相关的组件。举例说明:
install(
TARGETS cxx17 cxx17_test
RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin COMPONENT runtime
ARCHIVE DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/lib COMPONENT lib
)
这里编译生成了可执行文件和静态库,可以通过指定COMPOENNT
只安装需要的lib,RUNTIME
没有安装。
除非标记为EXCLUDE_FROM_ALL
,否则所有组件都会被安装。如果没有提供COMPONENT ,则会创建一个默认组件"Unspecified"。默认组件名称可以通过CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
变量进行控制。
PERMISSIONS
:指定要安装的文件的权限,指定哪个权限就有哪个权限,可以指定多个,如RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
RENAME
:对安装的文件重命名,仅在只有一个文件被安装的条件下才有效。但是以下示例并没有生效-
install( TARGETS cxx17 ARCHIVE DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/lib PERMISSIONS GROUP_WRITE RENAME dasha)
OPTIONAL
:安装文件不存在不用报错,继续执行EXCLUDE_FROM_ALL
安装目标
install(TARGETS targets...
[EXPORT <export-name>]
[[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE| # 从这儿
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
[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可以是多个,比如可执行文件,动态或静态库EXPORT
:这个关键字指定CMake将为目标生成一个导出的目标文件,除这里外还需要显式的指定它的安装规则,通过install(EXPORT …)来实现- 可以分别配置多个文件的安装规则
- target类型:
ARCHIVE
:静态库,如.a, .lib等LIBRARY
:共享库,.so, .dll等RUNTIME
:可执行文件PUBLIC_HEADER
:如果给目标设置了PUBLIC_HEADER
属性,可以通过该选项安装PUBLIC_HEADER
属性指定的文件到目录文件PRIVATE_HEADER
:类似PUBLIC_HEADER,针对设置了PUBLIC_HEADER属性的文件RESOURCE
:类似上面两个,针对RESOURCE文件OBJECTS
:针对object库(什么是object库?)FRAMEWORK
,BUNDLE
:这两个针对MacOS
举例:
install(
TARGETS
lib-shared # so
hello-world_wDSO # exe
ARCHIVE
DESTINATION ${INSTALL_LIBDIR}
COMPONENT lib
RUNTIME
DESTINATION ${INSTALL_BINDIR}
COMPONENT bin
LIBRARY
DESTINATION ${INSTALL_LIBDIR}
COMPONENT lib
PUBLIC_HEADER # 这里必须要由set_target_properties的PUBLIC_HEADER属性指定要导出的文件才可以使用
DESTINATION ${INSTALL_INCLUDEDIR}/message
COMPONENT dev
)
目标类型 | 对应的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 |
安装文件
install(<FILES|PROGRAMS> files...
TYPE <type> | DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
将文件或程序安装到DESTINATION
指定的路径。并设置安装文件适当的权限。DESTINATION
不存的话可以自动创建。
RENAME
:如果FILES指定了多个文件,这里会报错,目前自测只有一个文件时可以在安装时重命名文件
安装目录
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...]] [...])
- 用于安装目录。将由
DIRECTORY
指定的一个或多个目录安装到DESTINATION
指定的目录下。当只给出一个目录名时,默认为在当前源目录下。要注意的是指定到目录这一级(xxx/yyy)还是目录下(xxx/yyy/),拷贝的路径不一样。可以对目录的安装粒度进行控制。 FILE_PERMISSIONS
和DIRECTORY_PERMISSIONS
指定安装之后的权限PATTERN
和REGEX
:指定用于过滤的正则表达式,PERMISSIONS
用于指定经过滤后的文件权限
安装导出
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> [...])
使用 install(EXPORT ...)
时必须要在install(TARGETS ... EXPORT xxx ...)
指定EXPORT
之后才能使用,否则会报错:
导出
从构建树中导出以便外部项目使用
export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>])
创建一个可能被外部项目包含的文件filename。如果提供了NAMESPACE,<namespace>
字符串会被添加到所有的targets名前。<export-name>
的安装路径由install(TARGETS)
命令的EXPORT指定。- 用法和上面类似,只是targets被逐一列出来。APPEND给定的话会在文件中追加而不是覆盖。
export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]
[APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])
export(PACKAGE <PackageName>)
保存当前的构建目录
问题
下面cmake代码:
add_library(cxx17 SHARED)
target_include_directories(
cxx17
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/inc
)
...
install(
TARGETS cxx17
EXPORT "${cxx17}Targets"
ARCHIVE DESTINATION ${INSTALL_LIB_DIR} COMPONENT lib
LIBRARY DESTINATION ${INSTALL_LIB_DIR} COMPONENT sha
PUBLIC_HEADER DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include COMPONENT header
COMPONENT dev
)
...
export(TARGETS cxx17 FILE "${INSTALL_CMAKE_DIR}/${cxx17}Targets.cmake")
export(PACKAGE cxx17)
install(EXPORT "${cxx17}Targets" DESTINATION ${INSTALL_CMAKE_DIR})
运行cmake -H. -Bbuild
时报错:
经验证,target_include_directories
中要换成PRIVATE后就没问题了,原因暂时不知道