Подтвердить что ты не робот

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

По крайней мере, в Linux и Solaris статические библиотеки - это всего лишь куча скомпилированных .o, брошенных в один большой файл. При компиляции статической библиотеки обычно используется флаг -fpic, поэтому сгенерированный код зависит от положения.

Теперь скажите, что моя статическая библиотека - B. Я ее построил и получил полученный файл .a, который на самом деле является просто глотком всех зависимых от позиции файлов .o. Теперь у меня есть общая библиотека, которую я хотел бы построить, A, и я хочу, чтобы она статически связывала B. Когда я строю A, я, естественно, буду использовать флаг -fpic, чтобы сделать сгенерированную позицию кода независимой. Но если я связываюсь с B, не смешаю ли я положение зависимых от положения и позиционных объектных файлов?

Я получаю много ошибок перемещения текста, если не указать также -mimpure-text, и я думаю, что это может быть причиной. Кажется, когда я компилирую библиотеку, мне действительно нужно ее скомпилировать 3 раза, общую версию, статическую версию и версию static-that-be-be-used-by-shared-libs. Я прав? Я мог бы просто использовать -mimpure-text, но man-страница g++ говорит, что если вы сделаете это, на самом деле объект не будет разделяться (неясно, все ли они не разделены или только статически связанные части, хотя кто-нибудь знает?),

4b9b3361

Ответ 1

Вам не нужно использовать PIC-код в общих объектах (так как вы обнаружили, что можете использовать параметр -mimpure-text, чтобы это разрешить).

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

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

Для меня важная проблема заключается в том, будет ли одновременно выполняться несколько процессов, каждый из которых загружает общий объект. Если вы это сделаете, то определенно стоит убедиться, что весь код внутри SO - это PIC.

Но если это не так, и только один процесс имеет загруженный общий объект, он не так критичен.

Ответ 2

Я делаю следующее на этапе ссылки для версии библиотеки статических библиотек общих объектов: g++ -shared -o libshared.so -Wl, - whole-archive -fPIC -lstatic -Wl, - no-whole -архив. Поскольку -whole-archive связывает каждый объект в (списке) статических libs (формы libstatic.a), я считаю, что предшествующий (список) с -fPIC - это все, что нужно OP.

Ответ 3

В качестве альтернативного подхода отправьте две библиотеки: вашу общую и статическую, с которой вы связываетесь. Они должны правильно вписываться в окончательный исполняемый файл.