提前道歉,因为我对这个主题还不太了解,而且还在学习编译器的内部工作原理。
我目前正在研究在嵌入式系统中使用D的可能性,并发现一篇文章提到AVR后端是如何合并到上游LLVM项目中的,这样开发人员就可以为他们的语言创建AVR支持。D有LDC编译器,它使用LLVM后端。不过,这篇文章还提到了avr-gcc的使用,这让我有点困惑,在从D源代码到avr二进制代码的哪个阶段使用了哪些工具。我假设LDC将源代码转换为LLVM IR,然后再转换为二进制,所以我不确定avr gcc的用途。
有人能更详细地向我解释一下吗?
有两个选项可以链接ldc吐出的已编译对象文件:使用avr-gcc的链接器,或者使用llvm的内部链接器。参数-gcc=avr-gcc
告诉它在哪里可以找到avr-gcc工具,或者您可以使用--link-internally
,它使用llvm的内置链接器。两者都会起作用。
使用-gcc
的好处是,你可以把它指向你的arduino studio安装——你可能无论如何都想要它,因为它有objcopy、avrdude等程序以及其他有用的东西——让它正常工作,并更好地与其他库和工具集成,比如gcc提供的C运行时。
$ PATH=/opt/arduino/arduino-1.8.10/hardware/tools/avr/bin:$PATH ldc2 -betterC -Oz -mtriple=avr -mcpu=atmega328p -gcc=avr-gcc delay.d
$ file delay
delay: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, with debug_info, not stripped
$ ls -l delay
-rwxr-xr-x 1 me users 2440 Sep 18 08:28 delay
有了PATH中的arduino工具,-gcc=avr-gcc参数就可以工作了。
使用内部的--link,您不需要任何这些,但是:
$ ldc2 -betterC -Oz -mtriple=avr -mcpu=atmega328p --link-internally delay.d
lld: warning: cannot find entry symbol _start; defaulting to 0x110B4
$ file delay
delay: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped
$ ls -l delay
-rwxr-xr-x 1 me users 708 Sep 18 08:31 delay
请注意,它链接了,但它发出了关于缺少_start
的警告。还要注意不同的文件大小。这是因为gcc提供的C运行时存根有一个开始符号,它进行一些基本设置,然后调用extern(C) main
。如果没有这些,你将需要自己做更多的事情。我相信你也可以通过在link命令中列出lib/object文件来让ldc链接进来。。。但是有了-avr-gcc,它就可以工作了,因为它已经知道在哪里可以找到所有这些东西。