What does -fPIC mean when building a shared library?
Asked Answered
C

3

140

I know the '-fPIC' option has something to do with resolving addresses and independence between individual modules, but I'm not sure what it really means. Can you explain?

Chromaticness answered 8/6, 2009 at 20:54 Comment(1)
Also in case you want to know in more detail there's a great article here(akkadia.org/drepper/dsohowto.pdf)Frazier
A
82

PIC stands for Position Independent Code.

To quote man gcc:

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 AArch64, m68k, PowerPC and SPARC.

Use this when building shared objects (*.so) on those mentioned architectures.

Acclimate answered 8/6, 2009 at 20:58 Comment(5)
f doesn't mean anything, it's just part of the option name.Jaquesdalcroze
There is a difference between fpic and fPIC. They both do the same thing but fpic uses a shorter relative offset where available. Thus compiling with fpic can potentially produce smaller files. Unfortunately it does not always work as expected so use fPIC. Also Note not all processors support the shorter offsets so it may not make a difference.Anacreon
The 'f' is a hangover from the way that gcc handeled command line arguments (this was a couple of years ago and they have changed this part of the code I have not looked recently). But at the time only certain letters or combinations were allowed under different conditions (there was a very complex language for defining command line arguments) as a result the 'f' was used to make it easy to define as a command line argument.Anacreon
What will happen if one build a *.so without fPIC?Bleach
@IsaA I was compiling a c-api mysql function from source today and it wouldn't build, I got /usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC so I added fPIC and it built.Stet
T
42

The f is the gcc prefix for options that "control the interface conventions used in code generation"

The PIC stands for "Position Independent Code", it is a specialization of the fpic for m68K and SPARC.

Edit: After reading page 11 of the document referenced by 0x6adb015, and the comment by coryan, I made a few changes:

This option only makes sense for shared libraries and you're telling the OS you're using a Global Offset Table, GOT. This means all your address references are relative to the GOT, and the code can be shared accross multiple processes.

Otherwise, without this option, the loader would have to modify all the offsets itself.

Needless to say, we almost always use -fpic/PIC.

Tyndareus answered 8/6, 2009 at 21:10 Comment(2)
I thought the OS was free to load the library in any virtual address, but without pic/PIC the loader has to modify the code and adjust all the absolute jumps + indirections to the actual locations of the routines / libraries. With pic/PIC the code is not modified and thus it is really shared across multiple processes.Talie
Multiple processes are largely coincidental - they key point is that the code can be loaded at any virtual address with an absolute minimum of address fixups.Tipi
C
21

man gcc says:

-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 program starts (the dynamic
  loader is not part of GCC; it is part of the operating system). If
  the GOT size for the linked executable 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 therefore
  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.

-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
  and the SPARC.

  Position-independent code requires special support, and therefore
  works only on certain machines.
Cloistral answered 8/6, 2009 at 21:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.