如何将外部(共享)库包含在几个dll / dylib中

时间:2018-01-23 08:07:36

标签: c++ cmake

我需要将外部构建的(共享)库集成为逻辑 将目标构建到我的CMake配置中,该配置由几个组成 共享库文件(dlls / dylibs)。 通常我会做以下事情:

find_path(MyLib_INCLUDE_DIR mylib.h HINTS ${MyLib_PATH}/include)
find_library(MyLib_LIBRARY NAMES MyLib HINTS ${MyLib_PATH}/bin)
find_library(MyLib_LIBRARY_DEBUG NAMES MyLib_d ${MyLib_PATH}/bin)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib DEFAULT_MSG
  MyLib_LIBRARY MyLib_LIBRARY_DEBUG MyLib_INCLUDE_DIR)

if(MyLib_FOUND AND NOT TARGET MyLib::MyLib)
  set(MyLib_LIBRARIES ${MyLib_LIBRARY})
  set(MyLib_INCLUDE_DIRS ${MyLib_INCLUDE_DIR})

  add_library(MyLib::MyLib UNKNOWN IMPORTED)
  set_target_properties(MyLib::MyLib PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES ${MyLib_INCLUDE_DIR}
    IMPORTED_LOCATION ${MyLib_LIBRARY}
    IMPORTED_LOCATION_DEBUG ${MyLib_LIBRARY_DEBUG})

    mark_as_advanced(MyLib_INCLUDE_DIR MyLib_LIBRARY MyLib_LIBRARY_DEBUG)
endif()

我的理解是add_library(... UNKOWN IMPORTED)会CMake 找出共享/静态库本身(并根据选项 BUILD_SHARED_LIBS可能,但这不是必要的)。然而, CMake不允许向属性添加库列表 IMPORTED_LOCATION。对于Instance,如果我想导入MyLib, MyLibFoo和MyLibBar都作为调试和发布版本,但事实并非如此 可能使用列出的方法。

我知道add_library(MyLib::MyLib INTERFACE IMPORTED)并设置了一个 属性INTERFACE_LINK_LIBRARIES的库列表,但是这个 在创建可重定位包的情况下是有问题的(如 在CMake文档中提到)。此外,没有这样的 属性为INTERFACE_LINK_LIBRARIES_DEBUG,因此它只会是 可以指我的发布或调试版本 外部导入的图书馆。

那么,我该如何导入我的外部构建的库作为 可重定位的就绪逻辑CMake目标,实际上包括几个 调试还是发布构建共享库文件?

免责声明:我已经在CMake邮件列表上问过这个问题,但到目前为止还没有收到任何答复。

1 个答案:

答案 0 :(得分:5)

  

但是,CMake不允许向IMPORTED_LOCATION属性添加库列表。

这是合乎逻辑的,因为单个库(甚至 IMPORTED )应该只有一个文件。

只需为每个实际库创建一个库 IMPORTED 目标:

add_library(MyLib::MyLibFoo UNKNOWN IMPORTED)
  set_target_properties(MyLib::MyLibFoo PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES ${MyLibFoo_INCLUDE_DIR}
    IMPORTED_LOCATION ${MyLibFoo_LIBRARY}
    IMPORTED_LOCATION_DEBUG ${MyLibFoo_LIBRARY_DEBUG})

add_library(MyLib::MyLibBar UNKNOWN IMPORTED)
  set_target_properties(MyLib::MyLibBar PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES ${MyLibBar_INCLUDE_DIR}
    IMPORTED_LOCATION ${MyLibBar_LIBRARY}
    IMPORTED_LOCATION_DEBUG ${MyLibBar_LIBRARY_DEBUG})

创建一个INTERFACE IMPORTED库目标,链接上面的目标:

add_library(MyLib::MyLib INTERFACE IMPORTED)
set_property(TARGET MyLib::MyLib PROPERTY
  INTERFACE_LINK_LIBRARIES MyLib::MyLibFoo MyLib::MyLibBar)

因此,当用户链接MyLib::MyLib时,他实际上链接了所有库。