CMake之安装打包

安装

install的用法。
执行cmake --build ./build --target install之后,build下会按install规则安装一份,同时在install的DESTINATION指定的路径下也会安装一份。

公共选项

install有多个签名,这些签名公用的选项有以下:

  • DESTINATION:指定文件要安装的目录,可以是相对路径或绝对路径。建议使用GNUInstallDirs中的变量。如果路径不存在会自动创建。
    • 相对路径:会使用 CMAKE_INSTALL_PREFIX 作为前缀路径,即 ${CMAKE_INSTALL_PREFIX}/<your_path>,指定路径不存在的话可以自动创建。如果在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"生成(待验证)

  • 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可以是多个,比如可执行文件,动态或静态库
    • 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之后才能使用,否则会报错:
在这里插入图片描述

导出

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

  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后就没问题了,原因暂时不知道

猜你喜欢

转载自blog.csdn.net/u010378559/article/details/130867820