CMake ссылается на неверную версию библиотеки - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть несколько пакетов CMake, которые зависят от Protobuf v2.5, и один, который зависит от Protobuf v3.4.Я установил v2.5 для всей системы в /usr, тогда как v3.4 используется только в одном пакете.Поэтому я помещаю заголовки для v3.4 в подкаталог 3rdparty внутри пакета, в котором он используется, а затем вызываю include_directories(3rdparty) в моем CMakeLists.txt, чтобы его можно было найти.

Какдля общих библиотек .so файлы для v2.5 присутствуют в /usr/lib/x86_64-linux-gnu, и я установил .so файлы для v3.4 до /usr/lib.Короче говоря, вот так выглядит структура каталогов:

v2.5:
заголовки: /usr/include
библиотеки: /usr/lib/x86_64-linux-gnu

v3.4:
заголовки: <MY_PACKAGE_SRC_DIRECTORY>/3rdparty
библиотеки: /usr/lib

Теперь возникает проблема, когда я пытаюсь установить связь с v3.4.Чтобы упростить задачу, я не использую какие-либо файлы модуля CMake для поиска protobuf v3.4, я просто добавляю жестко заданный путь /usr/lib/libprotobuf.so в список библиотек, с которыми нужно ссылаться при создании цели.Но даже в этом случае, когда я запускаю ldd my_target_executable, результат:

libprotobuf.so.8 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.8

означает, что он связывается с библиотеками v2.5 в /usr/lib/x86_64-linux-gnu, хотя ядобавлен жестко заданный путь к правильному файлу .so в /usr/lib при вызове target_link_libraries при сборке этого исполняемого файла.

Стоит отметить, что если я удаляю файлы .so в /usr/lib/x86_64-linux-gnu, затем он связывается с правильным файлом .so в /usr/lib, поэтому кажется, что по какой-то причине CMake выполняет поиск в /usr/lib/x86_64-linux-gnu перед использованием пути к библиотеке, который я предоставляю.Как я могу изменить это поведение или исправить эту проблему любым другим способом?

ОБНОВЛЕНИЕ
Файл библиотеки для v3.4 /usr/lib/x86_64-linux-gnu/libprotobuf.so являетсяссылка на /usr/lib/x86_64-linux-gnu/libprotobuf.so.14, которая, в свою очередь, является ссылкой на фактический файл /usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0.

Теперь, если я изменю жестко закодированный путь, который я даю в target_link_libraries, с /usr/lib/x86_64-linux-gnu/libprotobuf.so на вторую символьную ссылку /usr/lib/x86_64-linux-gnu/libprotobuf.so.14 или на фактический файл /usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0, то мой исполняемый файл правильно связываетсяagaint v3.4.Похоже, что имя предоставленной символической ссылки оказывает некоторое влияние на поведение CMake.

1 Ответ

0 голосов
/ 03 декабря 2018

Это не только cmake, но и то, как все работает в Linux с gcc и общими библиотеками.

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

Когда вы указываете target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so), это устанавливает связь как -lprotobuf.В этом случае он должен просто использовать любую версию библиотеки, которую он находит первой.

target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so.14) настраивает сгенерированную cmake линию связи для использования определенной версии библиотеки.Похоже, это указывает gcc на ссылку на эту версию, которая изменит то, что происходит во время выполнения и поиска в библиотеке.

target_link_libraries

В некоторых случаяхCMake может попросить компоновщик выполнить поиск библиотеки (например, /usr/lib/libfoo.so становится -lfoo), например, когда обнаруживается, что в общей библиотеке нет поля SONAME.См. Политику CMP0060 для обсуждения другого случая.

...