Как заставить компоновщик и загрузчик выбрать разделяемую библиотеку по определенному пути? - PullRequest
2 голосов
/ 06 марта 2012

Я написал код, для которого у меня есть Makefile, например:

CC=gcc
CXX=g++
DEBUG=-g
COMPILER=${CXX}
#INCLUDE= -I Re2/ -I Re2/re2/
#WARN=-Wall
spambin: main.cpp Mail.o trie.o Spambin.o config.o getdns.o
        ${COMPILER}  ${DEBUG} ${WARN} -o spambin main.cpp Mail.o trie.o Spambin.o config.o getdns.o   /usr/lib/libre2.so

trie.o: trie.cpp
        ${COMPILER}  ${DEBUG} ${WARN} -c trie.cpp ${INCLUDE}

Mail.o: Mail.cpp
        ${COMPILER} ${DEBUG} ${WARN} -c Mail.cpp ${INCLUDE}

config.o: config.cpp
        ${COMPILER} ${DEBUG} ${WARN} -c config.cpp ${INCLUDE}

Spambin.o: Spambin.cpp
        ${COMPILER} ${DEBUG} ${WARN} -c Spambin.cpp ${INCLUDE}

getdns.o: getdns.c
        ${CC} ${DEBUG} ${WARN} -c getdns.c ${INCLUDE}
clean: 
        rm -f *.o

Проблема, с которой я сталкиваюсь, заключается в том, что я хочу, чтобы мой код напрямую выбрал /usr/lib/libre2.so. Выполнение ldd для конечного двоичного файла дает:

linux-gate.so.1 =>  (0x00693000)
libre2.so.0 => /usr/lib/libre2.so.0 (0x00159000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x004f4000)
libm.so.6 => /lib/libm.so.6 (0x00ce8000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x002b8000)
libc.so.6 => /lib/libc.so.6 (0x00b83000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00d13000)
/lib/ld-linux.so.2 (0x00b64000)

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

linux-gate.so.1 =>  (0x0018b000)
libre2.so.0 => /usr/local/lib/libre2.so.0 (0x00b89000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x0040f000)
libm.so.6 => /lib/libm.so.6 (0x00ad2000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00c5e000)
libc.so.6 => /lib/libc.so.6 (0x0096c000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00ab9000)
/lib/ld-linux.so.2 (0x00949000)

Двоичный путь - /usr/local/lib/libre2.so.0.

Есть ли способ заставить компилятор выбрать файл .so из нашего предпочтительного пути?

1 Ответ

2 голосов
/ 06 марта 2012

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

  1. Пусть моя библиотека: libtest2.so (она находится в /projects/tests/test_so)
  2. Пусть файл моей основной программы cpp: main.cpp Тогда:

    g++ main.cpp -o test /projects/tests/test_so/libtest2.so

Создает двоичный файл test который содержит абсолютный путь / projects / tests / test_so .Куда бы вы ни переместили двоичный файл test , он всегда будет искать / projects / tests / test_so / libtest2.so

В качестве альтернативы вы можете посмотреть -rpath переключатель, который вы можете использовать с gcc (на самом деле это переключатель компоновщика), например:

gcc -Wl,-rpath,'<path-to-lib-directory>'

Но этот подход может заставить вашу программу искать и другие общиебиблиотеки в <path-to-lib-directory>, которые могут быть не совсем такими, как вы хотите.

...