Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cmake使用PUBLIC_头将库文件和开发文件作为单独的组件安装_Cmake - Fatal编程技术网

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

cmake使用PUBLIC_头将库文件和开发文件作为单独的组件安装,cmake,Cmake,我希望创建两个包,一个包含共享库,另一个包含开发使用的头 有效的解决方案是: INSTALL(TARGETS mylib COMPONENT core LIBRARY DESTINATION ${LIBDIR} ) INSTALL ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPONENT devel DESTINATION ${INCLUDEDIR} FILES_MATCHING PATTERN "*.h") 然

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

有效的解决方案是:

INSTALL(TARGETS mylib
  COMPONENT core
  LIBRARY DESTINATION ${LIBDIR}
)
INSTALL (
    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMPONENT devel
    DESTINATION ${INCLUDEDIR}
    FILES_MATCHING PATTERN "*.h")
然而,CMake也有一个“PUBLIC_HEADER”目的地。 这样您就可以执行以下操作:

INSTALL(TARGETS mylib
  LIBRARY DESTINATION ${LIBDIR}
  PUBLIC_HEADER DESTINATION ${INCLUDEDIR}
)
我好像没法让它工作。即使将头文件显式添加到ADD_LIBRARY(),也不会将任何内容安装到${INCLUDEDIR}。有人能举一个例子说明这是如何工作的吗

另一个问题是,我希望库和头在不同的包中,因此理想情况下我希望:

INSTALL(TARGETS mylib
  COMPONENT core
  LIBRARY DESTINATION ${LIBDIR}
)
INSTALL(TARGETS mylib
  COMPONENT devel
  PUBLIC_HEADER DESTINATION ${INCLUDEDIR}
)
但公共_头似乎要求设置库目的地。 有办法做到这一点吗? PUBLIC_HEADER比install DIRECTORY有什么优势吗?

几乎肯定是错误的工具,除非您的共享库实际上是一个OSX框架库。文件中也明确指出了这一点

如果希望在安装步骤中复制头文件,则应使用:

install(FILES ${MY_PUBLIC_HEADERS} DESTINATION ${INCLUDEDIR} COMPONENT devel)
这是有意义的,因为CMake无法通过查看目标来推断您可能希望或不希望成为安装集的一部分的头。因此,手动指定文件列表确实是为安装指定头的唯一合理方法,而
install(FILES…
正是这样做的


您也应该避免使用glob表达式,因为显式提供文件可能节省的时间并不能证明文件中断时会带来的麻烦。

您必须实际设置库的
PUBLIC\u HEADER
属性才能工作

我将标题放在
include/mylib
中,这样它们就位于自己的“名称空间”中,以避免冲突

这样做:

# initializes ${CMAKE_INSTALL_*DIR} to sane defaults
include(GNUInstallDirs)

add_library(
    mylib
    src/src1.cpp src/src2.cpp
    include/mylib/header1.h include/mylib/header2.h
)

# this needs to be a list, so a ; separated string in cmake
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/header1.h;include/header2.h")

# headers are now installed to ${CMAKE_INSTALL_PREFIX}/include/mylib, and
# library into ${CMAKE_INSTALL_PREFIX}/lib or ${CMAKE_INSTALL_PREFIX}/lib64 depending on arch
install(
    TARGETS mylib
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
)
set(MYLIB_HEADERS include/mylib/header1.h include/mylib/header2.h)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "${MYLIB_HEADERS}")
通过创建如下变量,可以绕过列表中有点难看的设置:

# initializes ${CMAKE_INSTALL_*DIR} to sane defaults
include(GNUInstallDirs)

add_library(
    mylib
    src/src1.cpp src/src2.cpp
    include/mylib/header1.h include/mylib/header2.h
)

# this needs to be a list, so a ; separated string in cmake
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/header1.h;include/header2.h")

# headers are now installed to ${CMAKE_INSTALL_PREFIX}/include/mylib, and
# library into ${CMAKE_INSTALL_PREFIX}/lib or ${CMAKE_INSTALL_PREFIX}/lib64 depending on arch
install(
    TARGETS mylib
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
)
set(MYLIB_HEADERS include/mylib/header1.h include/mylib/header2.h)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "${MYLIB_HEADERS}")
文件:


我不确定文档是否清楚:。我(mis)读到“在非苹果平台上,可以使用install(TARGETS)命令的PUBLIC_HEADER选项安装这些头。”这意味着这是一种很好的方法。分离公共和私有标题的想法也很有吸引力。@BruceAdams我同意,这是一个很容易犯的错误,特别是如果你正在寻找一个能满足你要求的功能。CMake确实有一种推断公共和私有标题的方法。它甚至抱怨当你不使用$和$作为公共头时,尽管除了在Windows上之外,它拒绝进行任何安装。我一直试图使用公共头来达到这个目的。Daniel Pfeiffer在关于现代cmake的演讲中间接地介绍了它,它在windows上运行时可以工作/安装它们。无法找出我在linux上做错了什么…@JonathanOlson你让它工作了吗?