2015-11-20 3 views
3

Мне нужно создать общую библиотеку, чьи собственные зависимости, включая libc/libstdC++, должны быть статически связаны с ней для создания автономного двоичного файла. Я пытался сделать этоАвтономная общая библиотека

g++ -c -fpic -o foo.o foo.cpp 
g++ -static -shared -o foo.so foo.o 

который терпит неудачу с:

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

Может кто-нибудь сказать мне, что я делаю неправильно?

+1

'-fPIC', вероятно, чувствителен к регистру. Я не знаю, если это проблема. – Simple

+0

@ Простой: я пытался с '-fPIC', но я все равно получаю ту же ошибку. – user10602

+1

Попробуйте '-static-libstdC++'. См. Https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html для соответствующих ссылок. – Andrew

ответ

2

Вы можете использовать опцию -static-libstdc++, чтобы связать libstdc++ статически. Вы, вероятно, не должны статически связываться с libc (или libgcc, который вы можете связать статически с -static-libgcc, если вам нужно), если вы создаете динамическую библиотеку; вы захотите получить версию libc приложения, которое загружает вашу общую библиотеку.

Другие варианты управления статическим связыванием можно найти в GCC manual. Вы также можете добиться желаемых результатов, передав аргументы компоновщику (-Wl,<argument> или напрямую вызовите ld). В списке LD manual перечислены разрешенные варианты.


Пример:

Я написал следующий код

#include <iostream> 

extern "C" void do_something() { 
    std::cout << "Doing something!\n"; 
} 

и скомпилировал его в .o файл следующим образом:

g++ -fPIC -c -o tmp.o tmp.cpp 

Затем я произвел две разделяемые библиотеки из него , Один с -static-libstdC++, и один без:

g++ -shared -o tmp-shared.so tmp.o 
g++ -shared -static-libstdc++ -o tmp-static.so tmp.o 

Для сравнения, ldd tmp-shared.so:

linux-vdso.so.1 => (0x00007fffc6dfd000) 
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b708cb43000) 
libm.so.6 => /lib64/libm.so.6 (0x00002b708ce4c000) 
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b708d0cf000) 
libc.so.6 => /lib64/libc.so.6 (0x00002b708d2dd000) 
/lib64/ld-linux-x86-64.so.2 (0x00000035c6c00000) 

и ldd tmp-static.so:

linux-vdso.so.1 => (0x00007fff99bfd000) 
libm.so.6 => /lib64/libm.so.6 (0x00002acbec030000) 
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002acbec2b3000) 
libc.so.6 => /lib64/libc.so.6 (0x00002acbec4c1000) 
/lib64/ld-linux-x86-64.so.2 (0x00000035c6c00000) 
+1

Вам также потребуется '-static-libgcc' для удаления зависимости' libgcc_s.so.1'. –

+0

@MaximEgorushkin Конечно, если вы хотите удалить зависимость. Ответ теперь упоминает об этом, хотя обычно лучше разрешить 'libc' и' libgcc' подбираться из системы (если, конечно, динамическая 'libgcc' не присутствует в целевой системе). – Andrew

+0

@ Андрей: Спасибо! Вы также знаете, как я могу сделать полную статическую ссылку (включая libc и libm). Я знаю, что это не рекомендуется, но мне нужно сделать это для прототипа исследования. – user10602

2

Мне нужно создать общую библиотеку, чьи собственные зависимости, включая libc/libstdC++, должны быть статически связаны с ним для создания автономного двоичного кода

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

Использование многих коммерческих приложений $ORIGIN Функция компоновщика. Вы можете скопировать все необходимые общие библиотеки в каталог вместе с вашим исполняемым файлом и связать свой исполняемый файл с дополнительными флагами компоновщика. См man ld.so:

$ ORIGIN и RPATH

ld.so понимает строку $ORIGIN (или что то же самое ${ORIGIN}) в спецификации RPATH (DT_RPATH или DT_RUNPATH) означает каталог, содержащий исполняемый файл приложения.Таким образом, приложение, расположенное в , somedir/app может быть скомпилировано с gcc -Wl,-rpath,'$ORIGIN/../lib', поэтому , что он находит связанную совместно используемую библиотеку в somedir/lib независимо от того , где somedir находится в иерархии каталогов. Это облегчает создание приложений «под ключ», которые не обязательно должны быть установлены в специальные каталоги, но вместо этого могут быть распакованы в в любой каталог и по-прежнему находить свои собственные общие библиотеки.

Смежные вопросы