www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Build fully static library by the compiler?

reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
We can build static library directly from the compiler:

$ ldc2 --lib app.d

produces app.a file with app.o inside of it.

Are there simple way to make a static library that also includes 
necessary standard D libraries (i.e., phobos2 and druntime)?

Compiler already knows (?) paths to default static libs because 
it have --static option which produces static executable with all 
necessary libs inside. (Although I'm not sure that it works by 
this way)

Point is that D can be not a main language of the project and it 
is unconvient to extract by somehow paths to phobos and druntime 
at last stages of project build.
Aug 08
next sibling parent reply Alex Bryan <abryancs gmail.com> writes:
On Friday, 9 August 2024 at 02:34:03 UTC, Denis Feklushkin wrote:
 We can build static library directly from the compiler:

 $ ldc2 --lib app.d

 produces app.a file with app.o inside of it.

 Are there simple way to make a static library that also 
 includes necessary standard D libraries (i.e., phobos2 and 
 druntime)?

 Compiler already knows (?) paths to default static libs because 
 it have --static option which produces static executable with 
 all necessary libs inside. (Although I'm not sure that it works 
 by this way)

 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
ldc2 has the --static option, though, looking from ldc2 --help I'm not 100% sure exactly what that does. If that doesn't work we cat get a little creative: $ cat hello.d import std.stdio; void main() { writeln("hello, world!"); } $ gcc hello.o /usr/lib/x86_64-linux-gnu/libphobos2-ldc.a /usr/lib/x86_64-linux-gnu/libdruntime-ldc.a -lm -lz -o hello $ ./hello hello, world! $
Aug 09
next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Friday, 9 August 2024 at 22:32:21 UTC, Alex Bryan wrote:
 On Friday, 9 August 2024 at 02:34:03 UTC, Denis Feklushkin 
 wrote:
 We can build static library directly from the compiler:

 $ ldc2 --lib app.d

 produces app.a file with app.o inside of it.

 Are there simple way to make a static library that also 
 includes necessary standard D libraries (i.e., phobos2 and 
 druntime)?

 Compiler already knows (?) paths to default static libs 
 because it have --static option which produces static 
 executable with all necessary libs inside. (Although I'm not 
 sure that it works by this way)

 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
ldc2 has the --static option, though, looking from ldc2 --help I'm not 100% sure exactly what that does. If that doesn't work we cat get a little creative: $ cat hello.d import std.stdio; void main() { writeln("hello, world!"); } $ gcc hello.o /usr/lib/x86_64-linux-gnu/libphobos2-ldc.a /usr/lib/x86_64-linux-gnu/libdruntime-ldc.a -lm -lz -o hello $ ./hello hello, world! $
I had a similar issue, it almost made me drop D https://forum.dlang.org/thread/yguvdwlqtyvmjrdsjkzo forum.dlang.org Whoever working on that kind of things needs to get this sorted ASAP In other languages it is as easy as passing one argument In D? it's yet again an obfuscated bloat
Aug 09
prev sibling parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Friday, 9 August 2024 at 22:32:21 UTC, Alex Bryan wrote:

 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
ldc2 has the --static option, though, looking from ldc2 --help I'm not 100% sure exactly what that does.
--static means executable creation, not a static library
Aug 10
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Saturday, 10 August 2024 at 08:07:14 UTC, Denis Feklushkin 
wrote:
 On Friday, 9 August 2024 at 22:32:21 UTC, Alex Bryan wrote:

 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
ldc2 has the --static option, though, looking from ldc2 --help I'm not 100% sure exactly what that does.
--static means executable creation, not a static library
If i remember correctly, you have to pass `--link-defaultlib-shared=false`
Aug 11
parent Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 11 August 2024 at 08:30:05 UTC, ryuukk_ wrote:

 ldc2 has the --static option, though, looking from ldc2 
 --help I'm not 100% sure exactly what that does.
--static means executable creation, not a static library
If i remember correctly, you have to pass `--link-defaultlib-shared=false`
No, I checked - it didn't work
Aug 11
prev sibling parent reply kinke <noone nowhere.com> writes:
On Friday, 9 August 2024 at 02:34:03 UTC, Denis Feklushkin wrote:
 Are there simple way to make a static library that also 
 includes necessary standard D libraries (i.e., phobos2 and 
 druntime)?
Nope, you'd have to specify the path to the libs explicitly in the cmdline to merge them into the created static lib/archive, e.g., `ldc2 -lib bla.d $(dirname $(dirname $(which ldc2)))/lib/lib{druntime,phobos2}-ldc.a`.
 Compiler already knows (?) paths to default static libs because 
 it have --static option which produces static executable with 
 all necessary libs inside. (Although I'm not sure that it works 
 by this way)
