如何分发使用cmake构建的静态库

时间:2019-07-16 06:34:57

标签: c++ cmake

我有一个cmake项目,它是一个静态库,我必须与公司中的其他团队共享,而只是.lib文件而不是源代码。 该库取决于Boost。

现在,我构建库并将安装文件夹转移到另一台pc(exe_pc)上,并在exe项目中使用它(此exe也取决于boost)。 现在,在编译时,我收到一个链接错误,指出无法打开E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib

所以我打开并检查生成的LibTargets.cmake,它包含构建库的PC的boost库的绝对路径。

# The installation prefix configured by this project.
set(_IMPORT_PREFIX "C:/Program Files/cpp_licensing")

# Create imported target Licensing::liblicensing
add_library(Licensing::liblicensing STATIC IMPORTED)

set_target_properties(Licensing::liblicensing PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "_LICENSING_DEBUG=0"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_system-vc140-mt-gd.lib>;\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_filesystem-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_filesystem-vc140-mt-gd.lib>;cryptopp-static;wbemuuid"
)

LibLicensingTargets-release.cmake

et_target_properties(Licensing::liblicensing PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
  IMPORTED_LOCATION_RELEASE "C:/Program Files/cpp_licensing/lib/licensing.lib"
  )

list(APPEND _IMPORT_CHECK_TARGETS Licensing::liblicensing )
list(APPEND _IMPORT_CHECK_FILES_FOR_Licensing::liblicensing "C:/Program Files/cpp_licensing/lib/licensing.lib" )

该用户应该已经安装了Boost,我唯一的问题是,由于目标文件中使用了绝对路径,因此用户必须在其PC上的目标文件中手动更改它们。

我对cmake进行了哪些更改,以便可以共享库构建的文件夹。 我如何分发使用cmake构建的库?

这是图书馆项目的重要内容

cmake_minimum_required(VERSION 3.10)
project(liblicensing)

message("~~ Project: " ${PROJECT_NAME})

set(LIB_NAME "${PROJECT_NAME}")
set(PROJECT_VERSION 1.0)

include_directories(
        ${PROJECT_SOURCE_DIR}/include
)

if (WIN32)
    find_package(Boost REQUIRED system filesystem)
    find_package(cryptopp REQUIRED)
    find_package(unofficial-date REQUIRED)
    include_directories(
            ${Boost_INCLUDE_DIR}
    )

else()
    find_package(date REQUIRED)
endif ()

file(GLOB_RECURSE HEADER_FILES include/*.h include/*.hpp)
file(GLOB_RECURSE SOURCES src/*.cpp)

add_library(${LIB_NAME} STATIC ${SOURCES} ${HEADER_FILES} )

set_target_properties(
        ${LIB_NAME}
        PROPERTIES
        OUTPUT_NAME "licensing"
        POSITION_INDEPENDENT_CODE ON
        CXX_STANDARD 14
        CXX_STANDARD_REQUIRED YES
        CXX_EXTENSIONS NO
        LINKER_LANGUAGE CXX
)

if (MSVC)
    set_target_properties(${LIB_NAME} PROPERTIES DEBUG_POSTFIX "_d")
endif()

add_library(Licensing::liblicensing ALIAS ${LIB_NAME})

set(INSTALLATION_DIR "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_LIBDIR "${INSTALLATION_DIR}/lib")
set(CMAKE_INSTALL_BINDIR "${INSTALLATION_DIR}/bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})

target_include_directories(${LIB_NAME}
        PUBLIC
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
        )

if (WIN32)
    target_link_libraries(
            ${LIB_NAME}
            ${Boost_LIBRARIES}
            cryptopp-static
            wbemuuid
    )

else()
    target_link_libraries(
            ${LIB_NAME}
            cryptopp
            boost_system
            boost_filesystem
    )
endif ()

if(CMAKE_BUILD_TYPE MATCHES Debug)
    target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=1)
elseif(CMAKE_BUILD_TYPE MATCHES Release)
    target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=0)
endif()

# Expose Projects's public includes to other subprojects through cache variable.
set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)


###############
# Installation
##

install(TARGETS ${LIB_NAME}
        EXPORT LibLicensingTargets
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
#        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${LIB_NAME}
        FILES_MATCHING PATTERN "*.h*")

install(EXPORT LibLicensingTargets
        FILE LibLicensingTargets.cmake
        NAMESPACE Licensing::
        DESTINATION ${INSTALL_CONFIGDIR}
        )


#####################
# ConfigVersion file
##
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
        ${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
        VERSION ${PROJECT_VERSION}
        COMPATIBILITY AnyNewerVersion
)

configure_package_config_file(
        ${CMAKE_CURRENT_LIST_DIR}/CMake/LibLicensingConfig.cmake.in
        ${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
        INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)

## Install all the helper files
install(
        FILES
        ${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
        DESTINATION ${INSTALL_CONFIGDIR}
)

1 个答案:

答案 0 :(得分:0)

不是完整的答案,但评论太多:

如果您仔细检查文件LibLicensingTargets.cmake,则会发现cryptopp-staticwbemuuid并没有解析到库级别。

在查看如何引用Boost时,您使用的旧版本(${Boost_LIBRARIES})可以分解为库级别。

请尝试按以下方式使用FindBoost.cmake模块提供的目标:

if (WIN32)
    target_link_libraries(
            ${LIB_NAME}
            Boost::system
            Boost::filesystem
            cryptopp-static
            wbemuuid
    )

else()
    target_link_libraries(
            ${LIB_NAME}
            cryptopp
            Boost::system
            Boost::filesystem
    )
endif()

让我感到困惑的另一件事是为什么您添加了ALIAS

add_library(Licensing::liblicensing ALIAS ${LIB_NAME})

ALIAS是在LibLicensingTargets.cmake文件中正确创建的,因此您无需自己创建它。

另一件事是,您要给INSTALL命令提供绝对路径。要使软件包完全可重定位,您需要使用相对路径(相对于CMAKE_INSTALL_PREFIX,安装目录)。

因此,以下命令应更改为:

set(CMAKE_INSTALL_LIBDIR "lib")
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})

如果您进一步添加以下行:

export(TARGETS liblicensing NAMESPACE LibLicensing:: FILE LibLicensingTargets.cmake)

到您的CMakeLists.txt,从安装了许可的外部项目就可以从构建树文件夹中导入目标。请参阅CMake documentation of the export command.