Thread overview
Is there any plan for a dependency-free subset of "core" runtime?
Jul 19, 2018
Zheng (Vic) Luo
Jul 19, 2018
Seb
Jul 19, 2018
Zheng (Vic) Luo
Jul 19, 2018
Seb
Jul 19, 2018
Radu
Jul 19, 2018
Seb
Jul 19, 2018
kinke
Jul 20, 2018
Radu
Jul 20, 2018
Seb
Jul 21, 2018
Seb
July 19, 2018
Current implementation of d-runtime relies on a lot of symbols from libc, librt, libpthread, which makes it hard to create a minimal runtime used for embedded devices. Although there are some unofficial minimal versions of d-runtime, many of them lack maintenance and outdates rapidly. I was wondering that is there any plan for a https://doc.rust-lang.org/core/ library in D world, which only depends several explicitly-defined symbols?
July 19, 2018
On Thursday, 19 July 2018 at 10:27:36 UTC, Zheng (Vic) Luo wrote:
> Current implementation of d-runtime relies on a lot of symbols from libc, librt, libpthread, which makes it hard to create a minimal runtime used for embedded devices. Although there are some unofficial minimal versions of d-runtime, many of them lack maintenance and outdates rapidly. I was wondering that is there any plan for a https://doc.rust-lang.org/core/ library in D world, which only depends several explicitly-defined symbols?

Well, since 2.079 it's actually possible to use D without a dependency any runtime (even libc):

https://dlang.org/changelog/2.079.0.html#minimal_runtime

Also with -betterC you can actually use lots of things from core that don't depend on the runtime. For example, std.algorithm/range works in betterC:

https://run.dlang.io/is/38yowj

Now, I assume you are asking whether there are plans for a minimal -betterC runtime?
There aren't "official" plans, but AFAICT a few people are independently working on this. It might be a good idea to join efforts with them.
July 19, 2018
On Thursday, 19 July 2018 at 11:35:00 UTC, Seb wrote:
>
> Well, since 2.079 it's actually possible to use D without a dependency any runtime (even libc):
>
> https://dlang.org/changelog/2.079.0.html#minimal_runtime
>
> Also with -betterC you can actually use lots of things from core that don't depend on the runtime. For example, std.algorithm/range works in betterC:
>
> https://run.dlang.io/is/38yowj
>
> Now, I assume you are asking whether there are plans for a minimal -betterC runtime?
> There aren't "official" plans, but AFAICT a few people are independently working on this. It might be a good idea to join efforts with them.

Thank you for the clarification. I am working on a libc-free project (SAOC project: 2D rasterizer on embedded devices) and just faced some missing symbols(__assert, _memset32) from various libraries in snippets like https://run.dlang.io/is/Kme62V (more missing symbols without C runtime). I am a little bit confused at the boundary of D components:

- which subset of standard library can be used under -betterC?
- even with -betterC, the compiler sometimes require external symbols like __assert to work, so what are all the required symbols? rust-core limits them to five: memcpy, memcmp, memset, rust_begin_panic and rust_eh_personality.

