Повысить библиотеки, построенные с относительными путями

Я построил boost 1.57.0 в QNX 6.5.0. Там нет ошибки сборки. Но некоторые библиотеки связаны с libboost_system.so, указывая относительный путь. Я сохранил журналы компиляции. Вот шаг связывания для boost_thread:

"QCC_gpp"   -o "bin.v2/libs/thread/build/qcc/release/threading-multi/libboost_thread.so.1.57.0"  -shared "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/thread.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/once.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/future.o" "bin.v2/libs/system/build/qcc/release/threading-multi/libboost_system.so.1.57.0"    -lm 

Итак, когда я бегу ldd libboost_thread.so, он не может найти libboost_system. Я думаю, что libboost_thread должен быть связан с -lboost_system вариант. Но я не знаю, как это сделать.

Благодарю.

Изменить: я не могу построить любую программу, связывающую с boost_thread. Потому что boost_thread ищет boost_system в bin.v2/libs/system/build/qcc/release/threading-multi папка. Однако и boost_thread, и boost_system находятся в папке поиска библиотеки. (определяется с LD_LIBRARY_PATH)

3 ответа

Решение

Если вы бежите objdump -p libboost_thread.soвы обнаружите, что запись NEEDED для libboost_system.so содержит (относительный) путь. Согласно спецификации ELF, запись NEEDED должна содержать только имя нужной библиотеки, поэтому в компоновщике или в QCC, похоже, есть ошибка.

Потому что, если это так, система не сможет найти файл во время выполнения, если текущий каталог не будет таким, каким он был при установлении связи.

Самый простой обходной путь - это статическая ссылка на libboost_thread.a.

Другой обходной путь, который я использовал сам, - это создание оболочки вокруг QCC, которая преобразует командную строку так, что зависимости задаются как -Wl,-L <path> -Wl,-l <name> вместо <path>/lib<name>.so Это также требует внесения изменений в систему сборки Boost, чтобы он не добавлял номер версии в конец имен файлов библиотеки.

Как писал Никлас Ангаре, проблема в том, NEEDED запись содержит относительный путь во время сборки, когда он должен просто содержать имя.so файла.

Это происходит потому, что общие библиотеки, переданные компоновщику, не имеют SONAMEи это происходит потому, что компоновщику не была предоставлена ​​опция -h.

Из документации ld:

имя
-soname=имя
При создании общего объекта ELF установите для внутреннего поля DT_SONAME указанное имя. Когда исполняемый файл связан с общим объектом, имеющим поле DT_SONAME, то при запуске исполняемого файла динамический компоновщик будет пытаться загрузить общий объект, указанный в поле DT_SONAME, а не с использованием имени файла, данного компоновщику.

Почему компоновщик не получает опцию -h для qcc строить? Похоже, это давно пропущенная ошибка Boost (см. Тикет Boost.org, выпуск github)

Решение, как предлагается в приведенных выше ссылках, заключается в удалении $(HAVE_SONAME) от tools/build/v2/tools/qcc.jam

Я думаю, что вы должны взять библиотеки из зоны подготовки.

У меня обычно есть что-то похожее на:

-L /home/.../boost/stage/lib/ -lboost_system

Конечно замена /home/.../boost с вашим каталогом повышения


Немного связано: с вышеуказанным конфигом вам нужно убедиться, что правильные версии библиотек находятся в пути к библиотеке загрузчика (LD_LIBRARY_PATH, ldconfig).

Если вам нужна сборка разработки, которую вы можете "просто запустить" в системе, на которой вы ее построили, вы можете запечь путь к библиотеке прямо в целевой двоичный файл:

-Wl,-rpath -Wl,/home/.../boost/stage/lib/:/usr/lib/x86_64-linux-gnu
Другие вопросы по тегам