mar*_*o.b 4 linux linker makefile g++ ld
首先我想提供一些背景信息以避免XY 问题。
我正在尝试使用 makefile 和 g++ 编译 C++ 程序。我还必须将任何依赖项静态构建到程序中,但不是“系统库”(libz.so、libdl.so、libstdc++.so、libm.so、libpthread.so和libc.so)libgcc.so。
为了实现这一点,我指定-static为链接器标志,然后所有必须静态链接的依赖项,然后我使用该-Wl, -Bdynamic选项,该选项应该告诉链接器链接每个库,在此选项之后,动态链接,包括“系统库”因为它们是最后链接的。(如果我错了,请纠正我。)
LDFLAGS += -Lpath/to/dependencies
# These libs should be linked statically
LDFLAGS += -static
LDFLAGS += -llib1
LDFLAGS += -llib2
LDFLAGS += -llib3
# Libs after this should be linked dynamically.
LDFLAGS += -Wl, -Bdynamic
LDFLAGS += -lz # If i dont specify these three libraries (z, pthread, dl)
LDFLAGS += -lpthread # I get undefined reference errors
LDFLAGS += -ldl
Run Code Online (Sandbox Code Playgroud)
当我调用 make 时,程序编译和链接得很好,但是当我尝试执行它时,出现错误:bash: ./program: No such file or directory。但该文件确实存在。
当我从链接器中删除-static标志时,程序可以很好地执行,但是依赖项是动态链接的,这不是我想要的:(。
因此,当我调用file使用该标志制作的程序时-static,我得到以下信息:
program: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), dynamically linked, interpreter /usr/lib/libc.so.1, for GNU/Linux 4.9.0, not stripped
问题似乎是解释器被设置为/usr/lib/libc.so.1而不是/lib/ld-linux.so.2通常应该设置的。至少,当我在没有-static选项的情况下编译时是这样。
我发现“解释器”实际上是共享库加载器,从我读到的内容来看,我现在假设 bash 告诉我它找不到该程序,因为库加载器是错误的(尽管我不知道)不太明白这个细节)。
libc.so所以基本上我的问题是:当我为链接器指定选项时,为什么库加载器会被设置为-static,以及如何告诉链接器在-static指定时使用正确的库加载器?
您的错误是混合-static并-Bdynamic作为编译器和链接器标志。不要那样做。如果您使用-Wl,gcc 只是盲目地将这些标志传递给链接器,但如果您不这样做,它会重新排列整个链接行。(检查它的作用gcc -v)。
这种混合会产生不一致且错误的链接命令。我不知道为什么 gcc 至少不会对此发出警告,但它不会,并且默默地将动态加载器设置为不存在的文件。
您希望始终如一地使用-Wl,-Bstatic和。-Wl,-Bdynamic不是-Bstatic和-Bdynamic,因为 gcc 逻辑与 ld 不同。
这将创建一个正确的动态链接可执行文件,其中链接了一些静态库。
| 归档时间: |
|
| 查看次数: |
2115 次 |
| 最近记录: |