Как указать предпочтение пути библиотеки?

Я компилирую С++-программу, используя g++ и ld. У меня есть библиотека .so, которую я хочу использовать во время связывания. Тем не менее, библиотека с таким же именем существует в /usr/local/lib, а ld выбирает эту библиотеку над той, которую я прямо указываю. Как я могу это исправить?

В приведенных ниже примерах файл моей библиотеки /my/dir/libfoo.so.0. Вещи, которые я пробовал, которые не работают:

  • Моя команда g++ g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • добавление /my/dir в начало или конец моей переменной $PATH en`
  • добавление /my/dir/libfoo.so.0 в качестве аргумента для g++

Ответ 1

Добавьте путь к вашей новой библиотеке LD_LIBRARY_PATH (у нее немного другое имя на Mac...)

Ваше решение должно работать с использованием опций -L/my/dir -lfoo, во время выполнения используйте LD_LIBRARY_PATH для указания местоположения вашей библиотеки.

ИЛИ

Использовать опцию rpath через gcc в путь поиска библиотеки ссылок - runtime, будет использоваться вместо поиска в стандартном каталоге (опция gcc):

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

Это полезно для временного решения. Linker сначала ищет LD_LIBRARY_PATH для библиотек, прежде чем смотреть в стандартные каталоги.

Если вы не хотите постоянно обновлять LD_LIBRARY_PATH, вы можете сделать это "на лету" в командной строке:

LD_LIBRARY_PATH=/some/custom/dir ./fooo

Вы можете проверить, какие библиотеки компоновщик знает об использовании (пример):

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0

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

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)

Ответ 2

Указание абсолютного пути к библиотеке должно работать нормально:

g++ /my/dir/libfoo.so.0  ...

Вы не забыли удалить -lfoo после добавления абсолютного пути?

Ответ 3

Это старый вопрос, но никто, кажется, не упомянул об этом.

Вам повезло, что это вообще было связано.

Вам нужно было изменить

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp

:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo

Ваш компоновщик отслеживает символы, которые необходимо решить. Если он сначала читает библиотеку, у него нет необходимых символов, поэтому он игнорирует символы в нем. Укажите библиотеки после того, что вам нужно. чтобы ссылаться на них так, чтобы ваш компоновщик имел символы, чтобы найти в них.

Кроме того, -lfoo делает поиск для файла с именем libfoo.a или libfoo.so по мере необходимости. Не libfoo.so.0. Поэтому либо ln имя, либо переименовать библиотеку как appopriate.

Для цитирования страницы gcc man:

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.

Добавление файла непосредственно в строку g++ должно работать, если, конечно, вы не ставите его до bar.cpp, в результате чего компоновщик чтобы игнорировать его из-за отсутствия необходимых символов, потому что еще не нужны символы.

Ответ 4

В качестве альтернативы вы можете использовать переменные окружения LIBRARY_PATH и CPLUS_INCLUDE_PATH, которые соответственно указывают, где искать библиотеки и где искать заголовки (CPATH также будет выполнять задание), без указания - L и -I.

Изменить: CPATH включает заголовок с -I и CPLUS_INCLUDE_PATH с -isystem.

Ответ 5

Если вы используете для работы с DLL в Windows и хотите пропустить номера версий .so в linux/QT, добавление "CONFIG + = plugin" приведет к номерам версий. Чтобы использовать абсолютный путь к .so, предоставление его компоновщику прекрасно работает, как отметил г-н Клацко.