dub icon indicating copy to clipboard operation
dub copied to clipboard

WIP: Support dependencies to dynamic libraries

Open nordlow opened this issue 3 years ago • 9 comments

Closes https://github.com/dlang/dub/issues/571

nordlow avatar Jun 22 '21 20:06 nordlow

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: 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.

dlang-bot avatar Jun 22 '21 20:06 dlang-bot

Just 3 points OTOH:

  1. 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.

  1. For Windows targets, the A library to be linked into root isn't A.dll, but its import lib A.lib.

  2. Multiple static libs across the whole project is likely problematic, e.g., for

root project
- A (dynamic lib)
  - B (static lib)
- B (static lib)

kinke avatar Jun 22 '21 21:06 kinke

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.

rikkimax avatar Feb 04 '22 20:02 rikkimax

Just 3 points OTOH:

  1. 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.

  1. For Windows targets, the A library to be linked into root isn't A.dll, but its import lib A.lib.
  2. 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

rikkimax avatar Feb 07 '22 22:02 rikkimax

https://issues.dlang.org/show_bug.cgi?id=19784 is blocking OMF support.

rikkimax avatar Feb 07 '22 23:02 rikkimax

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.

kinke avatar Feb 08 '22 00:02 kinke

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 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](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.

rikkimax avatar Feb 08 '22 01:02 rikkimax

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.

rikkimax avatar Feb 08 '22 01:02 rikkimax

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.

kinke avatar Feb 08 '22 02:02 kinke