首先,我想提供一些背景信息以避免XY 问题。
我正在尝试使用 makefiles 和 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
当我调用 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
and -Bdynamic
,因为 gcc 逻辑与 ld 不同。
这将创建一个正确的动态链接可执行文件,其中链接了一些静态库。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句