dlang / dub

Package and build management system for D
MIT License
674 stars 230 forks source link

Support for building libc-free project by providing "customLinkingCommand"? #1517

Open htfy96 opened 6 years ago

htfy96 commented 6 years ago

System information

Bug Description

As shown in the official example, libc-free programming requires a very different way to produce the binary.

How to reproduce?

N/A

Expected Behavior

Provide something like customLinkingCommand in buildSettings, which passes all libraries pending to link in environment variables

AntonMeep commented 6 years ago

I'd rather have special build mode for that. This way when building betterC apps dub could invoke linker only with libraries provided by the libs option (for your specific case "lflags": "-nostdlib" could disable linking to the libc) and when building standard non-betterC apps dub could pass -lpthread -lm -lrt -ldl -lgcc_s.

htfy96 commented 6 years ago

@ohdatboi It seems that "lflags": "-nostdlib" does not prohibits linking with libc:

➜  rasterizer-d-embed git:(master) ✗ cc -Xlinker -nostdlib a.c --verbose
...
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccuFvh0M.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/../../.. -nostdlib /tmp/ccc45kiq.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.1/../../../../lib/crtn.o

To disable linking with libc/startfiles we need to pass flags directly to cc. ldc will add -Xcc in the next version. dmd currently has no plan for this. Moreover, in both ldc and dmd, we cannot disable linking to librt/libm/libpthread by passing custom flags because they are explicitly passed to cc with hard-coded strings. I have opened a bug to mark -lm -lrt -lpthread with --as-needed so if we don't use them they won't be linked in.

Since there are still lots of work to do (as shown above) before using dmd/ldc as the linker, the only way that works now is calling cc directly. A special mode is also a feasible choice, but I think -lpthread -lm -lrt -ldl -lgcc_s should be done in the compiler instead of dub.

AntonMeep commented 6 years ago

@htfy96 I am not familiar with libc-free development, but you can use "lflags": ["--as-needed"] to disable linking to libm/librt/libpthread when they're not needed.

Also, are you compiling your code with "dflags": ["-betterC"]? If you don't then it's quite possible that your program gets linked to the druntime which depends on the libc.

htfy96 commented 6 years ago

@ohdatboi Hacking with "lflags": "["--as-needed"] works but looks too tricky:

-Xlinker --no-as-needed -Xlinker --as-needed -L/usr/lib -Xlinker --export-dynamic -lpthread -lm -lrt -ldl
                         ^ lflags here

This hack only resolves libpthread/libm/librt/libdl dependency, gcc_s and entry files are still linked in by gcc

Regarding the -betterC flag, I did compile my code with this flag, but even with it, dmd adds -lm -lrt -lpthread and cc adds -lgcc_s before passing them to ld