LD链接器创建共享之一,当去除静态库的目标文件 [英] ld linker removing an object file from a static library when creating a shared one

查看:177
本文介绍了LD链接器创建共享之一,当去除静态库的目标文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些我连接成一个共享库的静态库。其中一人,说libUsefulFunc.a包含函数的对象文件usefulFunc.o,即只从另一个静态库使用usefulFunc(),让我们说usingFunc(),居住在usingFunc.c在libUsingFunc.a托管

I have a number of static libraries which I link together into one shared library. One of them, say libUsefulFunc.a contains an object file usefulFunc.o with a function, usefulFunc() that is only used from another static library, let's say usingFunc(), residing in usingFunc.c hosted in libUsingFunc.a

问题是,连接器扔掉的usefulFunc.o,我得到错误未定义的参考。我试图连接的两个订单。

The problem is that the linker throws away the usefulFunc.o and I get error " undefined reference ". I tried both orders of linking.

我已经重新使用最简单的文件,我能想到的情况:

I've recreated the situation using the simplest files I could think of:

A.H

extern int foo();

交流转换器

#include "a.h"
int foo()
{
    return 13;
}

b.c

#include "a.h"

extern int b()
{
  return print("a = %d\n", foo());
}

大厦这一切:

gcc -c a.c -o a.o
gcc -c b.c -o b.o
ar q b.a b.o
ar q a.a a.o
ld -shared -o test.so ./b.a ./a.a
nm ./test.so 
00001034 A __bss_start
00001034 A _edata
00001034 A _end

如果我提供的目标文件,而不是档案:

If I provide the object files instead of archives:

ld -shared -o test.so ./a.o ./b.o
nm ./test.so 
00001220 a _DYNAMIC
00000000 a _GLOBAL_OFFSET_TABLE_
00001298 A __bss_start
00001298 A _edata
00001298 A _end
000001a0 T b
00000194 T foo
         U print

有没有办法告诉链接器不要扔掉,他认为目标文件未使用,而无需列出所有目标文件?我知道有一个--whole归档选项,但我建库的Andr​​oid NDK项目的一部分,并没有找到一种方法,通过此选项对特定库中的一个。

Is there a way to tell the linker not to throw away the object files he thinks are unused without having to list all object files? I know there is a --whole-archive option, but I build the library as a part of Android NDK project and did not find a way to pass this option for specific library one.

更新我完全理解我原来的问题,并找到正确的解决方案。首先我上面的例子:连接器从入口点和搜索他们所使用的所有符号开始。这些在当前库抬起头来。一旦发现,它增加了他们使用其名单等力的符号。该库只处理一次,并在它们出现在命令行上的顺序。因此,如果第二个库使用从第一个符号 - 符号将保持不确定,因为链接器不回去。所以在我的例子中,我要告诉他,B()将被外部调用,我可以通过使用--undefined = B做到这一点:

An update I've fully understood my original problem and found the correct solution. First to my example above: the linker starts from the entry points and searches for all symbols they use. These are looked up in the current library. Once found it adds the symbols they use to its list and so force. The libraries are processes only once and in the order they appear on the command line. So if the second library uses a symbol from the first one - the symbol will remain undefined, as the linker does not go back. So in my example I should have told him that b() will be called externally, I could do it by using --undefined=b:

ld -shared -o test.so --undefined=b ./b.a ./a.a

在原来的问题,我有两个静态库之间的循环引用。
就好像我在B存档曾与功能foo_b()是从foo称为文件b1.c()。对于这样的情况也有,我发现3种可能的解决方案:

In the original problem I had there was a circular reference between two static libraries. as if I had in the b archive a file b1.c with function foo_b() that is called from foo(). For such cases there are 3 possible solutions I have found:


  1. 两次上榜乙:LD -shared -o test.so --undefined = B ./b.a ./a.a
    ./b.a

  2. 使用--whole存档

  3. 使用--start-group和--end档案组
    选项​​。指定的存档会被重复搜索直到没有新
    未定义的引用被创建。

有关的Andr​​oid NDK库,只有第一和第二选择似乎是可用的,如NDK的生成文件不提供方法以指定存档组

For Android NDK libraries, only the first and the second options seem to be available, as NDK's makefiles don't provide a way to specify the archive group

希望这将是其他人也同样有用!

Hope this will be useful to other people as well!

推荐答案

尝试与--whole归档选项:

try with --whole-archive option:

ld -shared -o test.so --whole-archive ./a.a ./b.a

这篇关于LD链接器创建共享之一,当去除静态库的目标文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