我正在尝试使用gcc为Android(linux)创建一个共享库,就像这样(为了清晰起见而简化):
g++ -Wl,-soname,liba.so -Wl,--no-undefined -shared -o liba.so b.o libc.a libd.a
其中b.o使用libc.a和libd.a中定义的符号。如果我修改b.cc不使用libd.a中的符号,则链接成功,否则它会因未定义的引用错误而失败到libd.a中定义的符号。正确找到了libc.a中定义的符号。
libc.a是来自正在开发的应用程序的库,使用与相关共享库相同的设置进行编译。 libd.a是本地构建的boost iostreams库(其他也失败了)。如果我从libd.a中提取目标文件d.o并直接链接到它,则链接成功。使用从提取的d.o创建libc.a的相同选项创建存档再次失败。
arm -...- objdump --syms显示报告为undefined的符号确实存在。对于libd.a和提取的d.o,转储的符号信息是完全相同的。
使用-Wl, - 整个存档强制包含libd.a会导致链接成功。
我对linux上的共享库没有太多经验,但我怀疑涉及c ++可见性。 libc.a和libd.a(boost)都是在没有任何可见性标志的情况下编译的。我怀疑boost(1.55)在标题中做了一些事情,但我还没有能够追踪它。
我现在可以通过强制包含任何所需的静态库来解决这个问题,但我真的不明白发生了什么......任何人都可以解释一下吗?为什么链接器可以使用一个静态库来解析未定义的符号而不是另一个?
(这不是名称修改或不同架构的问题,因为我相信上面描述的ar实验证明了这一点。)
构建libd.a而不是libc.a时使用的有趣的命令行标志:
我正在继续尝试使用boost编译/链接标记,但周转时间很长,因为提升是......好吧,提升。
谢谢!
泰勒