linux g ++, связывающий код 64-битной разделяемой библиотеки со статическими библиотеками - PullRequest
8 голосов
/ 23 августа 2010

Контекст: я могу создать библиотеку общих объектов, которая без проблем работает на 32-битной Linux.Когда я пытаюсь сделать то же самое на 64-битной Linux, я вижу эту ошибку компоновщика:

  • перемещение R_X86_64_32S против `локального символа 'не может использоваться при создании общего объекта;перекомпилировать с -fPIC

Эта ошибка довольно распространена в Интернете.Решение состоит в том, чтобы скомпилировать статически связанную библиотеку с позиционно-независимым кодом (-fPIC).

Я не понимаю, почему это не требуется для 32-битной сборки.Кто-нибудь может помочь?

Ответы [ 2 ]

4 голосов
/ 23 августа 2010

Хорошо, ответ подробно описан здесь: http://www.technovelty.org/code/c/amd64-pic.html.

Основная суть объяснения заключается в том, что архитектура i386 неявно разыменовывает указатель кадра для каждой функции (объяснено в последнем абзаце связанной страницы).Этот процесс требует дополнительных издержек, поэтому в новых 64-разрядных архитектурах эти издержки разыменования были исключены как оптимизация.

Следствием этой оптимизации с точки зрения компоновки было то, что, если 64-разрядный код явно не скомпилированпозиционно-независимый код, он будет генерировать код, жестко запрограммированный со смещениями для контекста выполнения.

Это несовершенное объяснение содержимого на связанной странице, но этого достаточно для моих целей.

4 голосов
/ 23 августа 2010

«Независимый от позиции код» всегда требуется, если ваш объектный модуль будет использоваться в общей библиотеке.Он сильно зависит от платформы и требует дополнительных затрат.

Причина, по которой вы должны указать это явно в amd64, но не в x386, заключается в том, что это просто значение по умолчанию для x86, но не для amd64.

Обратите внимание также на разницу между "-fpic" и "-fPIC":

-fpic
    Generate position-independent code (PIC) suitable for use in a 
    shared library, if supported for the target machine. Such code 
    accesses all constant addresses through a global offset table 
    (GOT). The dynamic loader resolves the GOT entries when the pro-
    gram starts (the dynamic loader is not part of GCC; it is part
    of the operating system). If the GOT size for the linked execu-
    table exceeds a machine-specific maximum size, you get an error 
    message from the linker indicating that -fpic does not work; in 
    that case, recompile with -fPIC instead. (These maximums are 8k 
    on the SPARC and 32k on the m68k and RS/6000. The 386 has no 
    such limit.)

    Position-independent code requires special support, and there
    fore works only on certain machines. For the 386, GCC supports 
    PIC for System V but not for the Sun 386i. Code generated for 
    the IBM RS/6000 is always position-independent.

    When this flag is set, the macros __pic__ and __PIC__ are defined to 1.

-fPIC
    If supported for the target machine, emit position-independent 
    code, suitable for dynamic linking and avoiding any limit on the 
    size of the global offset table. This option makes a difference 
    on the m68k, PowerPC and SPARC.

    Position-independent code requires special support, and therefore 
    works only on certain machines.

    When this flag is set, the macros __pic__ and __PIC__ are defined to 2. 
...