Not really; the `-defaultlib` libraries need to be in one of the `lib-dirs` in ldc2.conf, it's the linker that resolves them.
 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
Would using the D compiler as linker driver be an option? Similar to how people can avoid explicitly linking GNU's libstdc++ / LLVM's libc++ by using `c++` instead of `cc` as linker driver, thereby not having to know which implementation of the C++ std library to choose for the particular platform.
Aug 11
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 11 August 2024 at 10:18:56 UTC, kinke wrote:
 On Friday, 9 August 2024 at 02:34:03 UTC, Denis Feklushkin 
 wrote:
 Are there simple way to make a static library that also 
 includes necessary standard D libraries (i.e., phobos2 and 
 druntime)?
Nope, you'd have to specify the path to the libs explicitly in the cmdline to merge them into the created static lib/archive, e.g., `ldc2 -lib bla.d $(dirname $(dirname $(which ldc2)))/lib/lib{druntime,phobos2}-ldc.a`.
Even if I use my custom ldc2.conf? I can specify necessary options in it
 Compiler already knows (?) paths to default static libs 
 because it have --static option which produces static 
 executable with all necessary libs inside. (Although I'm not 
 sure that it works by this way)
Not really; the `-defaultlib` libraries need to be in one of the `lib-dirs` in ldc2.conf, it's the linker that resolves them.
That's exactly what I meant in this case
 Point is that D can be not a main language of the project and 
 it is unconvient to extract by somehow paths to phobos and 
 druntime at last stages of project build.
Would using the D compiler as linker driver be an option?
For whole project code (it is ESP IDF) it is impossible, as for me, because C linker is nearly "hardcoded" into it. I use ldc2 as compiler for my D code and would to use ldc2 for linking this code with D standard libraries.
 Similar to how people can avoid explicitly linking GNU's 
 libstdc++ / LLVM's libc++ by using `c++` instead of `cc` as 
 linker driver, thereby not having to know which implementation 
 of the C++ std library to choose for the particular platform.
Maybe in D case it will be right choice to respect --defaultlib= setting during static linking? So if anyone wants to link static library without stdlibs then just can leave it empty. In other cases druntime and phobos will be linked into static library?
Aug 11
parent reply kinke <noone nowhere.com> writes:
On Sunday, 11 August 2024 at 11:08:24 UTC, Denis Feklushkin wrote:
 Similar to how people can avoid explicitly linking GNU's 
 libstdc++ / LLVM's libc++ by using `c++` instead of `cc` as 
 linker driver, thereby not having to know which implementation 
 of the C++ std library to choose for the particular platform.
Maybe in D case it will be right choice to respect --defaultlib= setting during static linking? So if anyone wants to link static library without stdlibs then just can leave it empty. In other cases druntime and phobos will be linked into static library?
This is NOT static **linking**, what you are asking for is merging the D-default static libraries into a generated static lib, to make it 'standalone' and thus simplify linking D parts into another project. Merging druntime and Phobos into a static lib is an extremely exotic case, analogous to someone wanting to merge a static libstdc++.a into their static C++ lib. So I don't see a good reason to support this use case by the compiler directly. What you could e.g. do with a dedicated ldc2.conf is specifying the paths to druntime and Phobos as regular default switches. Then they'll be merged into all static libraries that you create with that config file. Compilations are unaffected. [I guess linking would still work, but note that even with `-defaultlib=`, druntime and Phobos would be in every generated static lib *and* additionally in the linker cmdline.]
Aug 11
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 11 August 2024 at 11:40:39 UTC, kinke wrote:
 On Sunday, 11 August 2024 at 11:08:24 UTC, Denis Feklushkin 
 wrote:
 Similar to how people can avoid explicitly linking GNU's 
 libstdc++ / LLVM's libc++ by using `c++` instead of `cc` as 
 linker driver, thereby not having to know which 
 implementation of the C++ std library to choose for the 
 particular platform.
Maybe in D case it will be right choice to respect --defaultlib= setting during static linking? So if anyone wants to link static library without stdlibs then just can leave it empty. In other cases druntime and phobos will be linked into static library?
This is NOT static **linking**, what you are asking for is merging the D-default static libraries into a generated static lib, to make it 'standalone' and thus simplify linking D parts into another project.
Yes, I meant that. But really I don't understand the fundamental difference with static binary linking: there are "default libraries" and "just libraries". But there is no fundamental difference.
 Merging druntime and Phobos into a static lib is an extremely 
 exotic case, analogous to someone wanting to merge a static 
 libstdc++.a into their static C++ lib.
I don't see anything wrong with that. If everything around was written in some other language, C++ people would have been forced to add their runtime in a same roundabout way. My opinion is that C/C++ are not a reference point here: they created system as if there was only two languages, C and C++. The very idea of "default ​​libraries" is grist to the same mill.
 So I don't see a good reason to support this use case by the 
 compiler directly.
