英文:
When static library needs position independent code
问题
a.c
是作为静态库liba.a
构建的。
b.c
是作为共享库libb.so
构建的。
然后liba.a
与libb.so
链接(即包含在内)。
main.c
是作为可执行文件构建的,并与libb.so
进行动态链接。
Makefile如下:
all:
gcc -c -fPIC -o a.o a.c
ar rcs liba.a a.o
gcc -c -fPIC -o b.o b.c
gcc -shared -o libb.so b.o liba.a
gcc -o main -L. -lb
因为b.o
变成了共享库,所以使用了位置无关代码标志来编译它。那么a.o
也需要构建为位置无关代码吗,因为它将被包含在共享库中呢?至少在我测试的系统上,当移除第一个-fPIC
时似乎也可以正常工作。
此外,如果main.c
更改为声明extern int a()
并调用它(假设libb.so
使其可见),那么是否需要将a.o
编译为位置无关代码呢?(在我的系统上,即使a.o
没有-fPIC
也可以正常工作)。
英文:
There are 3 files a.c, b.c, main.c:
// a.c
int a() { return 123; }
// b.c
extern int a();
int b() { return a(); }
// main.c
#include <stdio.h>
extern int b();
int main() {
printf("%d\n", b());
return 0;
}
a.c
is build as a static library liba.a
.
<br>
b.c
is build as a shared library libb.so
.
<br>
liba.a
is then linked with (i.e. included into) libb.so
.
<br>
main.c
is built as an executable, and dynamically linked to libb.so
.
The Makefile looks like:
all:
gcc -c -fPIC -o a.o a.c
ar rcs liba.a a.o
gcc -c -fPIC -o b.o b.c
gcc -shared -o libb.so b.o liba.a
gcc -o main -L. -lb
b.o
is compiled with the position-independent code flag, because it becomes a shared library.
Is it necessary to also build a.o
as position-independent code, because it will be included into a shared library? At least on the system I'm testing it on, it seems to work fine when the first -fPIC is removed.
Also, if main.c
would be changed to also declare extern int a()
and call it (assuming libb.so
makes it visible), would it then be needed to compile a.o
as position-independent code? (On my system this also works without the -fPIC for a.o
).
答案1
得分: 1
Yes, all code that goes into shared library has to be compiled with -fPIC
regardless of whether it's in an object file or static library.
It works without -fPIC
in your case because modern distros enable -fPIC
by default for security reasons:
$ echo 'int x; int foo() { return x; }' | gcc -x c - -S -o- | grep rip
movl x(%rip), %eax
It's better to keep it explicit in your build scripts for clarity though.
英文:
Yes, all code that goes into shared library has to be compiled with -fPIC
regardless of whether it's in an object file or static library.
It works without -fPIC
in your case because modern distros enable -fPIC
by default for security reasons:
$ echo 'int x; int foo() { return x; }' | gcc -x c - -S -o- | grep rip
movl x(%rip), %eax
It's better to keep it explicit in your build scripts for clarity though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论