cmake 使用 PUBLIC_HEADER 将库和开发文件安装为单独的组件

Bru*_*ams 7 cmake

我希望创建两个包,一个包含共享库,另一个包含供开发使用的标头。

一个有效的解决方案是:

INSTALL(TARGETS mylib
  COMPONENT core
  LIBRARY DESTINATION ${LIBDIR}
)
INSTALL (
    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMPONENT devel
    DESTINATION ${INCLUDEDIR}
    FILES_MATCHING PATTERN "*.h")
Run Code Online (Sandbox Code Playgroud)

然而,CMake 也有一个“PUBLIC_HEADER”目的地。这样你就可以做类似的事情:

INSTALL(TARGETS mylib
  LIBRARY DESTINATION ${LIBDIR}
  PUBLIC_HEADER DESTINATION ${INCLUDEDIR}
)
Run Code Online (Sandbox Code Playgroud)

我似乎无法让它发挥作用。即使头文件显式添加到 ADD_LIBRARY(),${INCLUDEDIR} 也不会安装任何内容。有人可以举一个例子来说明这是如何工作的吗?

另一个问题是我想要不同包中的库和标头,所以理想情况下我想要:

INSTALL(TARGETS mylib
  COMPONENT core
  LIBRARY DESTINATION ${LIBDIR}
)
INSTALL(TARGETS mylib
  COMPONENT devel
  PUBLIC_HEADER DESTINATION ${INCLUDEDIR}
)
Run Code Online (Sandbox Code Playgroud)

但 PUBLIC_HEADER 似乎需要设置 LIBRARY DESTINATION 。有没有办法做到这一点?无论如何,PUBLIC_HEADER 比安装目录有什么优势吗?

Com*_*sMS 0

PUBLIC_HEADER几乎可以肯定,这个工具不适合这里的工作,除非您的共享库确实是一个 OSX 框架库。文档也明确指出了这一点。

如果您希望在安装步骤中复制头文件,则应使用以下install(FILES ...)命令:

install(FILES ${MY_PUBLIC_HEADERS} DESTINATION ${INCLUDEDIR} COMPONENT devel)
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为 CMake 无法通过查看目标来推断您可能希望或不希望成为安装集的一部分的标头。因此,手动指定文件列表实际上是指定安装标头的唯一明智的方法,并且install(FILES ...)确实做到了这一点。

您也应该避免为此使用 glob 表达式,因为显式提供文件所节省的时间并不能证明它们在破坏时带来的麻烦是合理的。

  • 我不确定文档是否那么清楚:。我(误)读到“在非 Apple 平台上,可以使用 install(TARGETS) 命令的 PUBLIC_HEADER 选项来安装这些标头。” 暗示这是一个很好的方法。将公共和私有标头分开的想法在某种程度上也很有吸引力。 (3认同)
  • CMake 确实有一种推断公共标头和私有标头的方法。当您不使用 $<BUILD_INTERFACE:> 和 $<INSTALL_INTERFACE:> 作为公共标头时,它甚至会抱怨,尽管拒绝在 Windows 上进行任何安装 (3认同)