Ошибки компоновщика при использовании библиотек интерфейса с несколькими реализациями - PullRequest
0 голосов
/ 21 января 2019

Я работаю над перемещением базы кода в cmake, где в зависимости от того, какой исполняемый файл создается, требуются разные реализации конкретной библиотеки.В некоторых случаях это происходит из-за того, что полученные исполняемые файлы имеют разные требования / возможности, но во многих случаях мы можем использовать реализации, которыми можно управлять с помощью модульных тестов, которые не используются в рабочей среде.

Поскольку библиотеки нуждаются вЧтобы зависеть от интерфейсов, а не от реализаций, в некоторых случаях cmake не может правильно построить дерево зависимостей, что приводит к сбою шага компоновки (проблема описана здесь ).

Например, рассмотримследующий надуманный пример.Существует 2 библиотеки a & b, где b зависит от a, а a имеет две реализации.Я определил цели следующим образом в CMakeLists.txt:

add_library(lib-a-intf INTERFACE)
target_include_directories(lib-a-intf INTERFACE lib-a)

add_library(lib-a-impl-a impl-a/impl-a.cpp)
target_link_libraries(lib-a-impl-a PUBLIC lib-a-intf)

add_library(lib-a-impl-b impl-b/impl-b.cpp)
target_link_libraries(lib-a-impl-b PUBLIC lib-a-intf)

add_library(lib-b lib-b.cpp)
target_link_libraries(lib-b PRIVATE lib-a-intf)
target_include_directories(lib-b PUBLIC lib-b)

А затем исполняемый файл извлекает нужную ему версию в соответствии с его требованиями

add_executable(main main.cpp)
target_link_libraries(main lib-a-impl-b lib-b)

Поскольку cmake не может установитьдо правильного порядка ссылок, это не может сделать ссылку на неопределенную ссылку для функций, определенных в библиотеке a.

Я знаю несколько обходных путей, но они не оптимальны.Определение библиотеки a реализации как библиотеки объектов работает, но не хорошо масштабируется, так как эти реализации будут перекомпилированы для каждого исполняемого файла.Использование флага компоновщика --whole-archive также работает, но также плохо масштабируется, так как приводит к тому, что исполняемые файлы больше, чем необходимо, поскольку невостребованные символы в библиотеке a не будут собирать мусор.

Есть ли способ в cmakeуказать, что библиотека реализует интерфейсную библиотеку, так что порядок ссылок правильный?Кроме того, есть ли способ изменить способ определения библиотек для решения этой проблемы?

...