GNU链接器通过INPUT获取对象

问题描述:

我想使用第40页的GNU链接器手册中提出的建议,即INPUT(subr.o),从而在脚本文件中指定对象成员。 最后,我想指定链接器必须使用的程序的所有对象成员。GNU链接器通过INPUT获取对象

脚本文件看起来是这样的(只有文件的部分所示)

SEARCH_DIR(../lib) 

STARTUP(boot.o) 
ENTRY(_start) 

GROUP (libkernel.a libkflib.a) 

INPUT (
    lowcore.o 
    init.o 
    kfalloc.o 
    kflog.o 
    kfprintf.o 
) 

链接器与回复:

attempt to open boot.o failed 
attempt to open ../lib/boot.o failed 
m68k-rtems4.11-ld: cannot find boot.o 

我指定的搜索路径,库和列表对象成员;对象成员在库中是最初的。 我期待链接器在工作目录中查找对象成员,如果没有,则使用搜索路径和库。 很明显,有什么问题,但我无法弄清楚。

欢迎您提出建议,以实现所需的链接方式:指定所有链接的对象不超过。

感谢

你看错the manual

INPUT(file文件...)

INPUT命令指示链接器包括在指定的文件链接, 就好像它们是在命令行上命名的一样。

...

在情况a SYSROOT前缀配置,并且文件名与/字符, 和被处理物位于SYSROOT前缀内的脚本开始时,文件名 将寻找在sysroot前缀。否则,连接器将尝试在当前目录中打开文件 。如果找不到,链接器 将搜索存档库搜索路径。请参阅命令行选项中关于 -L的说明。

如果使用INPUT(-lfile),则ld将把名称转换为libfile.a,如 命令行参数-l所示。

...

GROUP(文件文件...)

group命令是INPUT相似,不同之处在于命名的文件都必须是 档案,它们将被重复搜索直到没有新的未定义参考文献 已创建。

STARTUP(文件名)

启动命令就像INPUT命令,除了文件名将 成为第一个输入文件被链接,就好像它是第一指定的命令行上

或者您可能已经阅读了一些错误的其他文档。

你有错该命令GROUP(libboo.a...)互补INPUT(foo.o...)STARTUP(bar.o),与文件bar.o, foo.o...将搜索的档案 libboo.a...和效果的印象 - 如果发现 - 从档案中提取并添加到连锁。

INPUT(foo.o)具有与接头上的 命令行指定foo.o除了同样的效果,如果它会以同样的方式被搜索 为与-l选项指定的静态库将当前目录没有找到,与任何SEARCH_DIR(path) 链接描述文件中的命令与命令行选项 -Lpath具有相同的影响。

STARTUP(bar.o)具有如图接头 命令行指定bar.o第一相同的效果。

GROUP(libboo.a...)具有与命令行选项

--start-group -lboo.a... --end-group 
再次用任何 SEARCH_DIR(path)命令actiing像 -Lpath

相同的效果。

INPUT(foo.o)STARTUP(bar.o)未连接与GROUP(libboo.a...),就像在命令行选项:

bar.o --start-group -lboo.a... --end-group foo.o 

bar.ofoo.o是输入文件与无关--start-group -lboo.a... --end-group

链接器从不在输入对象文件中查找静态库,否则它会找不到。

所以这个命令:

INPUT (
    lowcore.o 
    init.o 
    kfalloc.o 
    kflog.o 
    kfprintf.o 
) 
在你的链接脚本

要求链接器查找当前 目录或../lib这些目标文件,并且它们不存在。同样适用于STARTUP(boot.o)。因此 的联系错误。

这些目标文件不存在,但静态库libkernel.alibkflib.a, 你告诉我们,他们包含了所有的所有这些目标文件作为成员。在这种情况下 你根本不需要:

INPUT (
    lowcore.o 
    init.o 
    kfalloc.o 
    kflog.o 
    kfprintf.o 
) 

因为链接将搜索静态库找到目标文件 提供其定义的目标文件中呼吁 通过引用任何符号的定义,它已经联系了。你不必 告诉它。

而是让连接任何理由在你 搜索静态库必须告诉它链接是指一些不确定的符号(S) 它认为静态库之前的一些目标文件。

这就是为什么,在命令行,你必须在 库,它们所涉及前将目标文件的原因,这就是为什么在一个自包含的链接脚本,如果你 库添加到联动GROUP(libboo.a...)或与INPUT (-lboo...), 您还必须指定要链接的目标文件第一个,与STARTUP 命令。

因此而发生故障的INPUT命令是不必要的,可以只是 删除,发生故障的STARTUP(boot.o)必须保持,启动 任何联系。并且不能失败。

为了STARTUP(boot.o)成功,你必须把目标文件boot.o 本身在一个地方,该脚本将告诉链接来寻找它,要么 当前目录或../lib。据推测,当前目录。

而当你这样做时,将boot.o保留为其中一个静态库的成员 变得毫无意义,因为它不能从一个库中链接。最好的 将它从你拥有它的任何库文件中删除。离开它有类似的 将程序的main函数放入其中一个库中,您将 将它链接到一个库中。

+0

链接器的行为如所解释的那样并且因此如所指定的;现在我将在链接器脚本之外解决这个问题。就像在调用链接器之前使所有对象成员在工作目录中可用一样。 – BenJ

+0

@ BenJ嗨。这将是一个直接的方式。你可能想看看[当有人回答我的问题时该怎么办?](https://*.com/help/someone-answers) –