代码之家  ›  专栏  ›  技术社区  ›  Gearoid Murphy

Linux G++将64位共享库代码链接到静态库

  •  8
  • Gearoid Murphy  · 技术社区  · 14 年前

    上下文:我可以创建一个共享对象库,它链接到一个静态库,在32位Linux上没有任何问题。当我在64位Linux上尝试相同的构建时,我看到这个链接器错误:

    • 在创建共享对象时,不能使用相对于“本地符号”的重新定位r_x86_64_32s;请使用-fpic重新编译

    这个错误在网络上很常见。解决方案是用位置无关代码(fpic)编译静态链接库。

    我不明白的是为什么32位构建不需要这样做。有人能帮忙吗?

    2 回复  |  直到 14 年前
        1
  •  4
  •   paulsm4    14 年前

    如果对象模块将在共享库中使用,则始终需要“位置独立代码”。它高度依赖于平台,并且会产生一些开销。

    您必须在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. 
    
        2
  •  4
  •   Gearoid Murphy    14 年前

    好的,答案在这里详细描述: http://www.technovelty.org/code/c/amd64-pic.html .

    解释的基本要点是i386体系结构隐式地取消引用每个函数的帧指针(在链接页的最后一段中解释)。这个过程会产生一些额外的开销,所以在新的64位体系结构中,这种取消引用的开销被作为优化消除了。

    从链接的角度来看,这种优化的结果是,除非64位代码显式编译为位置无关的代码,否则它将生成硬编码的代码,其中包含执行上下文的偏移量。

    这是对链接页中内容的不完美解释,但对我来说已经足够了。