dub
dub copied to clipboard
WIP: Support dependencies to dynamic libraries
Closes https://github.com/dlang/dub/issues/571
Thanks for your pull request and interest in making D better, @nordlow! 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:
andReturns:
)
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.
Just 3 points OTOH:
- Link dependencies will probably need to be adapted. For a dependency tree:
root project
- A (dynamic lib)
- B (static lib)
compiling root
will need import paths and compile flags etc. from B
, but its static library is not to be linked into root
, only A
. That's also the case if B
was a dynamic library.
-
For Windows targets, the
A
library to be linked intoroot
isn'tA.dll
, but its import libA.lib
. -
Multiple static libs across the whole project is likely problematic, e.g., for
root project
- A (dynamic lib)
- B (static lib)
- B (static lib)
I mentioned this in #2206, but this isn't enough.
Optlink needs to be told to generate import libraries and import libraries need to be copied if they aren't already.
Just 3 points OTOH:
- Link dependencies will probably need to be adapted. For a dependency tree:
This is fine. There are no checks for shared libraries so right now https://github.com/dlang/dub/blob/master/source/dub/generators/generator.d#L661 and its caller is doing the right thing.
- For Windows targets, the
A
library to be linked intoroot
isn'tA.dll
, but its import libA.lib
.- Multiple static libs across the whole project is likely problematic, e.g., for
I've been thinking about this.
I don't think we can fix multiple sibling shared libraries depending on a static library. I think the only fix is to turn it into shared library implicitly which would be a bit surprising.
For a binary depending on something in a shared library, I think this just affects link command generation. Which might be solvable by determining what binaries that depend on a Target to link a static library into. Somewhere in here: https://github.com/dlang/dub/blob/master/source/dub/generators/generator.d#L247
https://issues.dlang.org/show_bug.cgi?id=19784 is blocking OMF support.
For DMD, there are much bigger blockers for proper Windows DLL support, it would need something like LDC's -fvisibility=public
and -dllimport=all
, and then some druntime upstreamings for a druntime/Phobos DLL. Edit: And on Windows, there's still the max 64K symbols per DLL limit…
This is fine.
Good, thx for checking.
Another thing that came to mind is that a DLL dependency and its outputs should probably be copied to the root project's output dir, if they aren't already. For Windows, only the .dll, not the .lib.
I don't think we can fix multiple sibling shared libraries depending on a static library. I think the only fix is to turn it into shared library implicitly which would be a bit surprising.
I agree. Sometime, it might make sense for targetType "library"
to default to sharedLibrary
when building the dependent project as dynamic lib. And possibly even if the root project is an executable and has at least one transitive dynamic lib dependency. In which case, dub could automatically add -link-defaultlib-shared
/ -defaultlib=libphobos2.so
to the executable linker cmdline too, making sure druntime and Phobos are shared.
For DMD, there are much bigger blockers for proper Windows DLL support, it would need something like LDC's
-fvisibility=public
and-dllimport=all
, and then some druntime upstreamings for a druntime/Phobos DLL. Edit: And on Windows, there's still the max 64K symbols per DLL limit…
A lot of those are implementations details that dub can ignore.
But yeah they need to solved.
Another thing that came to mind is that a DLL dependency and its outputs should probably be copied to the root project's output dir, if they aren't already. For Windows, only the .dll, not the .lib.
Right now with MSVC the import libraries will be copied as well. Which I think is the correct behavior. The same goes for pdb files.
It's not an intermediary like object files are. It's an output that may be used with say C. You shouldn't have to go digging for them.
After all what happens if you are distributing your shared library for others to use (i.e. paid and they don't have source)?
I don't think we can fix multiple sibling shared libraries depending on a static library. I think the only fix is to turn it into shared library implicitly which would be a bit surprising.
I agree. Sometime, it might make sense for
targetType "library"
to default tosharedLibrary
when building the dependent project as dynamic lib. And possibly even if the root project is an executable and has at least one transitive dynamic lib dependency. In which case, dub could automatically add-link-defaultlib-shared
/-defaultlib=[libphobos2.so](http://libphobos2.so)
to the executable linker cmdline too, making sure druntime and Phobos are shared.
I don't think this is totally necessary. Lots of libraries are small, they can be statically linked against. Unless we actually get shared library support good everywhere it's probably best we don't mess with it, unfortunately.
For DMD, there are much bigger blockers for proper Windows DLL support, it would need something like LDC's
-fvisibility=public
and-dllimport=all
, and then some druntime upstreamings for a druntime/Phobos DLL. Edit: And on Windows, there's still the max 64K symbols per DLL limit…A lot of those are implementations details that dub can ignore.
But yeah they need to solved.
I just realized until that is fixed with export, it's not possible to resolve the issue of static libraries being linked in multiple times.
I'll do a PR with just the removal of dynamicLibrary to staticLibrary for non-x86_omf targets. Because that is all we can do for now.
Another thing that came to mind is that a DLL dependency and its outputs should probably be copied to the root project's output dir, if they aren't already. For Windows, only the .dll, not the .lib.
Right now with MSVC the import libraries will be copied as well. Which I think is the correct behavior. The same goes for pdb files.
It's not an intermediary like object files are. It's an output that may be used with say C. You shouldn't have to go digging for them.
I wasn't talking about copying both concurrency.{dll,lib}
to the output dir of a concurrency
dynamic lib, but about copying concurrency.dll
to the output dir of some other DLL/exe depending on concurrency.dll. Where the .lib is useless.