compiler-constructionllvmdavrldc

How does AVR support with LLVM work for different languages?


Apologies in advance since I am not too knowledgeable on the topic yet and still in the process of learning about the inner workings of compilers.

I am currently investigating the possibility of using D in embedded systems and found an article mentioning how the AVR backend has been merged into the upstream LLVM Project, so developers can work on creating AVR support for their languages. D has the LDC compiler, which uses the LLVM backend. The article also mentions the use of the avr-gcc though, which leaves me a bit confused about which tools are used at which stage to go from D-sourcecode to an AVR binary. I would have assumed LDC converts the sourcecode to LLVM IR and then to binary, so I'm not sure what the avr-gcc is used for.

Can anyone explain this to me in more details perhaps?


Solution

  • There's two options to link the compiled object files that ldc spits out: with avr-gcc's linker, or with llvm's internal linker. The argument -gcc=avr-gcc tells it where to find avr-gcc tools, or you can use --link-internally instead, which uses llvm's built-in linker. Both will work.

    The nice thing about using the -gcc thing is you can point it at your arduino studio install - which you probably want anyway since it has the objcopy, avrdude, etc. programs as well as other useful things - and have it just work, and integrate better with other libraries and tools and such, like the C runtime that gcc provides.

    $ 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
    

    With the arduino tools in the PATH, the -gcc=avr-gcc argument just works.

    With --link-internally, you don't need any of that, but:

    $ 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
    

    Notice it linked, but it gave a warning about the missing _start. Also notice the different file size. This is because the C runtime stubs that gcc provides has that start symbol, which does some basic setup then calls your extern(C) main. Without that, you will need to do a little more yourself. I'm sure you can get ldc to link in that too by listing the lib/object files in the link command... but with -avr-gcc, it just works since it already knows where to find all that stuff.