Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux g++ linking 64 bit shared library code to static libraries

Context: I can create a shared object library which is linked to a static library without any problems on 32bit linux. When I attempt the same build on 64bit linux, I see this linker error:

  • relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC

This error is quite common on the web. The solution is to compile the statically linked library with position independent code (-fPIC).

What I do not understand is why this is not required for the 32bit build. Can anyone help out?

like image 977
Gearoid Murphy Avatar asked Aug 23 '10 14:08

Gearoid Murphy


People also ask

Can shared library be statically linked?

What are Shared Libraries in C? Shared libraries are libraries that use dynamic linking vs static linking in the compilation steps for compiling a file. Static and dynamic linking are two processes of collecting and combining multiple object files in order to create a single executable file.

Can you link a static library to a dynamic library?

When you want to “link a static library with dynamic library”, you really want to include the symbols defined in the static library as a part of the dynamic library, so that the run-time linker gets the symbols when it is loading the dynamic library.

How do I link a static library?

Static libraries are created by copying all necessary library modules used in a program into the final executable image. The linker links static libraries as a last step in the compilation process. An executable is created by resolving external references, combining the library routines with program code.

How do I connect to a shared library?

Shared libraries (also called dynamic libraries) are linked into the program in two stages. First, during compile time, the linker verifies that all the symbols (again, functions, variables and the like) required by the program, are either linked into the program, or in one of its shared libraries.


1 Answers

"Position Independent Code" is always required if your object module will be used in a shared library. It's highly platform dependent, and it incurs some overhead.

The reason you have to specify it explicitly on amd64, but not x386, is simply that it happens to be the default for x86, but not amd64.

Note, too, the difference between "-fpic" and "-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. 
like image 73
paulsm4 Avatar answered Nov 15 '22 20:11

paulsm4