【发布时间】:2023-03-13 19:00:01
【问题描述】:
首先我想提供一些背景信息以避免XY Problem。
我正在尝试使用 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
当我调用 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 告诉我它找不到程序,因为库加载器是错误的(即使这个细节我不太明白)。
所以基本上我的问题是:当我为链接器指定-static 选项时,为什么库加载器会设置为libc.so,以及当指定-static 时如何告诉链接器使用正确的库加载器?
【问题讨论】:
-
找到了一种解决方法,如下所述:stackoverflow.com/questions/6578484/…。通过使用 -l:liblibname.a。这与 n.m. 的解决方案一样有效
标签: linux makefile linker g++ ld