Building for ARM 32-bit embedded
Bonsaipanda
jukka.korhonen at gmail.com
Fri Oct 11 21:02:04 UTC 2024
Hey guys, thought I'd throw some notes from testing out D for the
first time. I'm a complete n00b when it comes to cross-platform
buildchains and barely understand what crosslinking means and I
thought I'd just create a small hello world test app and try to
build it for amrhf to see if D would work for an app idea I have
had for quite a while.
Now, for comparison, same hello world test app (when running
Ubuntu 24.04) build using C is >>
```
arm-linux-gnueabihf-gcc test.c test_armhf
```
.. and out pops a 32-bit ARM executable.
So, in my head, I thought that there would be some kind of
shorthand like this >>
```
ldc2 -armhf test.d
```
.. and that would give me a standalone executable, ready to be
deployed on the ARM box and run.
The documentation says that you have to jump a bit through hoops
to get LLVM working if you're not building on the platform that
you're targeting, but the section in the documentation was almost
incomprehensible to me - not that I'm stupid, I'm just not
familiar with all that's required when linking stuff together,
never done anything like that, never heard of any of these
technologies before.
Apparently, if I want a static build (the target platform will
not have anything available, optimal end-result is a standalone
executable), I would need a pre-built armhf binary of the D
runtime and Phobos, but I didn't understand why would I need
those. When working with Vala, this was the thing that put me off
- no matter how I would build the executable, on the embedded
platform it would always nag about not finding all it's libraries
and I couldn't figure out a way to make stuff static (there is a
way, folks use it for embedded dev).
So I hopped on over to Raspberry Pi and made the test build
there. Out pops a test.o which I have no idea what to do with. I
know it's a 'shared object' but why would I want something like
this. Testing out different build options I managed to get an
executable out. Which then nags that it's in wrong format, it
doesn't understand what to do, it wants to run for president
etc., head scratching x 9000.
Diving into this forum, I found out that there's a problem with
the linker - it connects stuff in the wrong order.
So the final build command, after ~5 hours of headscrathing (and
trying ChatGPT to help out on understanding everything) is in the
form of >>
```
ldc2 -mtriple=armv6-linux-gnueabihf -c test.d &&
arm-linux-gnueabihf-gcc test.o
/usr/lib/arm-linux-gnueabihf/libphobos2-ldc.a
/usr/lib/arm-linux-gnueabihf/libdruntime-ldc.a -lm -lz -o
test_armhf
```
Yipe.
I mean, when you break it down, it's completely logical, but holy
skagsack minion, that's verbose and I have a feeling I'm doing
this completely wrong. Also, doing this on the Raspberry Pi is
super cumbersome and slow.
And I don't mean this post to be any sort of rant, I'm just
surprised on how the whole toolchain was so tricky to understand
and set up. Was really hoping for the shorthand of sorts that
would 'just work' on Ubuntu (or Windows), since LLVM itself is
pretty agnostic about the platforms, or so I've understood.
The D language itself seems to fit perfectly for the stuff I had
in mind, so I'm excited to dive deeper into it, but I have no
idea if I'm able to build more complex code (like drawing
directly into the framebuffer, some DSP stuff for ALSA).
More information about the digitalmars-d-ldc
mailing list