Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] fix issue 4071 and others: shared runtime DLL for Windows #14849

Merged
merged 13 commits into from
Dec 30, 2023

Conversation

rainers
Copy link
Member

@rainers rainers commented Jan 26, 2023

This is work in progress.

Basic idea is copied from LDC:

  • root modules dllexport all symbols
  • symbols from non-root modules are dllimported.
  • code accessing symbols in another DLL use an indirection through the import table
  • data initialized with addresses in another DLL are patched by an "early" CRT constructor

Runtime support for properly attaching to the GC still missing.

@rainers rainers requested a review from ibuclaw as a code owner January 26, 2023 08:44
@dlang-bot dlang-bot added the Review:WIP Work In Progress - not ready for review or pulling label Jan 26, 2023
@dlang-bot
Copy link
Contributor

Thanks for your pull request, @rainers!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#14849"

@WalterBright
Copy link
Member

Doesn't this imply that both the executable and the dll must each be compiled monolithically, i.e. no separate compilation?

@rainers
Copy link
Member Author

rainers commented Jan 27, 2023

Doesn't this imply that both the executable and the dll must each be compiled monolithically, i.e. no separate compilation?

Yes. There is also an option to only dllimport symbols from druntime/phobos which covers building executables that use the runtime in a DLL. This could be expanded to allow specifying the affected packages/modules on the command line. IIRC that's what Benjamin Thaut also proposed.

@WalterBright
Copy link
Member

Martin told me that the export everything runs up against a 64K limit on exports for Windows DLLs.

bool isDllImported(Dsymbol var)
{
if (target.os & Target.OS.Posix)
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since dllimport is a windows-only thing, the test should be "if not Windows return false".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same test is used in createImport(). I have changed it to Windows-only nonetheless.

@rainers
Copy link
Member Author

rainers commented Jun 22, 2023

Martin told me that the export everything runs up against a 64K limit on exports for Windows DLLs.

This might be an issue in the long run, but not that different from C++ libraries that export a class hierarchy. Qt5Widgets.dll has >9000 exports, Qt5Gui.dll >25000 exports. druntime and phobos lie in the same ballpark with 14000 and 13000, respectively, according to my last experiments. LDC's DLLs are a bit below that.

@rikkimax
Copy link
Contributor

Martin told me that the export everything runs up against a 64K limit on exports for Windows DLLs.

In my ~100+k LOC codebase, it's sitting around 9k exports from my rough estimate recently. This could be decreased by a worthwhile amount with the implicit construction of sum types in function arguments.

It isn't going to be a worry unless you do templates galore while exporting everything or scope your binaries very badly IMO.

Copy link
Member

@WalterBright WalterBright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approve this because it is behind a switch, so is not the default behavior, and it will support a behavior some people want #15298 (comment)

@LightBender
Copy link
Contributor

@rainers Is there any chance we can get this rebased? I've been hammering on Walter to get the DLL situation fixed, so we should be good to merge if you are.

@thewilsonator
Copy link
Contributor

I have a rebase at https://github.com/thewilsonator/dmd/tree/rainer_dll but since @kinke redid the makefiles, will need to redo the specific commit that changed win64.mak.

@rikkimax
Copy link
Contributor

Long term, perhaps it should be a step in the pipeline steps?

For now, an optional new pipeline seems to be arguably ok.

@thewilsonator
Copy link
Contributor

Also this looks to be missing the argument reconciliation logic https://github.com/dlang/dmd/pull/15964/files#diff-527cf1019708a4dc99987160134da80d3a0628c6df7a207192ddf3e34575ace7

@rainers
Copy link
Member Author

rainers commented Dec 29, 2023

Also this looks to be missing the argument reconciliation logic

Although the description says this should happen (copied from LDC), it is a change to how -shared behaves. I was not so sure whether this should happen right away.

@thewilsonator
Copy link
Contributor

error: undefined reference to '__fpclassifyf', floor, log10 etc. Is libm not being linked?

@rainers
Copy link
Member Author

rainers commented Dec 29, 2023

error: undefined reference to '__fpclassifyf', floor, log10 etc. Is libm not being linked?

I'm struggling with the mixture of (UT_)-DRUNTIMESO and DRUNTIMESOLIB...

allow writable module info
enable CI tests for shared runtime
@thewilsonator
Copy link
Contributor

Yay, it's green! Is this good to go now?

@rainers
Copy link
Member Author

rainers commented Dec 30, 2023

The test/shared tests didn't rerun for the shared runtime, now cleaning the generated folder. I'm trying to build the link/lib pair for Windows, too. That will show some remaining issues...

@rainers
Copy link
Member Author

rainers commented Dec 30, 2023

I'm trying to build the link/lib pair for Windows, too. That will show some remaining issues...

As expected, these show that there is runtime library support missing for clients of the shared druntime:

  • running shared module ctors
  • running thread local module ctors
  • registering DATA/TLS ranges with the GC
  • exceptions

I think these should be done in separate PRs.

@thewilsonator thewilsonator merged commit f9a2557 into dlang:master Dec 30, 2023
46 checks passed
@rikkimax
Copy link
Contributor

A thank you to you Rainer over this PR: https://forum.dlang.org/post/ymkubdpxsdnzgypidkwd@forum.dlang.org

@LightBender
Copy link
Contributor

Thank you @rainers and @thewilsonator for getting this across the finish line at light-speed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review:WIP Work In Progress - not ready for review or pulling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants