Как заставить символы из статической библиотеки быть включенными в сборку общей библиотеки?

Я пытаюсь создать общую библиотеку объектов, которая будет открыта программой, используя dlopen(). Эта библиотека будет использовать функциональные возможности, предоставляемые отдельной статичной библиотекой.

Я включил соответствующий флаг в линию ссылок, чтобы вытащить статическую библиотеку при связывании динамического (например, у меня есть -lfoo для libfoo.a), и компоновщик не жалуется. Однако, когда основная программа вызывает dlopen() в динамической библиотеке, вызов завершается с сообщением "undefined", ссылающимся на символ из статической библиотеки.

Запуск nm указывает, что данный символ имеет значение undefined в динамической библиотеке, а основная программа не содержит его, так как я могу заставить компоновщик вытащить этот символ? Сам символ находится в секции неинициализированных данных (тип символа "B" в выходе nm).

Ответ 1

Опция компоновщика --whole-archive должна сделать это. Вы бы использовали его, например,

gcc -o libmyshared.so foo.o -lanothersharedlib -Wl,--whole-archive -lmystaticlib

То, что вы испытываете, заключается в том, что по умолчанию компоновщик будет искать символы в статическом архиве, которые вы создаете для двоичного файла, а если он нужен, он будет содержать целое .o, в котором находится символ. Если вашей общей библиотеке не нужны какие-либо символы, они не будут включены в вашу общую библиотеку.

Помните, что код, который становится разделяемой библиотекой, должен быть скомпилирован со специальными параметрами, такими как -fpic, поскольку вы включаете статическую библиотеку в вашу общую библиотеку, статическая библиотека должна быть скомпилирована с теми же параметрами.

Ответ 2

Недавно я искал решение для него. Я нашел, используя

--undefined=symbol

или

-u symbol

решает проблему.

Ответ 3

Другой взлом - это взять адрес функции где-нибудь во время инициализации библиотеки. Это позволит вам фактически использовать символ.