【问题标题】:g++ -static flag replaces the dynamic library loader [duplicate]g++ -static 标志替换动态库加载器[重复]
【发布时间】:2023-03-13 19:00:01
【问题描述】:

首先我想提供一些背景信息以避免XY Problem

我正在尝试使用 makefile 和 g++ 编译 c++ 程序。我还必须在程序中静态构建任何依赖项,但不是“系统库”(libz.solibdl.solibstdc++.solibm.solibpthread.solibc.solibgcc.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 时如何告诉链接器使用正确的库加载器?

【问题讨论】:

标签: linux makefile linker g++ ld


【解决方案1】:

您的错误是将-static-Bdynamic 混合为编译器和链接器标志。不要那样做。如果你使用-Wl,gcc 只是盲目地将这些标志传递给链接器,但如果你不这样做,它会重新排列整个链接行。 (检查它对gcc -v 的作用)。

混合创建一个不一致和错误的链接命令。我不知道为什么 gcc 至少不会对此发出警告,但事实并非如此,而是默默地将动态加载程序设置为不存在的文件。

您希望始终使用-Wl,-Bstatic-Wl,-Bdynamic。不是-Bstatic-Bdynamic,因为gcc 逻辑和ld 不同。

这将创建一个正确的动态链接可执行文件,其中链接了一些静态库。

【讨论】:

  • 成功了,你是英雄。谢谢。
猜你喜欢
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 2021-05-18
相关资源
最近更新 更多