Создать shared object (.so) со статически влинкованой libc внутри
От: GhostCoders Россия  
Дата: 16.03.16 08:42
Оценка:
Доброго времени суток!

Использую следующее, файл hello_library.cpp:
#include <iostream>

extern "C" void hello_library()
{
    std::cout << "Hello, Library!" << std::endl;
}


файл main.cpp:
#include <iostream>

extern "C" void hello_library();

int main()
{
    std::cout << "Hello, World!" << std::endl;
    hello_library();
    return 0;
}


Хочется собрать такую "универсальную" shared object библиотеку, которую можно было бы запускать на любом Linux с ядром 2.6 и выше.
Для этого использую Alpine Linux, который мне посоветовали в топике
Автор: GhostCoders
Дата: 13.02.16
.
Сразу после установки Alpine ставим необходимые пакеты:
apk add clang gcc g++


Для начала просто соберем библиотеку и пример:
clang++ -shared -o libhw_s.so hello_library.cpp


на выходе имеем libhw_s.so:
file ./libhw_s.so
./libhw_s.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

ldd ./libhw_s.so
        ldd (0x697a112e1000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x697a10d8f000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x697a10b7c000)
        libc.musl-x86_64.so.1 => ldd (0x697a112e1000)

то есть сейчас на выходе получили shared object, динамически линкованный, требующий для запуска libstdc++.so.6, libgcc_s.so.1 и libc.musl-x86_64.so.1.

Теперь соберем пример:
clang++ -o main_s main.cpp -lhw_s -L./


на выходе имеет исполняемый файл main_s:
file ./main_s
./main_s: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, not stripped

ldd ./main_s
        /lib/ld-musl-x86_64.so.1 (0x778b4be3b000)
        libhw_s.so => .//libhw_s.so (0x778b4ba37000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x778b4b6e7000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x778b4b4d4000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x778b4be3b000)

./main_s
Hello, World!
Hello, Library!


Исполняемый файл, как ожидалось, требует для запуска libhw_s.so, а также stdc++ и muscl libc.

Теперь попытаемся избавиться от зависимости к динамическим библиотекам stdc++ и muscl libc.

файл main2.cpp:
#include <iostream>

int main()
{
    std::cout << "Hello, Main2!" << std::endl;
    return 0;
}


Компилируем:
clang++ -static -o main2 main2.cpp


имеем на выходе main2:

file ./main2
./main2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

ldd ./main2
ldd: ./main2: Not a valid dynamic program

./main2
Hello, Main2!


что и требовалось получить.

В теперь вопрос: можно ли получить shared object (динамическую библиотеку) libhw.so, которая не будет имеет зависимостей от динамических библиотек stdc++ и muscl libc?

Я делал так:
clang++ -shared -static -o libhw.so hello_library.cpp
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400170
# Имеем предупреждение

 file ./libhw.so
./libhw.so: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

ldd ./libhw.so
ldd: ./libhw.so: Not a valid dynamic program


И на выходе имеем исполняемый файл вместо shared object.
Поэтому и предупреждение на счет отсутствующего символа _start.

Пересобираем main_s, для того, чтобы он использовал libhw.so:
clang++ -o main_s2 main.cpp -lhw -L./


и имеем ошибки линковки
 clang++ -o main_s2 main.cpp -lhw -L./
.//libhw.so: In function `_fini':
/home/buildozer/aports/main/musl/src/musl-1.1.12/crt/x86_64/crti.s:9: multiple definition of `_fini'
/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/5.3.0/../../../crti.o:/home/buildozer/aports/main/musl/src/musl-1.1.12/crt/x86_64/crti.s:9: first defined here
.//libhw.so: In function `_init':
/home/buildozer/aports/main/musl/src/musl-1.1.12/crt/x86_64/crti.s:4: multiple definition of `_init'
/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/5.3.0/../../../crti.o:/home/buildozer/aports/main/musl/src/musl-1.1.12/crt/x86_64/crti.s:4: first defined here
.//libhw.so:(.data+0x0): multiple definition of `__dso_handle'
/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/5.3.0/crtbeginS.o:(.data.rel.local+0x0): first defined here
/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/5.3.0/crtendS.o:(.dtors+0x0): multiple definition of `__DTOR_END__'
.//libhw.so:(.dtors+0x8): first defined here
/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/5.3.0/crtendS.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
.//libhw.so:(.data+0x480): first defined here
/usr/bin/ld: error in .//libhw.so(.eh_frame); no .eh_frame_hdr table will be created.
clang-3.6: error: linker command failed with exit code 1 (use -v to see invocation)


Вопрос: можно ли вообще создавать shared object библиотеки (.so файлы), со статически влинкованными stdc++, muscl libc, но внаружи их использоввать как динамически библиотеки?
Если можно, то как это сделать? Если нет, то можно не объяснять или вкратце.
Третий Рим должен пасть!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.