Is there any way to make this project remain as a "library" with a few explicit external symbol dependencies instead of bundling a minimal d-runtime/libc stubs? Since eliminating d-runtime looks like an overkill in the most of time (almost every embedded project defines their own size_t/string/bitop/attribute, hope to see a core subset of d-runtime to prevent reinventing the wheel.
July 19, 2018
On Thursday, 19 July 2018 at 11:35:00 UTC, Seb wrote:
> On Thursday, 19 July 2018 at 10:27:36 UTC, Zheng (Vic) Luo wrote:
>> Current implementation of d-runtime relies on a lot of symbols from libc, librt, libpthread, which makes it hard to create a minimal runtime used for embedded devices. Although there are some unofficial minimal versions of d-runtime, many of them lack maintenance and outdates rapidly. I was wondering that is there any plan for a https://doc.rust-lang.org/core/ library in D world, which only depends several explicitly-defined symbols?
>
> Well, since 2.079 it's actually possible to use D without a dependency any runtime (even libc):
>
> https://dlang.org/changelog/2.079.0.html#minimal_runtime
>
> Also with -betterC you can actually use lots of things from core that don't depend on the runtime. For example, std.algorithm/range works in betterC:
>
> https://run.dlang.io/is/38yowj
>
> Now, I assume you are asking whether there are plans for a minimal -betterC runtime?
> There aren't "official" plans, but AFAICT a few people are independently working on this. It might be a good idea to join efforts with them.

Just tried something similar with new LDC Webassembly support [1] and it fails to compile

---
int foo()
{
    import std.algorithm, std.range;
    auto r = 100.iota.stride(2).take(5);
    return r.sum();
}
---
ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC -link-internally -L-allow-undefined -release -Os wasm.d
ldc\bin\..\import\core\stdc\stdio.d(31): Error: module `core.stdc.stdint` import intptr_t not found
ldc\bin\..\import\core\stdc\stdio.d(1149): Error: undefined identifier FILE
....

This is a prime example of stuff that should just workTM on targets like that. I would like to submit some fixes but I think there needs to be a more systematic approach on making more core APIs modular.
Also, CI support to make sure core API compile on such targets and there are no regressions. Webassembly would be an excellent target as it is both constrained and portable.

1 - https://wiki.dlang.org/Generating_WebAssembly_with_LDC
July 19, 2018
On Thursday, 19 July 2018 at 12:40:09 UTC, Zheng (Vic) Luo wrote:
> On Thursday, 19 July 2018 at 11:35:00 UTC, Seb wrote:
>>
>> Well, since 2.079 it's actually possible to use D without a dependency any runtime (even libc):
>>
>> https://dlang.org/changelog/2.079.0.html#minimal_runtime
>>
>> Also with -betterC you can actually use lots of things from core that don't depend on the runtime. For example, std.algorithm/range works in betterC:
>>
>> https://run.dlang.io/is/38yowj
>>
>> Now, I assume you are asking whether there are plans for a minimal -betterC runtime?
>> There aren't "official" plans, but AFAICT a few people are independently working on this. It might be a good idea to join efforts with them.
>
> Thank you for the clarification. I am working on a libc-free project (SAOC project: 2D rasterizer on embedded devices) and just faced some missing symbols(__assert, _memset32) from various libraries in snippets like https://run.dlang.io/is/Kme62V (more missing symbols without C runtime). I am a little bit confused at the boundary of D components:
>
> - which subset of standard library can be used under -betterC?

Unfortunately, it's not properly defined (or tested) as -betterC is still WIP and there's also WIP to make the standard library more opt-in (e.g. the GC only starts when you actually use it since 2.080).
Anyhow, for -betterC there's a lot of all currently supported features:

https://dlang.org/spec/betterc.html

In terms of the standard library, everything that is either templated or a template will very likely work, e.g.

- std.algorithm (mostly)
- std.range (mostly)
- std.meta
- std.typecons

I actually have a PR in the works to add a -betterC testsuite to Phobos.

> - even with -betterC, the compiler sometimes require external symbols like __assert to work, so what are all the required symbols? rust-core limits them to five: memcpy, memcmp, memset, rust_begin_panic and rust_eh_personality.

assert is lowered to the C runtime assert with betterC.
With -betterC you should still have access to memcpy, just import core.stdc.string (see: https://dlang.org/library/core/stdc/string/memcpy.html).
If you don't use the C runtime which provides assert, memcpy etc. you need to define them yourself in the minimal runtime.
However, I think GDC/LDC provide intrinsics for a few of these operations.

See e.g. https://github.com/JinShil/stm32f42_discovery_demo/tree/master/source/runtime

> Is there any way to make this project remain as a "library" with a few explicit external symbol dependencies instead of bundling a minimal d-runtime/libc stubs? Since eliminating d-runtime looks like an overkill in the most of time (almost every embedded project defines their own size_t/string/bitop/attribute, hope to see a core subset of d-runtime to prevent reinventing the wheel.

Well, if you just use -betterC you still have access to all definitions in druntime (like size_t).
You just need to avoid linking with the C runtime when you absolutely want to avoid it (i.e. build the executable).

Here's a simple example of a D program for Linux x86_64 without any runtime that still accepts arguments , can do primitive output and uses declarations from druntime like size_t:

https://gist.github.com/wilzbach/1bb812b9bdd2fed693b0ee4a6f8a2fd8

tl;dr: the declarations in druntime are still usable - you simply can't call libc functions if you plan to build an executable from your library that should be runtime free.
July 19, 2018
On Thursday, 19 July 2018 at 12:44:30 UTC, Radu wrote:
> Just tried something similar with new LDC Webassembly support [1] and it fails to compile
>
> ...
>
> This is a prime example of stuff that should just workTM on targets like that. I would like to submit some fixes but I think there needs to be a more systematic approach on making more core APIs modular.
> Also, CI support to make sure core API compile on such targets and there are no regressions. Webassembly would be an excellent target as it is both constrained and portable.

To be fair, the WebAssembly support is still WIP and hasn't even been released yet ;-)
Anyhow, here's how I think we can move forward for now:

1) Open the issue you experienced in the ldc issue tracker
2) Add more tests for -betterC to the test suites (and thus CI)

For (2) I have an "old" PR staling around (https://github.com/dlang/phobos/pull/5952), which I should try to rebase and get into Phobos. Then it should be easier to add more -betterC tests for Phobos.
July 19, 2018
On Thursday, 19 July 2018 at 12:44:30 UTC, Radu wrote:
> ---
> int foo()
> {
>     import std.algorithm, std.range;
>     auto r = 100.iota.stride(2).take(5);
>     return r.sum();
> }
> ---
> ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC -link-internally -L-allow-undefined -release -Os wasm.d
> ldc\bin\..\import\core\stdc\stdio.d(31): Error: module `core.stdc.stdint` import intptr_t not found
> ldc\bin\..\import\core\stdc\stdio.d(1149): Error: undefined identifier FILE
> ....
>
> This is a prime example of stuff that should just workTM on targets like that. I would like to submit some fixes but I think there needs to be a more systematic approach on making more core APIs modular.

Removing some superfluous explicit druntime dependencies from Phobos would be a start. Your (nice) example compiles fine with this 4-lines Phobos hack:

---
diff --git a/std/ascii.d b/std/ascii.d
index 8622785b1..b3815cafd 100644
--- a/std/ascii.d
+++ b/std/ascii.d
@@ -105,10 +105,10 @@ enum LetterCase : bool
 /// Newline sequence for this system.
 version(Windows)
     immutable newline = "\r\n";
-else version(Posix)
+else// version(Posix)
     immutable newline = "\n";
-else
-    static assert(0, "Unsupported OS");
+//else
+//    static assert(0, "Unsupported OS");


 /++
diff --git a/std/typecons.d b/std/typecons.d
index 203ab05f4..49edebfaf 100644
--- a/std/typecons.d
+++ b/std/typecons.d
@@ -68,7 +68,8 @@ Authors:   $(HTTP erdani.org, Andrei Alexandrescu),
  */
 module std.typecons;

-import core.stdc.stdint : uintptr_t;
+//import core.stdc.stdint : uintptr_t;
+alias uintptr_t = size_t;
 import std.format : singleSpec, FormatSpec, formatValue;
 import std.meta; // : AliasSeq, allSatisfy;
 import std.range.primitives : isOutputRange;
---

Importing core.stdc.stdint for `uintptr_t` in std.typecons is particularly troublesome and totally unnecessary. It leads to importing (see -v output):

core.stdc.stdint
core.stdc.config
core.stdc.stddef
core.stdc.signal
core.stdc.wchar_
core.stdc.stdarg
core.stdc.stdio
core.stdc.time

whereas after the hack, it's only `core.stdc.stdarg`, and no core.stdc.* hacks for `version(WebAssembly)` are required to import std.algorithm and std.range.

[I'll open a PR for std.typecons.]
July 20, 2018
On Thursday, 19 July 2018 at 18:16:17 UTC, kinke wrote:
> On Thursday, 19 July 2018 at 12:44:30 UTC, Radu wrote:
>> [...]
>
> Removing some superfluous explicit druntime dependencies from Phobos would be a start. Your (nice) example compiles fine with this 4-lines Phobos hack:
>
> [...]

Was able to get it working with a bunch of hacks also.

See that you fixed in a more elegant way in the PR, nice!

I'll go with Seb's suggestion and look at the betterC tests upstream for issues like this.
July 20, 2018
On Friday, 20 July 2018 at 15:33:19 UTC, Radu wrote:
> On Thursday, 19 July 2018 at 18:16:17 UTC, kinke wrote:
> I'll go with Seb's suggestion and look at the betterC tests upstream for issues like this.

FYI: I made a reboot of the old PR to a new one which just adds the betterC testsuite:

https://github.com/dlang/phobos/pull/6640
July 21, 2018
On Friday, 20 July 2018 at 16:37:24 UTC, Seb wrote:
> On Friday, 20 July 2018 at 15:33:19 UTC, Radu wrote:
>> On Thursday, 19 July 2018 at 18:16:17 UTC, kinke wrote:
>> I'll go with Seb's suggestion and look at the betterC tests upstream for issues like this.
>
> FYI: I made a reboot of the old PR to a new one which just adds the betterC testsuite:
>
> https://github.com/dlang/phobos/pull/6640

You can now start to add your -betterC tests directly to Phobos: https://github.com/dlang/phobos/tree/master/test/betterC

make -f posix.mak betterC

We probably should support sth. like a `@test-betterc` (or @betterc-test`) UDA with which we can annotate existing tests that would then get extracted from Phobos automatically.