C ++ Статически связанная разделяемая библиотека - PullRequest
26 голосов
/ 09 июля 2011

У меня есть общая библиотека, используемая другим приложением вне моего контроля, для которого требуются объекты * .so. Моя библиотека использует sqlite3, который должен быть статически связан с ним (мне абсолютно необходим автономный двоичный файл).

Когда я пытаюсь скомпилировать и связать свою библиотеку:

-fpic -flto -pthread -m64
-flto -static -shared

Я получаю следующую ошибку:

/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

С чем связана перекомпиляция с -fPIC ? Мой код или ЭЛТ?

Я уже пытался скомпилировать мой объект с -fPIC с тем же результатом.

Спасибо.

EDIT:

Проблема, похоже, не связана с SQLite3.

Я написал простую библиотеку с одной строкой, которая ничего не делает, которая компилирует и ссылается следующим образом:

g++ -c -fPIC -o bar.o bar.cpp
g++ -shared -o bar.so bar.o

но не так:

g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o

Проблема, похоже, связана с ЭЛТ (crtbeginT.o). Я должен перекомпилировать GCC - с рис. Или что-нибудь?

Ответы [ 3 ]

39 голосов
/ 10 июля 2011

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

Если у вас есть только статическая версия библиотеки, вы можете просто связать ее с помощью-lsqlite3.Но если есть и динамическая версия (.so), и статическая версия, компоновщик предпочтет динамическую.

Чтобы указать компоновщику выбрать статическую, присвойте компоновщику флаг -Bstatic, изаставить его переключиться обратно на динамическое связывание для других вещей (таких как libc и динамическая поддержка времени выполнения) с -Bdynamic.То есть вы используете флаги:

 -Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

Альтернативно, вы можете просто указать полный путь к файлу .a, например /usr/lib/libsqlite3.a вместо любых флагов компилятора / компоновщика.

С GNU ld вы также можете использовать -l:libsqlite3.a вместо -lsqlite3.Это заставит использовать библиотечный файл libsqlite3.a вместо libsqlite3.so, который по умолчанию предпочитает компоновщик.

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

8 голосов
/ 09 июля 2011

Любой код, который каким-то образом попадет в динамическую библиотеку, должен быть перемещаемым.Это означает, что все, что связано с вашим .so, независимо от того, статически или динамически, должно быть скомпилировано с -fPIC.В частности, статическая библиотека sqlite также должна быть скомпилирована с -fPIC.

Подробная информация о том, что означает PIC: http://en.wikipedia.org/wiki/Position-independent_code

0 голосов
/ 28 июля 2015

У меня была такая же проблема.По-видимому, -static - это не то же самое, что -Bstatic.Я перешел на -Bstatic и все заработало.

...