CMake之安装打包


我们承担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库?)
    • FRAMEWORKBUNDLE:这两个针对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_PERMISSIONSDIRECTORY_PERMISSIONS 指定安装之后的权限
  • PATTERNREGEX:指定用于过滤的正则表达式,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之后才能使用,否则会报错:
在这里插入图片描述

导出

从构建树中导出以便外部项目使用

  1. export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>]) 创建一个可能被外部项目包含的文件filename。如果提供了NAMESPACE,<namespace>字符串会被添加到所有的targets名前。<export-name>的安装路径由install(TARGETS)命令的EXPORT指定。
  2. 用法和上面类似,只是targets被逐一列出来。APPEND给定的话会在文件中追加而不是覆盖。
export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]
       [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])
  1. 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后就没问题了,原因暂时不知道

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值