It helps with cases discussed in this topic. Because world around is written on C and C++, not on D. Build systems also isn't supporting D in most - for example, I can't force cmake to search the D standard library path to link target with it.
 What you could e.g. do with a dedicated ldc2.conf is specifying 
 the paths to druntime and Phobos as regular default switches.
This will break a lot of things, it's easier to manually add a similar hack into the build scripts Ok, thanks to all! I think my question was completely cleared
Aug 11
parent reply kinke <noone nowhere.com> writes:
On Sunday, 11 August 2024 at 13:16:16 UTC, Denis Feklushkin wrote:
 What you could e.g. do with a dedicated ldc2.conf is 
 specifying the paths to druntime and Phobos as regular default 
 switches.
This will break a lot of things, it's easier to manually add a similar hack into the build scripts
Yeah I'd probably prefer and go with that myself too. E.g., for the LDC CMake build, you can use the C++ compiler as linker driver (or the D host compiler); in that case, we need to pass the linker flags for host druntime+Phobos too, and do so by building a dummy-executable with the D host compiler and `-v`, and then parsing the printed linker cmdline. Wrt. available options for linking D parts *statically* into a project in another language, I'd go in this order: 1. Use the D compiler as linker driver. 2. With a non-D compiler as linker driver, inject the required linker flags for the D parts, something like `-L<path to libs dir> -lphobos2-ldc -ldruntime-ldc`, in the correct position. 3. Otherwise merge all static D libs incl. druntime+Phobos to a single monolithic static lib (still depending on libc etc.) as an extra step. Solution 3 could potentially be implemented in build systems like dub, which would then e.g. also allow you to create a 'standalone' fat static lib for a dub project with regular static-lib dub dependencies, merging all of them, not just druntime and Phobos. What I wrote earlier wasn't 100% exact:
 the `-defaultlib` libraries need to be in one of the 
 `lib-dirs` in ldc2.conf, it's the linker that resolves them
They don't **need** to be in one of the lib-dirs, but can also be specified in the cmdline/config file via `-L-L<dir>`. So the compiler really doesn't know the exact location the linker would use (potentially even skipping dirs with libs for another target architecture etc.).
Aug 11
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 12/08/2024 2:04 AM, kinke wrote:
 Wrt. available options for linking D parts /statically/ into a project 
 in another language, I'd go in this order:
 
  1. Use the D compiler as linker driver.
  2. With a non-D compiler as linker driver, inject the required linker
     flags for the D parts, something like |-L<path to libs dir>
     -lphobos2-ldc -ldruntime-ldc|, in the correct position.
  3. Otherwise merge all static D libs incl. druntime+Phobos to a single
     monolithic static lib (still depending on libc etc.) as an extra step.
 
 Solution 3 could potentially be implemented in build systems like dub, 
 which would then e.g. also allow you to create a 'standalone' fat static 
 lib for a dub project with regular static-lib dub dependencies, merging 
 all of them, not just druntime and Phobos.
This touches upon something I've been wanting for a while now, which is essentially a platform probe switch for D compilers. It would replace dub's platform probe file, but would aid in cases like this where you don't want to be guessing locations of files. But it could also offer: All target triples, their linker flags (with respect to shared + static builds), file paths to druntime/phobos, and if the triple is default or supported by host.
Aug 11
parent reply Denis Feklushkin <feklushkin.denis gmail.com> writes:
On Sunday, 11 August 2024 at 14:27:11 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

 This touches upon something I've been wanting for a while now, 
 which is essentially a platform probe switch for D compilers.

 It would replace dub's platform probe file, but would aid in 
 cases like this where you don't want to be guessing locations 
 of files.

 But it could also offer:

 All target triples, their linker flags (with respect to shared 
 + static builds), file paths to druntime/phobos, and if the 
 triple is default or supported by host.
https://github.com/ldc-developers/ldc/pull/4717 Maybe this is what you need? Just need to specify correct `--conf=` path
Aug 11
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 12/08/2024 6:06 AM, Denis Feklushkin wrote:
 On Sunday, 11 August 2024 at 14:27:11 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 
 This touches upon something I've been wanting for a while now, which 
 is essentially a platform probe switch for D compilers.

 It would replace dub's platform probe file, but would aid in cases 
 like this where you don't want to be guessing locations of files.

 But it could also offer:

 All target triples, their linker flags (with respect to shared + 
 static builds), file paths to druntime/phobos, and if the triple is 
 default or supported by host.
https://github.com/ldc-developers/ldc/pull/4717 Maybe this is what you need? Just need to specify correct `--conf=` path
No, that changes the configuration file location (you want to use the one that came with the compiler). What I suggested was for introspecting how the compiler is configured so tasks like linking against druntime/phobos separately didn't involve guess work.
Aug 11