Thread overview
Embedded Systems (STM32) LDC Absolute minimal runtime
Jun 19, 2017
Dan Walmsley
Jun 20, 2017
Mike
Jun 20, 2017
Kagamin
Apr 05, 2018
Cora Dias
Apr 06, 2018
Mike Franklin
June 19, 2017
Hi guys,

   I run an open source project developing a modern cross platform IDE for embedded systems, https://github.com/VitalElement/avalonStudio (perhaps the IDE could complement D as I have not found many just works out the box solutions for D yet.)

   I have begun to integrate the LDC compiler and would also like to attempt to use D in an upcoming embedded project I have.

I have played around with the betterC flag and it looks promising. I would also like to have use of classes, however as soon as I try to use a class I get many link errors. see below:

The  undefined reference to `_d_dso_registry' comes from removing the -betterC flag.

I understand these other symbols would be provided by object.d, however I am unable to find an object.d that will compile on LDC, and ideally a minimal implementation.

Can anyone help?


C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o: In function `_D4main9TestClass3SumMFZi':
C:\dev\repos\STM32DBlinky\Blinky/main.d:9: undefined reference to `_D9invariant12_d_invariantFC6ObjectZv'
C:\dev\repos\STM32DBlinky\Blinky/main.d:9: undefined reference to `_d_assert_msg'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o: In function `ldc.register_dso':
C:\dev\repos\STM32DBlinky\Blinky\main.d:(.text.ldc.register_dso+0x60): undefined reference to `_d_dso_registry'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x4): undefined reference to `_D6object6Object8toStringMFZAya'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x8): undefined reference to `_D6object6Object6toHashMFNbNeZk'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0xc): undefined reference to `_D6object6Object5opCmpMFC6ObjectZi'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x10): undefined reference to `_D6object6Object8opEqualsMFC6ObjectZb'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data._D4main9TestClass7__ClassZ[_D4main9TestClass7__ClassZ]+0x0): undefined reference to `_D14TypeInfo_Class6__vtblZ'
C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data._D4main9TestClass7__ClassZ[_D4main9TestClass7__ClassZ]+0x28): undefined reference to `_D6Object7__ClassZ'

June 20, 2017
On Monday, 19 June 2017 at 10:24:29 UTC, Dan Walmsley wrote:

> I have played around with the betterC flag and it looks promising. I would also like to have use of classes, however as soon as I try to use a class I get many link errors. see below:

It is my understanding that the DMD -betterC switch currently only disables generating ModuleInfo.  Walter's recent pull request (http://forum.dlang.org/post/oi9v2q$23ms$1@digitalmars.com) makes it do a little more.

It is also my understanding the -betterC is just an idea at the moment, and what it should do has not yet been defined.

>
> The  undefined reference to `_d_dso_registry' comes from removing the -betterC flag.
>
> I understand these other symbols would be provided by object.d, however I am unable to find an object.d that will compile on LDC, and ideally a minimal implementation.

The most minimal implementation I'm aware of is this: https://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22

If you're targeting STM32, you may also be interested in this: https://github.com/JinShil/stm32f42_discovery_demo

I haven't tested either of those in quite some time, so I doubt the will compile out of the box.  But basically, what you need is a minimal runtime implementation that implements the features of D that your code is using, and unfortunately, some that your code isn't using but is required by the compiler just to get a build.

> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o: In function `_D4main9TestClass3SumMFZi':
> C:\dev\repos\STM32DBlinky\Blinky/main.d:9: undefined reference to `_D9invariant12_d_invariantFC6ObjectZv'
> C:\dev\repos\STM32DBlinky\Blinky/main.d:9: undefined reference to `_d_assert_msg'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o: In function `ldc.register_dso':
> C:\dev\repos\STM32DBlinky\Blinky\main.d:(.text.ldc.register_dso+0x60): undefined reference to `_d_dso_registry'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x4): undefined reference to `_D6object6Object8toStringMFZAya'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x8): undefined reference to `_D6object6Object6toHashMFNbNeZk'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0xc): undefined reference to `_D6object6Object5opCmpMFC6ObjectZi'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data.rel.ro._D4main9TestClass6__vtblZ[_D4main9TestClass6__vtblZ]+0x10): undefined reference to `_D6object6Object8opEqualsMFC6ObjectZb'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data._D4main9TestClass7__ClassZ[_D4main9TestClass7__ClassZ]+0x0): undefined reference to `_D14TypeInfo_Class6__vtblZ'
> C:\dev\repos\STM32DBlinky\Blinky\build\obj\main.o:(.data._D4main9TestClass7__ClassZ[_D4main9TestClass7__ClassZ]+0x28): undefined reference to `_D6Object7__ClassZ'

`_d_assert_msg` and `_d_dso_registry` and those symbols with `_d_invariant` in them look like missing druntime implementations.  You can see an old and unmaintained list of such "runtime hooks" here: https://wiki.dlang.org/Runtime_Hooks.  Each compiler (DMD, LDC, and GDC) have their own druntime implementation, unfortunately.  LDC's implementation is here: https://github.com/ldc-developers/druntime

I suspect the `.data.re.ro.*` symbols are the result of an error in your linker script.  That is you haven't added that `.data` section to your linker script, so the symbols aren't being populated.  I'd have to see your linker script and source code before I spend to much mental energy on it, though.

No compiler that I'm aware has a druntime implementation for the ARM Cortex-M architecture, so the onus is on you to build implement whatever features the toolchain is complaining about.

Mike
June 20, 2017
I believe you can do without any runtime at all, but it's a tradeoff, see also https://forum.dlang.org/post/tmofjecvnqdthvetezfp@forum.dlang.org
April 05, 2018
Hi...i am a new user here. As per my observation as suggested above you need a minimal runtime implementation that implements the features of D that your code is using, some that your code is not using but is required by the compiler just to get a build.
April 06, 2018
On Thursday, 5 April 2018 at 15:58:28 UTC, Cora Dias wrote:
> Hi...i am a new user here.

Welcome!

> As per my observation as suggested above you need a minimal runtime implementation that implements the features of D that your code is using, some that your code is not using but is required by the compiler just to get a build.

Yeah, so D can be both a systems programming language and an applications programming language, and it's even convenient enough to use a scripting language :-)  But that means that it has both high level and low level features.

If you want to do bare-metal programming on the STM32 (or any resource-constrained micrcontroller), you may not want or need things like the garbage collector, runtime type information, etc. (though with something like the STM32F7, it may be the right choice). To do the low-level stuff, you just need the fundamental compiler facilities, and not much, if anything, from the runtime.  So, you have a few options:

1) The -betterC switch - This switch allows you to use D like C.  No classes, No runtime-type information, no exceptions, but you still get the compiler facilities like templates, mixins, etc. that aren't found in C.  Thus it is a "better C".  See https://dlang.org/spec/betterc.html and https://dlang.org/blog/category/betterc/ for lots of information about that.

I am, personally, not a fan of betterC, and affectionately call it worseD.  IMO, if the compiler would just be fixed to reduce coupling to the runtime (as was done recently in 2.079.0) betterC would not be needed.

2) A v2.079.0 compliant compiler - 2.079.0 did some long overdue decoupling of the compiler from the runtime so you no longer get compiler errors for missing features that your code doesn't even make use of.  See https://dlang.org/changelog/2.079.0.html#minimal_runtime for more information about that.

3) A pre-2.079.0 version of a compiler with useless stubs to get the compiler to shut up and generate your binary.  Trying to make a minimal runtime with the current LDC release is fraught with problems: (1) https://github.com/ldc-developers/ldc/issues/781 (2) https://github.com/ldc-developers/ldc/issues/552  GDC is much better, but still requires a few useless stubs to get a build (e.g. https://github.com/JinShil/stm32f42_discovery_demo/blob/master/source/runtime/object.d)

LDC is currently working on adding the 2.079.0 features:  https://github.com/ldc-developers/ldc/pull/2641  I hope it will be in the next LDC release.  When that's done it will be a much better competitor with GDC (and may even surpass it) when it comes to ARM Cortex-M programming in D.  I'm currently trying to find a way to contribute to GDC to accelerate its progress, but I have a lot to learn.

A few resource which you may find interesting:
https://bitbucket.org/timosi/minlibd - probably the most complete port of the D runtime to the ARM Cortex-M platform.  I think it's only compatible with GDC at the moment though.

https://github.com/JinShil/stm32f42_discovery_demo - A proof of concept illustrating the bare-metal programming ARM Cortex-M microcontrollers without the need for -betterC, opting for minimal runtime instead, is feasible.

https://forum.dlang.org/post/qjowkuwstewnmdunepiq@forum.dlang.org, https://theartofmachinery.com/2018/04/02/inheritance_and_polymorphism.html - A very cool way of using D's mixin features to simulate classes without the D runtime.

I hope that will give you some of what you were looking for.

Mike