gcc -fPIC 与 -shared

gcc -fPIC vs. -shared

使用 gcc / g++ 编译共享库时,为什么 -fPIC 没有被 -shared 选项暗示?或者,换句话说,link 时是否需要选项 -fPIC

简而言之,我应该写成:

gcc -c -fPIC foo.c -o foo.o
gcc -shared -fPIC foo.o -o libfoo.so  // with -fPIC

或者以下是否足够:

gcc -c -fPIC foo.c -o foo.o
gcc -shared foo.o -o libfoo.so // without -fPIC

内置到共享库中的代码通常但不强制是位置无关的代码,以便共享库可以很容易地加载到内存中的任何地址。 -fPIC 选项确保 GCC 生成这样的代码。它不是必需的,因此 -shared 中没有隐含,因此 GCC 提供了选择的自由。如果没有这个选项,编译器可以对该位置相关的代码进行一些优化。

如果一个进程想要在同一虚拟地址加载多个共享库,位置相关代码可能会发生错误。由于库无法预测可以加载哪些其他库,因此传统共享库概念无法避免此问题。虚拟地址 space 在这里没有帮助。如果您的应用程序不使用很多其他共享库并且它们在您之前加载,您可以预测您的库的加载地址并将其定义为您的位置相关库的基地址。

共享库应该在进程之间共享,可能并不总是可以在两个进程中的相同地址加载库。如果代码不是位置独立的,那么每个进程都需要自己的副本。