Доброго времени суток!
Использую следующее, файл 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, но внаружи их использоввать как динамически библиотеки?
Если можно, то как это сделать? Если нет, то можно не объяснять или вкратце.