如何配置 CMakeLists.txt 以安装共享库的公共标头?

新手上路,请多包涵

我想使用 cmake 安装我的库 edv 但是当我执行时:

 cmake --build . --target install

它安装但它只创建 bin/edv.dlllib/ < empty > 。如何使 cmake 安装 EDV_PUBLIC_INCLUDE_DIRECTORIESinclude/... 内?

这是我的 CMakeLists.txt

 cmake_minimum_required(VERSION 3.12)

project(edv)

# include PUBLIC directories
set(EDV_PUBLIC_INCLUDE_DIRECTORIES      include/ )

set(EDV_PRIVATE_INCLUDE_DIRECTORIES     src/   )

# Edv source files list
file(GLOB_RECURSE EDV_SOURCE_FILES "src/*.cpp" "src/*.hpp*")

# build the library
add_library(${PROJECT_NAME} SHARED ${EDV_SOURCE_FILES} )

target_include_directories(${PROJECT_NAME} PUBLIC ${EDV_PUBLIC_INCLUDE_DIRECTORIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${EDV_PRIVATE_INCLUDE_DIRECTORIES})

install (TARGETS ${PROJECT_NAME}
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    PUBLIC_HEADER DESTINATION include
)

原文由 FrameBuffer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 432
1 个回答

CMake 无法从目标推导出要安装的头文件集。这是有道理的,因为目标可能同时包含私有和公共头文件,但 CMake 不会区分它们。因此,您必须在 INSTALL(FILES ...) 命令中明确列出头文件:

 install(FILES ${MY_HEADER_FILES} DESTINATION include)

CMake 3.23 及更高版本的更新:

CMake 版本 3.23 引入了 File Sets ,它允许以更优雅的方式处理头文件。这样,头文件只需在 CMakeLists.txt 中列出一次,即可集成到 IDE 中并正确安装:

 cmake_minimum_required(VERSION 3.23)

# example library with sources and headers located at ${MY_LIB_SOURCE_DIR}
add_library(my_lib)
target_include_directories(my_lib PUBLIC ${MY_LIB_SOURCE_DIR})

# source files get added as before
target_sources(my_lib PUBLIC ${MY_LIB_SOURCE_DIR}/my_lib/my_lib.cpp)

# header files get added via FILE_SET
# BASE_DIR should point to the same directory that is used as the
# target_include_directory, otherwise the install paths may be off.
target_sources(my_lib PUBLIC FILE_SET HEADERS
  BASE_DIRS ${MY_LIB_SOURCE_DIR}
  FILES ${MY_LIB_SOURCE_DIR}/my_lib/my_lib.hpp)

# install command needs to reference the file set again
install(TARGETS my_lib FILE_SET HEADERS)

3.23 更新结束

您偶然发现的 PUBLIC_HEADER 字段与 OSX 框架机制有关,这是它自己的蠕虫罐。我建议你远离它,除非你真的想在 OSX 上将你的库部署为 .framework

请特别注意 INSTALL(TARGET ...) 命令的 INCLUDES DESTINATION 选项。虽然这实际上并不复制任何文件本身,但它允许将包含目录自动添加到配置包脚本提供的导入目标中。如果您打算向您的用户提供一个包配置脚本(您可能应该这样做,至少如果您希望您的用户也使用 CMake),您可能需要设置此选项。

由于总体上安装机制相当复杂,我有 一个小型 github 项目,您可以在其中观察所有元素的运行情况。

原文由 ComicSansMS 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题