当静态库需要位置无关代码

huangapple go评论58阅读模式
英文:

When static library needs position independent code

问题

a.c是作为静态库liba.a构建的。
b.c是作为共享库libb.so构建的。
然后liba.alibb.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 &#39;int x; int foo() { return x; }&#39; | 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.

huangapple
  • 本文由 发表于 2023年3月9日 18:36:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683423.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定