Номера версий в общих объектных файлах - PullRequest
11 голосов
/ 23 апреля 2011

Я создаю общий объектный файл из группы исходных файлов C ++, используя GCC.Во всех примерах по созданию файлов .so показан файл, созданный с номером версии после суффикса .so.Например:

gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1  calc_mean.o

Это приведет к созданию файла .so libmean.so.1.0.1

Кроме того, если я просматриваю каталог /usr/lib на моем локальном компьютере, я вижучто многие из файлов .so имеют номера версий в конце.

Однако, когда я компилирую общий объектный файл и помещаю его в /usr/lib, компоновщик не может найти его, если я поставил версиюномер в конце.Если я удаляю номер версии, он работает нормально.Меня действительно не интересует номер версии или нет, я просто не понимаю, почему это кажется общим соглашением, и все же это приводит к тому, что разделяемая библиотека не работает с компоновщиком.Итак, что здесь происходит?Почему существует соглашение о размещении номера версии в конце .so имени файла?

1 Ответ

17 голосов
/ 23 апреля 2011

Номер версии добавляется, так что вы можете иметь несколько несовместимых версий библиотеки, сосуществующих в системе.Вы должны увеличивать основной номер версии (число в soname) каждый раз, когда вы изменяете API несовместимым способом (конечно, при условии, что предыдущая версия установлена ​​и используется в системе).

2-йи 3-е числа в имени файла допускают несколько незначительных ревизий библиотеки в системе, которые можно переключать в масштабе всей системы с помощью простого обновления символической ссылки.

Во время ссылки вы можете указать имя файла .so в качестве компоновщикааргумент, вместо -l опция.ldd достаточно умен, чтобы извлечь из него soname, связанный с ним двоичный файл использует его для поиска библиотеки.

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

czajnik@czajnik:~/z$ gcc -shared -Wl,-soname,libtest.so.2 -o libtest.so.2.3.4  a.c 
czajnik@czajnik:~/z$ gcc -o test b.c -L. ./libtest.so.2.3.4

Вы можете использовать ldd, чтобы убедиться, что двоичный файл теперь ищет libtest.so.2:

czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test
    linux-gate.so.1 =>  (0x002c1000)
    libtest.so.2 => not found
    libc.so.6 => /lib/libc.so.6 (0x00446000)
    /lib/ld-linux.so.2 (0x00a28000)

Очевидно, он не может его найти, но для этого предназначена символическая ссылка:

czajnik@czajnik:~/z$ ln -s libtest.so.2.3.4 libtest.so.2
czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test
    linux-gate.so.1 =>  (0x00d75000)
    libtest.so.2 => ./libtest.so.2 (0x00e31000)
    libc.so.6 => /lib/libc.so.6 (0x00a5e000)
    /lib/ld-linux.so.2 (0x00378000)

Обновление: Все вышеизложенное верно, но я сам не знал о значении третьего компонента номера версии.До недавнего времени я считал, что это просто номер патча (или похожая вещь).Неправильно!Для libtool это имеет особое значение.

3-й компонент оказался полем age , в котором указано , сколько основных версий обратно совместимы стекущий .

Рекомендуемое чтение:

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