Эта библиотека имеет функцию main ()
или эквивалентную точку входа и была скомпилирована таким образом, что ее можно использовать как в качестве исполняемого файла, так и в качестве общего объекта.
Вот одно предложение о том, как это сделать, хотя у меня это не работает.
Вот еще один в ответ на аналогичный вопрос о S.O , который я без зазрения совести сплагиатирую, настрою и добавлю немного пояснений.
Во-первых, исходный код нашей библиотеки примеров, test.c
:
#include
void sayHello (char *tag) {
printf("%s: Hello!\n", tag);
}
int main (int argc, char *argv[]) {
sayHello(argv[0]);
return 0;
}
Скомпилируйте это:
gcc -fPIC -pie -o libtest.so test.c -Wl,-E
Здесь мы компилируем разделяемую библиотеку ( -fPIC
), но сообщаем компоновщику, что это обычный исполняемый файл ( -pie
]), и сделать его таблицу символов экспортируемой ( -W1, -E
), чтобы ее можно было эффективно связать.
И хотя файл
скажет, что это общий объект, он действительно работает как исполняемый файл:
> ./libtest.so
./libtest.so: Hello!
Теперь нам нужно посмотреть, действительно ли он может быть динамически связан. Пример программы, program.c
:
#include
extern void sayHello (char*);
int main (int argc, char *argv[]) {
puts("Test program.");
sayHello(argv[0]);
return 0;
}
Использование extern
избавляет нас от необходимости создавать заголовок. Теперь скомпилируйте это:
gcc program.c -L. -ltest
Прежде чем мы сможем его выполнить, нам нужно добавить путь к libtest.so
для динамического загрузчика:
export LD_LIBRARY_PATH=./
Теперь:
> ./a.out
Test program.
./a.out: Hello!
и ldd a.out
покажет связь с libtest.so
.
Обратите внимание, что я сомневаюсь, что именно так компилируется glibc, поскольку он, вероятно, не такой переносимый, как сам glibc (см. man gcc
относительно -fPIC
и ] -pie
), но он демонстрирует основной механизм. Для реальных подробностей вам нужно посмотреть исходный make-файл.