LINUX.ORG.RU

Как скомпилить статически динамическую библиотеку?

 , ,


0

2

Есть код

#include <iostream>
int main(){
    std::cout<<"zzz"<<std::endl;
}
Собираю его статически
#g++ -static test.cc
#ldd ./a.out 
	not a dynamic executable
Все ок. Собираю на его основе .so
#g++ -shared test.cc -o test.so
#ldd test.so 
	linux-gate.so.1 =>  (0xb77cd000)
	libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7642000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb748c000)
	libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7437000)
	/lib/ld-linux.so.2 (0xb77ce000)
	libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb741a000)
Теперь хочу сделать его без зависимостей
#g++ -shared -Wl,-static test.cc -o test.so
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
Как скомпилить статически динамическую библиотеку?

если ты не знал, -shared и -static указывают, с какими версиями библиотек линковать, а не какой будет выходной файл

короче убери -shared из последней строчки

Harald ★★★★★ ()
Ответ на: комментарий от anonymous

ТС хочет .so со статически вкомпиленными зависимостями

Harald ★★★★★ ()
Ответ на: комментарий от Harald
$ g++  -Wl,-static test.cc -o test.so
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status

Если убрать -shared то он будет компилить исполняемый файл а не .so https://linux.die.net/man/1/g -shared Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when you specify this option.[1]

$ g++ -static test.cc -o test.so
/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status

Spinel ()

Если компилить так g++ -shared -static-libstdc++ test.cc -o test.so то удалось отвязать от с++ либ.

$ g++ -shared -static-libstdc++ test.cc -o test.so
$ ldd test.so 
	linux-gate.so.1 =>  (0xb778a000)
	libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7620000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb746a000)
	/lib/ld-linux.so.2 (0xb778b000)

Spinel ()
Ответ на: комментарий от Spinel

/usr/bin/ld: cannot find -lgcc_s

ну и возможно статическая версия libgcc отдельным пакетом идёт, какой у тебя дистр?

Harald ★★★★★ ()
Ответ на: комментарий от Spinel
$ g++ -shared -static-libgcc -static-libstdc++ test.cc -o test.so
$ ldd test.so 
	linux-gate.so.1 =>  (0xb76ec000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb73e3000)
	/lib/ld-linux.so.2 (0xb76ed000)

Осталось понять как от libc отвязать!!!!

Spinel ()
Ответ на: комментарий от Harald

Если добавить -static или -Bstatic то еще хуже

g++ -shared -static-libgcc -static-libstdc++ -static  test.cc -o test.so
ldd test.so 
	linux-gate.so.1 =>  (0xb7726000)
	libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb759b000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb73e5000)
	libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7390000)
	/lib/ld-linux.so.2 (0xb7727000)
	libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7373000)

Spinel ()
Ответ на: комментарий от Spinel

Мне всегда казалось сошки это shared по определению (это такая же программа, её даже можно выполнять исполняя файл). Статично линкуешь уже программу, со статичными версиями конкретных библиотек. Сошка тянущая говно неизвестных версий других либ в себе (со всеми багами и уязвимостями), это какая-то глупость.

anonymous ()
Ответ на: комментарий от Spinel

Статически линковать libc в динамическую либу — очень плохая идея. Ну и по-хорошему тебе скорее всего придется перекомпилировать libc.a с -fPIC.

Может быть сработает, если у тебя 32-битная сборка:

g++ -shared -static-libgcc -static-libstdc++ test.cc /lib/libc.a -o test.so

Путь к libc.a поправь, как нужно.

buddhist ★★★★★ ()
Ответ на: комментарий от buddhist
$ g++ -shared -static-libgcc -static-libstdc++ test.cc //usr/lib/i386-linux-gnu/libc.a -o test.so
/usr/bin/ld: read-only segment has dynamic IFUNC relocations; recompile with -fPIC
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: error: ld returned 1 exit status
Spinel ()
Ответ на: комментарий от Spinel

Зачем оно (libc.a) лежит там без -fPIC, вот вопрос. Почему сразу в пакет не класть нормальный libc.a c -fPIC?

Deleted ()
Ответ на: комментарий от Spinel

Для простоты придется обратиться к сторонней libc.

Попробуй такие шаги (на свой страх и риск в плане совместимости всех либ):

1. Качаешь (допустим, в ~/musl) сорцы musl: https://www.musl-libc.org/download.html
2. Собираешь musl так:

$ CFLAGS=-fPIC ./configure --disable-shared && make
Сборка занимает в пределах минуты. Хотя, по-моему, -fPIC там и так есть, но на всякий случай лучше его явно указать.
3. Собираешь свою либу так:
g++ -fPIC -shared -static-libgcc -static-libstdc++ -L/home/$(whoami)/musl/lib test.cc -o test.so

На моей машине собралось статически, импорт потом нормально сработал, тоже проверил.

Может быть, так можно сделать и с GLIBC, не знаю.

buddhist ★★★★★ ()
Последнее исправление: buddhist (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.