Skip to content

Add -dnostdlib to simplify the use of DLang without stdlib#10180

Closed
ghost wants to merge 1 commit intomasterfrom
unknown repository
Closed

Add -dnostdlib to simplify the use of DLang without stdlib#10180
ghost wants to merge 1 commit intomasterfrom
unknown repository

Conversation

@ghost
Copy link
Copy Markdown

@ghost ghost commented Jul 15, 2019

This PR was created to provide an easier alternative to accept than #7825 and #9814

This PR has been divided into 5 parts to make it easier to analyze each change and not to accept all the changes

With this initial PR you begin to define the new flag: "-dnostdlib" which will allow developers to use the DLang compiler without any dependency on various runtime (both DRuntime and Libc) without having to use boring methods like generating object files and linking them manually (this is done for example here https://github.com/JinShil/utiliD/blob/91b9048cac92e8341816cd2bc78fdc066f5ad5cc/test/HelloWorld/run.d#L17)

With this PR, unlike previous attempts, no code/script currently in use will be broken, just a new flag will be added for users interested in using DLang without any standard library.

The "-dnostdlib" flag should do the following:

  • Disable the generation of the entry point C main
    immutable cmaincode =
  • Prevent implicit linking with default libraries hardcoded in dmd/link.d
    argv.push("-lpthread");
  • Prevent the use of the library specified in -defaultlib
  • Add to the linker flags "-nostdlib -nodefaultlibs -nostartfiles" to prevent the linking of standard C libraries
  • Do not implicitly import the object module
    auto im = new Import(Loc.initial, null, Id.object, null, 0);

After this PR it will be possible to compile with DMD a source code like this just adding -dnostdlib (so with a way like C compilers):

private extern(C) void __d_sys_exit(long arg1)
{
    asm
    {
        mov RAX, 60;
        mov RDI, arg1;
        syscall;
    }
}

private long __d_sys_write(long arg1, in void* arg2, long arg3)
{
    long result;

    asm
    {
        mov RAX, 1;
        mov RDI, arg1;
        mov RSI, arg2;
        mov RDX, arg3;
        syscall;
    }

    return result;
}

void write(string text)
{
    __d_sys_write(2, text.ptr, text.length);
}

private extern(C) void _start()
{
    main();
    __d_sys_exit(0);
}

void main()
{
    write("Hello, World!\n");
}

@dlang-bot
Copy link
Copy Markdown
Contributor

Thanks for your pull request and interest in making D better, @ErnyTech! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + dmd#10180"

@ghost
Copy link
Copy Markdown
Author

ghost commented Jul 15, 2019

Link to other PR:
#10181
#10182
#10183
#10184

@thewilsonator
Copy link
Copy Markdown
Contributor

cc @JinShil @marler8997

@Geod24
Copy link
Copy Markdown
Member

Geod24 commented Jul 16, 2019

How does it compare to -betterC ?

@ghost
Copy link
Copy Markdown
Author

ghost commented Jul 16, 2019

-betterC links the libc and import object.d, while -dnostdlib was born to be used without any stdlib (druntime, phobos and libc)

@WalterBright
Copy link
Copy Markdown
Member

I don't understand. Just don't call your main function main(), as it is main() that triggers the other stuff.

@marler8997
Copy link
Copy Markdown
Contributor

marler8997 commented Jul 16, 2019

Already have a PR for this: #9831

It turns out we don't need an new option, using -defaultlib= will suffice. The only thing holding it back is that there's still some linker errors when running the druntime tests.

@JinShil
Copy link
Copy Markdown
Contributor

JinShil commented Jul 17, 2019

It turns out we don't need an new option, using -defaultlib= will suffice.

If you examine the other PRs (#10181, #10182, #10183, #10184), you will see that there is more to it than just linking the default platform libraries. This PR will introduce a compiler switch that will also disable implicitly importing object.d and generation of the startup code (__entrypoint, C main, etc.)

I don't understand. Just don't call your main function main(), as it is main() that triggers the other stuff.

That's only true for the startup code (__entrypoint, C main, etc.). As mentioned above the goal with the new compiler switch proposed in this PR is to do more (e.g. preventing linking of default platform libs, and prevent implicitly importing object.d).


I've given this PR some thought, but the approach proposed here is not my preference.

I'm interested in making D more pay-as-you-go, but the spirit of the pay-as-you-go mantra is that everything is turned OFF by default and you only turn ON what you need. The approach taken with this PR is to turn things OFF. That's not a deal-breaker, but it's a warning flag that something's not right.

I have an alternate proposal which I believe will be more generally useful for all, more in the spirit of "pay-as-you-go", and will reduce much hard-coded complexity in the compiler. I propose utilizing dmd.conf as the place where default compiler behavior is encoded. That includes import directories, implicitly imported modules, library search directories, and default linked libraries. That way all the hard-coded logic in link.d and elsewhere can be delegated to the compiler/toolchain configuration. It can be fully customized for a given platform (as is already done) without having to make any changes to the compiler, complicating the compiler with a lot of platform detection logic, or versioning the compiler.

Those who are using D for bare-metal, new platforms, or other pioneering use cases that don't wish to utilize the compiler's defaults can simply invoke the compiler with dmd -conf= or create a new dmd.conf file with their default configuration suitable to their target platform or use case.

I believe that will be more scalable, will reduce complexitiy in the compiler, and will be more generally useful for all.

@marler8997
Copy link
Copy Markdown
Contributor

@JinShil I already started work on your proposal but we are waiting on @WalterBright to respond #9936 (comment)

[WIP] [NeedsAcceptOrRejectFromWalter] Move standard library config to dmd.conf
#9944

[WIP] [NeedsAcceptOrRejectFromWalter] Remove hardcoded phobos info from the compiler
#9936

@ghost ghost closed this Aug 29, 2019
@ghost ghost deleted the dnostdlib-flag branch August 29, 2019 15:30
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants