Arm binutils/ld的自定义编译不';在档案中找不到符号

Arm binutils/ld的自定义编译不';在档案中找不到符号,arm,clang,ld,binutils,Arm,Clang,Ld,Binutils,我目前正试图为裸机aarch64目标编译Clang/LLVM。编译Clang非常简单——事实上,我编译Clang是为了针对多种体系结构,包括arm和aarch64。对于后端,我使用binutils。由于binutils只能针对一种体系结构,我已经构建了aarch64和arm版本。这座建筑似乎也很简单。我使用以下方法为aarch64构建了binutils: mkdir build cd build ../configure --target=aarch64-none-elf make 来自bin

我目前正试图为裸机aarch64目标编译Clang/LLVM。编译Clang非常简单——事实上,我编译Clang是为了针对多种体系结构,包括arm和aarch64。对于后端,我使用binutils。由于binutils只能针对一种体系结构,我已经构建了aarch64和arm版本。这座建筑似乎也很简单。我使用以下方法为aarch64构建了binutils:

mkdir build
cd build
../configure --target=aarch64-none-elf
make
来自binutils 2.24的未打包源程序包

我遇到的问题是,我无法让我的自定义ld版本正确处理归档文件。它似乎可以毫无问题地查找和打开归档文件,但在编译最终二进制文件时无法搜索未定义的符号。下面通过一个示例介绍一些更具体的细节:

通过编译创建简单的main.s文件:

int foo();
int main() { return foo(); } 
int foo() { return 0; }
使用Clang并使用--target=aarch64-S,即发出特定于体系结构的程序集文件

通过编译来创建foo.s,请执行相同的操作:

int foo();
int main() { return foo(); } 
int foo() { return 0; }
使用来自binutils的自定义gas构建将两个.s文件组装为.o文件

通过使用ar-cr-foo.a foo.s和ranlib-libfoo.a从binutils运行自定义的ar和ranlib构建来创建归档libfoo.a

尝试使用ld-L-lfoo-omain.elf main.o将这两个文件链接在一起

输出显示对foo的未定义引用

bar.cpp:(.text+0x14): undefined reference to `foo()'
我可以在foo.a上运行readelf,而且它的格式似乎非常好。特别是我可以看到foo的公共符号。如果我用--verbose运行ld,那么我就明白了

attempt to open ./libfoo.a succeeded
但没有迹象表明它找到了任何符号

如果我直接链接到对象文件,即使用ld-o main.elf foo.o main.o,那么我会得到一个格式良好的elf文件。此外,如果我从libfoo.a中提取foo.o,那么我还可以成功地与提取的foo.o链接

有人知道为什么会这样吗?我非常确定我的clang构建是正常的,因为发出的程序集文件有效地将问题与clang解耦。我猜汇编的.o文件也可以。所以这只剩下ar/ranlib或ld是罪魁祸首

为了消除ar/ranlib作为罪魁祸首,我为arm重建了binutils(步骤相同,但使用--target=arm none-eabi)。如果我将构建的ar/ranlib二进制文件集成到已知良好的arm eabi none GCC工具链中,那么它们似乎可以正常工作。因此,我的怀疑指向劳工处。请注意,如果我将我的clangbuild与binutils的arm构建结合使用,那么main/foo示例会遇到与上面相同的问题

我还尝试将ld的arm版本集成到现有良好的GCC工具链中,但得到了:

this linker was not configured to use sysroots
我需要弄清楚。现在这对我来说还是有点神秘。它阻止我检查手臂的ld构造

很可能我做了一些明显错误的事情,但现在我看不出来

注:

  • 我不得不修改binutils的make脚本来添加几个-Wno-xxx标志。我需要以“正确”的方式进行操作,但我不认为这种攻击会影响输出

  • 我正在OSX 10.9.4 64位上构建/托管所有工具

更新:

关于sysroot的错误很简单。预先存在的工具链配置了以下标志:

--with-prefix $SOME_INSTALL_DIR
--with-sysroot $SOME_INSTALL_DIR/arm-none-eabi

如果我用这些重新构建,那么我可以毫无问题地插入我的ld版本,并且它可以正常工作。想到这可能是我的错误,我很激动。以前我没有运行makeinstall,因为在这个阶段我并不真正关心安装。我认为我的新ld版本可能以某种方式引用了OSX系统libs/exes(尽管我不确定它究竟可以引用什么,除了ar,即它是否运行ar来处理归档)。然而,即使这样配置,arm和arrach64版本的binutils仍然存在同样的问题。

看起来我对这个问题考虑得太多了,还遗漏了一些我从未意识到的关于ld的东西。问题在于线路:

 ld -L. -lfoo -o main.elf main.o
我没有意识到ld对对象文件/库顺序很敏感。对foo()的未定义引用位于main.o中。在解析main.o之前,我将libfoo.a库指定为输入。这意味着链接器不必在libfoo.a中搜索符号,因为它已经处理了这个库。main.o必须在之前指定,例如

ld -L. main.o -lfoo -o main.elf
甚至用--start组包装-lfoo--终端组无法解决此问题

我仍然对此感到有些惊讶。我还没有说服自己这是ld的一个好特性。似乎我现在能想到的唯一用例就是偷偷地允许重复符号

该喝杯茶了