【问题标题】:How to create both static and shared libraries at one go using CMake?如何使用 CMake 一次性创建静态库和共享库?
【发布时间】:2021-09-10 18:06:52
【问题描述】:

在我的项目中,静态库是使用 cmake 创建的。但现在我想改变它来创建和支持静态库和共享库。

有人可以帮我解决这个问题吗?

下面是我现有的静态库脚本:

include(bundle_static_library.cmake)

set(BINARY camsdk)

set(CMAKE_VERBOSE_MAKEFILE ON)

include_directories("../../OpenSource/boost_1_75_0")
if(CMAKE_HOST_WIN32)
add_definitions(-DBOOST_DATE_TIME_NO_LIB)
endif()
include_directories(Include)
include_directories("../Dependencies/CamSupport/h")

file(GLOB_RECURSE SOURCES LIST_DIRECTORIES true *.h *.cpp)
set(SOURCES 
    ${SOURCES}
    ${CMAKE_CURRENT_LIST_DIR}/../CamVisionLibrary/Source/VisionClient.cpp)

if(CMAKE_HOST_UNIX)
    add_compile_options(-fpic -Wall -Werror)
    add_definitions(-DBOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX)
elseif(CMAKE_HOST_WIN32)
    # all warnings as errors
    add_compile_options(/W4 /WX)
    add_definitions(-D_UNICODE -DUNICODE)
endif ()

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    set(BUILD_TYPE "debug")
else()
    set(BUILD_TYPE "release")
endif() 

if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
    set(PLATFORM "macos")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    set(PLATFORM "windows")
else()
    set(PLATFORM "linux")
endif()

# We depend on another static library EMR
add_library(EMR STATIC IMPORTED)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    if(NOT CMAKE_CL_64)
        message(STATUS "Architecture: x86")
        set_property(TARGET EMR PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/Library/emr/lib/${PLATFORM}-x86-${BUILD_TYPE}-static/testemr-cc.lib)
    else()
        message(STATUS "Architecture: x64")
        set_property(TARGET EMR PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/Library/emr/lib/${PLATFORM}-x64-${BUILD_TYPE}-static/testemr-cc.lib)
    endif()
else()
    set_property(TARGET EMR PROPERTY IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/Library/emr/lib/${PLATFORM}-x64-${BUILD_TYPE}-static/libtestemr-cc.a)
endif()

# First build a temporary library
set(TMP_BINARY camsdk-tmp)
add_library(${TMP_BINARY} STATIC ${SOURCES})
target_link_libraries(${TMP_BINARY} PUBLIC EMR)

bundle_static_library(${TMP_BINARY} ${BINARY})

【问题讨论】:

  • 这应该是第一次运行 cmake 时的配置选项,还是每次构建都需要两个目标?
  • 嗨@Marek R,我们每次构建都需要两个目标。
  • 只需创建另一个库目标,将共享一个。例如。 add_library(${TMP_BINARY}-shared SHARED ${SOURCES})。你需要像往常一样链接这个库。
  • 感谢@Tsyvarev 的建议。我将创建库目标并链接库,如下所示。但在那之后如何将它与共享库捆绑在一起,就像我们使用 bundle_static_library 作为静态库一样。 add_library(${TMP_BINARY}-shared SHARED ${SOURCES}) target_link_libraries(${TMP_BINARY} PUBLIC EMR)
  • “但在那之后如何捆绑它......” - 你所说的“捆绑”是什么意思?例如。 bundle_static_library.cmake 合并静态库到单个静态库中。此过程对共享库没有意义。

标签: c++ cmake shared-libraries static-libraries


【解决方案1】:

我记得,处理这个问题的最佳方法是使用 CMake 对象库。对象库包含已编译的对象,然后您可以使用共享和静态版本包装这些对象。这避免了编译两次的需要。例如:

add_library(something OBJECT lib/something.cpp)
target_include_directories(something PUBLIC lib)

add_library(something_shared SHARED)
target_link_libraries(something_shared PUBLIC something)

add_library(something_static STATIC)
target_link_libraries(something_static PUBLIC something)

在此示例中,您编译一次 .cpp,然后使用可以链接到的共享静态版本包装该库。

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2020-03-02
    • 2013-07-04
    • 1970-01-01
    • 2021-03-18
    • 2012-07-10
    相关资源
    最近更新 更多