C++ Статически связанная разделяемая библиотека

У меня есть общая библиотека, используемая другим приложением вне моего контроля, для которого требуются объекты *.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 с тем же результатом.

Благодарю.

РЕДАКТИРОВАТЬ:

Проблема, похоже, не связана с 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 - с-pic или что-нибудь?

3 ответа

Решение

Вы не должны использовать -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 флаг, иначе вы обычно не можете встроить его в общую библиотеку.

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

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

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

Другие вопросы по тегам