c++ 安装并导出仅限INTERFACE的库CMake

pkwftd7m  于 2023-03-20  发布在  其他
关注(0)|答案(3)|浏览(126)

这里有一个新的CMake用户。
我创建了一个简单的只包含头文件的库,包含以下CMake文件:

cmake_minimum_required(VERSION 3.7)

project(mylib VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 14)
#add_compile_options(-Wa -aslh)

# Define the library target
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE include/)

add_executable(mytest test/basic_checks.cpp)
target_link_libraries(mytest mylib)

http://foonathan.net/blog/2016/03/03/cmake-install.html开始
我了解到安装一个库并使其在另一个CMake项目中可用需要几个步骤。首先必须“安装”它,然后必须“导出”它。然后是find_package,但我将在完成前两个步骤后跨越这座桥梁。
因此,按照这个示例,我认为可以将以下内容添加到CMake文件的底部:

# Install the header file.
install(FILES include/mylib.hpp DESTINATION "include/mylib-${PROJECT_VERSION}")

但是指南也谈到了在目标上使用install,然后在目标安装命令中添加EXPORT。
这在多大程度上适用于一个只有头文件的库,在这个库中,除了头文件之外,我没有其他文件的编译代码?
如何应用中描述的步骤:http://foonathan.net/blog/2016/03/03/cmake-install.html到仅支持INTERFACE的库?由于项目中缺少.cpp文件,我不禁要问哪些指令适用,哪些指令不适用。

enyaitl3

enyaitl31#

试试这个:

cmake_minimum_required(VERSION 3.7)

project(mylib VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 14)
#add_compile_options(-Wa -aslh)

# Define the library target
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE 
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    "${PROJECT_BINARY_DIR}/mylibConfigVersion.cmake"
    VERSION 0.1
    COMPATIBILITY AnyNewerVersion
)

install(TARGETS mylib
    EXPORT mylibTargets
    LIBRARY DESTINATION lib COMPONENT Runtime
    ARCHIVE DESTINATION lib COMPONENT Development
    RUNTIME DESTINATION bin COMPONENT Runtime
    PUBLIC_HEADER DESTINATION include COMPONENT Development
    BUNDLE DESTINATION bin COMPONENT Runtime
)

include(CMakePackageConfigHelpers)
configure_package_config_file(
    "${PROJECT_SOURCE_DIR}/cmake/mylibConfig.cmake.in"
    "${PROJECT_BINARY_DIR}/mylibConfig.cmake"
    INSTALL_DESTINATION lib/cmake/mylib
)

install(EXPORT mylibTargets DESTINATION lib/cmake/mylib)
install(FILES "${PROJECT_BINARY_DIR}/mylibConfigVersion.cmake"
              "${PROJECT_BINARY_DIR}/mylibConfig.cmake"
        DESTINATION lib/cmake/mylib)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)

add_executable(mytest test/basic_checks.cpp)
target_link_libraries(mytest mylib)

cmake/mylibConfig.cmake.in的含量应该只有这个

@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/mylibTargets.cmake")
check_required_components("@PROJECT_NAME@")

如果你做了所有这些,它不仅使你只有头文件的库“可安装”,而且使它“可查找”。用户将能够像这样导入你的库:

find_package(mylib CONFIG REQUIRED)
target_link_libraries(MyApp mylib) # installed include/ path automatically added
mctunoxg

mctunoxg2#

只是对https://stackoverflow.com/a/49143782/2119944的一个小补充
可能cmake/mylibConfig.cmake.in应该看起来像这样:

@PACKAGE_INIT@

include("${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib/mylibTargets.cmake")
check_required_components("@PROJECT_NAME@")

否则它将指向本地项目目录。

6ie5vjzr

6ie5vjzr3#

在我的例子中,头文件包含在多个子目录中,我只想将它们Map到安装目录并保留相对的文件结构,我从阅读here中了解到,自cmake 3.23版本以来,文件集是实现此目的的首选方式。
这是我用来建图书馆的代码

cmake_minimum_required(VERSION 3.23.1)
include_guard(GLOBAL)
project(headerlib-proj VERSION 0.0.0 LANGUAGES C)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

add_library(mylib INTERFACE)

target_include_directories(mylib
        INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

target_sources(mylib
        INTERFACE FILE_SET HEADERS
        BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
        FILES myHeader.h)

install(TARGETS mylib
        EXPORT mylibTargets
        FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib)

install(EXPORT mylibTargets
        FILE mylibConfig.cmake
        NAMESPACE MyNamespace::
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib)

install(FILES
        ${CMAKE_CURRENT_BINARY_DIR}/mylibConfig.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/mylibTargetsVersion.cmake
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib)

export(EXPORT mylibTargets
        FILE ${CMAKE_CURRENT_BINARY_DIR}/mylibConfig.cmake
        NAMESPACE MyNamespace::)

configure_package_config_file(
        ${CMAKE_CURRENT_SOURCE_DIR}/mylibConfig.cmake.in
        ${CMAKE_CURRENT_BINARY_DIR}/mylibConfig.cmake
        INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib)

write_basic_package_version_file(
        ${PROJECT_BINARY_DIR}/mylibTargetsVersion.cmake
        VERSION 1.0.0
        COMPATIBILITY SameMajorVersion)

客户...

cmake_minimum_required(VERSION 3.23)
project(master-proj LANGUAGES CXX)

find_package(mylib CONFIG REQUIRED)

add_executable(myProgram)
target_link_libraries(myProgram PRIVATE MyNamespace::mylib)
target_sources(myProgram PRIVATE main.cpp)

相关问题