cc/msvc: real DLL output for dynamic_link (auto-export, implib, staging) - #70
Merged
Conversation
blade-go linked dynamic_link targets statically. Now, on MSVC, a
cc_library reachable from a dynamic_link cc_binary/cc_test is built as a
real DLL, and the consumer links the import lib with the DLL staged for
load -- matching Blade. gcc/clang and non-dynamic builds are unchanged.
Mechanism (internal/cc, internal/windef, cmd/blade):
* needs-dynamic set: the cc_library closure of every dynamic_link
binary/test, honoring generate_dynamic=False (gtest_main/test_main
stay static -- their main() belongs in the exe, not a DLL).
* a `windef` edge runs the new `__gen-windef` subcommand: read the
objects' COFF symbols via `dumpbin /SYMBOLS`, write a .def exporting
every defined external (DATA-tagged when not a function), so a library
exports without per-source __declspec(dllexport). The blade-go analog
of Blade's cc_windef.
* `solink` links the DLL + import lib (/DLL /DEF /IMPLIB); the DLL base
name encodes its package (suites.cc_basic.hello.dll) so DLLs flatten
into one dir without collision.
* a dynamic_link binary/test links the deps' import libs (not the static
archives) and gets each transitive DLL staged next to the exe via a
deduped `copy` edge (`__cp` subcommand), so it loads at runtime.
* ninja.Build gains ImplicitOutputs (DLL|implib); ninja.Rule gains
Restat (write-if-changed .def prunes needless DLL relinks).
Verified on Windows 11 ARM64 (VS2026): blade-test cc_basic's dynamic tests
(hello_dynamic_test, cross_package_dynamic_test) build as real DLLs and
pass; hello.dll / farewell.dll are auto-exported and staged next to the
exe. All cc suites (cc_basic/cc_incs/cc_export_map/cc_dll_export) stay
green. go test ./... green on macOS/arm64; new tests cover dllBasename,
the dynamic-link generation, and the export filter.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
blade-go linked
dynamic_linktargets statically. Now, on MSVC, acc_libraryreachable from adynamic_linkcc_binary/cc_test is built as a real DLL, the consumer links the import lib, and the DLL is staged for load — matching Blade. gcc/clang and non-dynamic builds unchanged.Mechanism
dynamic_linktarget, honoringgenerate_dynamic=False(gtest_main/test_main stay static — theirmain()belongs in the exe, not a DLL)..def— awindefedge runs the new__gen-windefsubcommand: read the objects' COFF symbols viadumpbin /SYMBOLS, write a.defexporting every defined external (DATA-tagged when not a function). The blade-go analog of Blade'scc_windef— no per-source__declspec(dllexport)needed.solink— links the DLL + import lib (/DLL /DEF /IMPLIB); the DLL base name encodes its package (suites.cc_basic.hello.dll) so DLLs flatten into one dir without collision.dynamic_linkbinary/test links the deps' import libs (not the static archives) and gets each transitive DLL staged next to the exe via a dedupedcopyedge (__cp), so it loads at runtime.ninja.BuildgainsImplicitOutputs(DLL|implib);ninja.RulegainsRestat(write-if-changed.defprunes needless relinks).Verified (Windows 11 ARM64, VS2026)
blade-test cc_basic's dynamic tests (
hello_dynamic_test,cross_package_dynamic_test) build as real DLLs and pass;hello.dll/farewell.dllare auto-exported + staged next to the exe. All cc suites (cc_basic/cc_incs/cc_export_map/cc_dll_export) stay green.go test ./...green on macOS/arm64; new tests coverdllBasename, the dynamic-link generation, and the export filter.