g ++ -static标志替换动态库加载程序

问题描述:

首先我想给出一些背景信息以避免XY Problemg ++ -static标志替换动态库加载程序

我想编译一个使用makefile和g ++的C++程序。我还必须在程序中静态构建任何依赖关系,但不是“系统库”(libz.solibdl.so, libstdc++.so,libm.so,libpthread.so,libc.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 

当我打电话做,程序编译和链接就好了,但是当我试图执行它我得到错误:bash: ./program: No such file or directory。 但文件确实存在。

当我从链接中删除-static标志,该程序可以excecuted就好了,但依赖关系是动态链接的,这不是我想要的:(。

所以,当我打电话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告诉我它无法找到程序,因为库加载器是错误的(Even尽管我不太了解这个细节)。

所以基本上我的问题是:为什么库加载程序得到设为libc.so当我指定-static选项链接,我怎么能告诉链接时指定-static使用正确的库加载器?

+0

找到一个解决方法:https://开头计算器。COM /问题/ 6578484 /说服力-GCC-直接到链接一个库静态。通过使用-l:liblibname.a。这工作以及从上午的解决方案。 – Mario

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

混合会创建不一致且错误的链接命令。我不知道为什么gcc至少不会提醒,但它不会,并且默默地将动态加载器设置为不存在的文件。

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

这里描述这将创建一个正确的动态链接的可执行文件中链接一些静态库

+0

它的工作,你是一个英雄。谢谢。 – Mario