target_link_libraries在链接时错误地拉入MODULE库

时间:2018-09-20 08:56:58

标签: module cmake

我有两个使用CMake 3.12.2的C ++项目。

第一个是MODULE库(一个动态加载的插件)。它会为CMake安装DLL,头文件和配置文件。

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MyPlugin LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX "d")

# MODULE libraries are dynamically loaded at runtime and never linked against
add_library(MyPlugin MODULE
    include/a.h
    src/a.cpp
    src/b.h
    src/b.cpp
)

target_include_directories(MyPlugin
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include/MyPlugin>
    PRIVATE
        src
)

install(TARGETS MyPlugin EXPORT MyPluginConfig
    # MODULE libraries are installed as LIBRARY
    LIBRARY DESTINATION plugins COMPONENT Runtime
    RUNTIME DESTINATION bin COMPONENT Runtime
    PUBLIC_HEADER DESTINATION include/MyPlugin COMPONENT Development
)
install(FILES $<TARGET_PDB_FILE:MyPlugin> DESTINATION plugins OPTIONAL COMPONENT Runtime)
install(
    DIRECTORY include/
    DESTINATION include/MyPlugin
    FILES_MATCHING PATTERN "*.h"
)
install(EXPORT MyPluginConfig
    NAMESPACE MyPlugin::
    DESTINATION lib/cmake/MyPlugin
)

第二个是一个简单的可执行文件,它通过target_link_libraries(现代CMake方式)提取插件的头文件。

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MyExe LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX "d")

find_package(MyPlugin REQUIRED)

add_executable(MyExe src/main.cpp)
target_link_libraries(MyExe MyPlugin::MyPlugin)

使用vs2015生成的解决方案,链接失败,因为在可执行文件链接期间会馈送插件DLL ...

有人对此有解决方案吗?还是应该提交错误?

致谢。

1 个答案:

答案 0 :(得分:1)

此问题的解决方案是将库分为两部分:仅提供标头的接口库和不导出任何标头的模块库。

模块库CMakeLists.txt变为:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MyPlugin LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX "d")


# Move public headers to a dedicated INTERFACE library
add_library(MyPluginInterface INTERFACE)
add_custom_target(Includes SOURCES include/a.h)
target_include_directories(MyPluginInterfacecmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MyPlugin LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX "d")


# Move public headers to a dedicated INTERFACE library
add_library(MyPluginInterface INTERFACE)
add_custom_target(Includes SOURCES include/a.h)
target_include_directories(MyPluginInterface
    INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include/MyPlugin>
)
install(TARGETS MyPluginInterface EXPORT MyPluginConfig
    PUBLIC_HEADER DESTINATION include/MyPlugin COMPONENT Development
)


# MODULE libraries are dynamically loaded at runtime and never linked against
add_library(MyPlugin MODULE
    src/a.cpp
    src/b.h
    src/b.cpp
)
target_link_libraries(MyPlugin MyPluginInterface)
install(TARGETS MyPlugin
    # MODULE libraries are installed as LIBRARY
    LIBRARY DESTINATION plugins COMPONENT Runtime
    RUNTIME DESTINATION bin COMPONENT Runtime
)
install(FILES $<TARGET_PDB_FILE:MyPlugin> DESTINATION plugins OPTIONAL COMPONENT Runtime)

install(
    DIRECTORY include/
    DESTINATION include/MyPlugin
    FILES_MATCHING PATTERN "*.h"
)
install(EXPORT MyPluginConfig
    NAMESPACE MyPlugin::
    DESTINATION lib/cmake/MyPlugin
)

    INTERFACE
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include/MyPlugin>
)
install(TARGETS MyPluginInterface EXPORT MyPluginConfig
    PUBLIC_HEADER DESTINATION include/MyPlugin COMPONENT Development
)


# MODULE libraries are dynamically loaded at runtime and never linked against
add_library(MyPlugin MODULE
    src/a.cpp
    src/b.h
    src/b.cpp
)
target_link_libraries(MyPlugin MyPluginInterface)
install(TARGETS MyPlugin
    # MODULE libraries are installed as LIBRARY
    LIBRARY DESTINATION plugins COMPONENT Runtime
    RUNTIME DESTINATION bin COMPONENT Runtime
)
install(FILES $<TARGET_PDB_FILE:MyPlugin> DESTINATION plugins OPTIONAL COMPONENT Runtime)

install(
    DIRECTORY include/
    DESTINATION include/MyPlugin
    FILES_MATCHING PATTERN "*.h"
)
install(EXPORT MyPluginConfig
    NAMESPACE MyPlugin::
    DESTINATION lib/cmake/MyPlugin
)

可执行文件CMakeLists.txt变为:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(MyExe LANGUAGES CXX)
set(CMAKE_DEBUG_POSTFIX "d")

find_package(MyPlugin REQUIRED)

add_executable(MyExe src/main.cpp)
target_link_libraries(MyExe MyPlugin::MyPluginInterface)