Thread overview
Create D portable binary
Dec 08, 2017
Fra Mecca
Dec 08, 2017
Adam D. Ruppe
Dec 08, 2017
Cym13
Dec 08, 2017
Jacob Carlborg
December 08, 2017
Is there a way to compile a project and deploying it as a single statically linked binary?

My main target would be something like a self contained jar (like .war files), but something that is in the style of go binaries and portable to another Linux distribution without any hassle would be enough.

From what I understand the main problem in achieving this is the dependency to curl (all the warnings related to gethostbyname during linking phase) and glibc that makes it hard to static link.

What if musl is used as libc?

Right now it seems that the only viable option is to distribute object files and make the end user link them
December 08, 2017
On Friday, 8 December 2017 at 05:16:22 UTC, Fra Mecca wrote:
> Is there a way to compile a project and deploying it as a single statically linked binary?

A default build of a D program is *reasonably* compatible. All its dependencies are core operating system components like libc. Now, there can certainly be libc version incompatibilities, but there's a decent chance it will just work.

I'm pretty sure this is the exact same situation Go is in; the default Go and D builds link the same way.


If you want to eliminate the potential C lib incompatibility too, you can do it basically the same way as in C, passing options to gcc with dmd's -L thing like `-L-static -L-nodefaultlib -L-lsome_alternate_clib`
December 08, 2017
On Friday, 8 December 2017 at 06:37:36 UTC, Adam D. Ruppe wrote:
> On Friday, 8 December 2017 at 05:16:22 UTC, Fra Mecca wrote:
>> Is there a way to compile a project and deploying it as a single statically linked binary?
>
> A default build of a D program is *reasonably* compatible. All its dependencies are core operating system components like libc. Now, there can certainly be libc version incompatibilities, but there's a decent chance it will just work.
>
> I'm pretty sure this is the exact same situation Go is in; the default Go and D builds link the same way.
>
>
> If you want to eliminate the potential C lib incompatibility too, you can do it basically the same way as in C, passing options to gcc with dmd's -L thing like `-L-static -L-nodefaultlib -L-lsome_alternate_clib`

On the same note, has https://wiki.dlang.org/DIP59 been dropped?
December 08, 2017
On Friday, 8 December 2017 at 06:37:36 UTC, Adam D. Ruppe wrote:
> On Friday, 8 December 2017 at 05:16:22 UTC, Fra Mecca wrote:
>> Is there a way to compile a project and deploying it as a single statically linked binary?
>
> A default build of a D program is *reasonably* compatible. All its dependencies are core operating system components like libc. Now, there can certainly be libc version incompatibilities, but there's a decent chance it will just work.
>
> I'm pretty sure this is the exact same situation Go is in; the default Go and D builds link the same way.


I was curious so I just tried. Building a hello world with "go build" (I just litterally did what was on https://gobyexample.com/hello-world) produces a file that is not a dynamic executable. There is no dependency.

For comparison building a similar hello world with dmd and no options gives the followig dependencies (thanks ldd):

        linux-vdso.so.1 (0x00007fffd02aa000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f45e5e69000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f45e5b1d000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007f45e5915000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f45e5711000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f45e54fa000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f45e5142000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f45e6087000)

(And using -L-static produces an error because of an incompatibility with -pie... I'm sure it's workable I just didn't take the time to look it up yet)
December 08, 2017
On 2017-12-08 06:16, Fra Mecca wrote:
> Is there a way to compile a project and deploying it as a single statically linked binary?
> 
> My main target would be something like a self contained jar (like .war files), but something that is in the style of go binaries and portable to another Linux distribution without any hassle would be enough.
> 
>  From what I understand the main problem in achieving this is the dependency to curl (all the warnings related to gethostbyname during linking phase) and glibc that makes it hard to static link.
> 
> What if musl is used as libc?

Currently the musl library cannot be used because the runtime relies on some GNU extension to standard libc.

> Right now it seems that the only viable option is to distribute object files and make the end user link them

You can statically link a D binary using the -static flag and LDC, if you don't rely on any of the functions that the linker warns about, like gethostbyname. DMD cannot be used because of its TLS implementation.

For example, this project I've created is 100% statically linked on Linux. You can have a look in the Dub configuration [2].

If you need some resource files you can have a look at the Import Expression [3] as well.

[1] https://github.com/jacob-carlborg/remarkify
[2] https://github.com/jacob-carlborg/remarkify/blob/master/dub.sdl#L7
[3] https://dlang.org/spec/expression.html#import_expressions

-- 
/Jacob Carlborg