Приложение, связывающее 2 версии одной и той же библиотеки из-за зависимостей - PullRequest
0 голосов
/ 14 июня 2019

У меня проблемы с библиотекой (libpng), которую мое приложение динамически связывает в Linux.

Используемая версия libpng - libpng15. Так как мое приложение также связывает DI-GUY, который связывает libpng3, эти 2 версии конфликтуют. Под "clash" я имею в виду, что компоновщик (ldd) выбирает libpng3 вместо libpng15.

Если я посмотрю на вывод ldd, в списке указаны и libpng15, и libpng3. Порядок следующий:

    libpng.so.3 => ../lib/libpng.so.3 (0x00007f4bccdff000)
    libpng15.so.15 => ../lib/libpng15.so.15 (0x00007f4bc5d1b000)

В CMake я проверяю, что я ссылаюсь на 15, а именно:

add_library(PNG::Shared SHARED IMPORTED)
    set_target_properties(PNG::Shared PROPERTIES
    IMPORTED_LOCATION ${_IMPORT_PREFIX}/lib/libpng15.so.15.4.0
    INTERFACE_INCLUDE_DIRECTORIES ${_IMPORT_PREFIX}/include
    INTERFACE_LINK_LIBRARIES z
)

Насколько я понимаю, приложение должно взять libpng15, но, поскольку libpng.so.3 в ldd выше версии 15, компоновщик выбирает libpng.so.3.

Как можно заставить мое приложение использовать libpng15.so.15, а библиотека DI-GUY будет использовать libpng.so.3. Так как я не могу перекомпилировать DI-GUY, я застрял с libpng.so.3, который также связан, но его не следует путать с версией 15 ...

Что я не понимаю, так это почему libpng.so.3 даже рассматривается, так как я явно ссылаюсь на libpng15.so.15.4.0

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

Правильным решением было сделать библиотеку, которая связывает libpng3, связать ее в приватном режиме:

target_link_libraries(${TARGET} PUBLIC 
    VigFramework
    PedestriansBDI_Base
    DIGUY::GraphicsApi
    DIGUY::Main
    DIGUYDevil::Main
    TBB::Main2
    Qt4::QtCore
    Qt4::QtSql
    Qt4::QtGui
    Qt4::QtXml
    Qt4::QtNetwork
    Tiff::Main
)

target_link_libraries(${TARGET} PRIVATE 
    PNG3::Shared #required for DIGUY
)

Это будет гарантировать, что основное приложение связывается с libpng15 и не будет загрязнено libpng3 издругие библиотеки.

0 голосов
/ 14 июня 2019

Вы должны использовать find_package, чтобы найти вашу конкретную версию библиотеки:

find_package(<package> [version] [EXACT] ...)

В документации сказано:

Аргумент [version] запрашивает версию, с которой был найден пакет должен быть совместимым (формат является основным [.minor [.patch [.tweak]]]). Параметр EXACT запрашивает точное совпадение версии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...