Связывание приложения с libbz2.so.1, а не с libbz2.so.1.0 - PullRequest
5 голосов
/ 02 декабря 2009

Вот текущая ситуация, в которой я нахожусь:

Я хочу распространять бинарное приложение для Linux, которое будет работать в нескольких дистрибутивах (не все из них, только основные из них на данный момент имеют значение, давайте сосредоточимся на Ubuntu и Fedora ради этого обсуждения). Рассматриваемое приложение ссылается на libbz2 для некоторых своих работ. Простой «Hello World» проиллюстрирует ситуацию:

/* main.cpp */
#include <iostream>

int main(int argc, char* argv[])
{
  std::cout << "Hello World!\n";
  return 0;
}

Приложение построено так:

g++ -lbz2 -o test.bin main.cpp

Моя система сборки установлена ​​на Ubuntu. Когда я выполняю проверку с помощью ldd в полученном двоичном файле, он перечисляет libbz2.so.1.0 как зависимость времени выполнения. Когда я беру это приложение на компьютер Fedora, оно не запускается, и ldd показывает, что не может найти libbz2.so.1.0. Fedora имеет только libbz2.so.1 и libbz2.so.1.0.4, но не libbz2.so.1.0.

База данных Red Hat Bugzilla показывает, что это не ошибка, а особенность. Мне действительно не нужен libbz2.so.1.0, и я был бы удовлетворен простой связью с libbz2.so.1, но мне еще предстоит выяснить, как.

Я видел подобный вопрос, заданный здесь ранее , но принятый ответ (Вы можете передать фактический файл .so вместо -l в командной строке компоновщика), похоже, не работает. Я попытался построить с помощью следующей команды:

g++ /lib/libbz2.so.1 -o test.bin main.cpp

Тем не менее, ldd все еще упоминает, что приложение зависит от libbz2.so.1.0, хотя я передал полное имя g ++.

Теперь вопрос в том, существует ли в Ubuntu способ создать приложение, чтобы оно зависело только от libbz2.so.1, а не от libbz2.so.1.0?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 03 декабря 2009

Вот немного предыстории, чтобы объяснить, что связано. На платформах ELF передаваемые флаги -L и -l определяют местоположение только двоичного файла во время соединения. Если компоновщик компоновщика определяет, что библиотека требуется, он генерирует ссылку на SONAME в этом двоичном файле независимо от того, как он был вызван. Например:

$ objdump -p /lib64/libbz2.so.1 | grep SONAME
  SONAME      libbz2.so.1

Таким образом, независимо от того, как называется libbz2, это то, что будет отображаться как зависимость. Снова на примере, делая что-то совершенно сломанное:

$ ln -s /lib64/libbz2.so.1 libblah.so
$ g++ t.C -L. -l blah

У вас есть очевидная связь с libblah, но поскольку значение SONAME в этом двоичном файле имеет значение, ваша зависимость по-прежнему равна libbz2.so.1

$ ldd a.out | grep bz2
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00002b3d1a000000)

Кроме хитрости -static (которая может сломать вещи интересным образом), не существует простого выхода из беспорядка (в идеале библиотека должна делать хорошие версии символов, такие как glibc, и никогда или редко менять свое SONAME).

3 голосов
/ 02 декабря 2009

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

В прошлом я делал это для сборок на Ubuntu и развертывания на RHEL, что прекрасно работает с использованием статических сборок.

...