fix: support LLVM LTO DLL exports and optional automatic discovery - #763
Merged
Sunrisepeak merged 2 commits intoOct 5, 2026
Merged
Conversation
Export intent is checked before candidate enumeration. The selected LLVM compiler and llvm-nm handle LTO objects, while ordinary COFF retains its native reader. Per-target auto_export disables discovery for root and dependency DLLs.
18 tasks
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.
Summary
A release-profile MSVC-ABI DLL with LLVM LTO objects fails at
coff-defwithunsupported COFF machine 0x4342. Even an annotated library reaches candidateenumeration before its annotations can suppress the generated export list.
Export discovery now checks native COFF directives before inspecting bitcode
export intent. Any input's explicit exports still suppress automatic exports
for the entire DLL. Only unannotated inputs reach candidate enumeration. LLVM
bitcode candidates use
llvm-nmfrom the selected compiler's installation;the selected compiler reads IR without generating machine code. COFF and
bitcode share the symbol filter and i386 name normalization.
[targets.<name>] auto_export = falseremoves the discovery edge for targetsand dependency-owned shared libraries. The default stays
true. The TOML andxpkg readers implement the same boolean contract. The English and Chinese
references and lookup indexes document the key, platform scope and LTO inputs.
The new behavior is explicitly marked as unreleased source-build functionality.
Closes #762.
Criteria
Validation used a freshly built binary on Windows x64, MSVC 14.51.36231 and
Windows SDK 10.0.26100.0. The binary was built with
llvm@22.1.8; the E2Efixtures select
llvm@20.1.7, which is the repository's Windows pin.881_pe_auto_exports_accept_llvm_bitcode.shfailed against the fresh,unmodified
origin/mainbinary atbin/automatic.defwith machine0x4342.It passes with this branch. It builds and loads FullLTO DLLs, runs a module
consumer, checks DATA exports, preserves annotated surfaces, checks the
root and dependency opt-outs, and reads ThinLTO, mixed objects and x86 input.
The ordinary annotated COFF tests deliberately supply nonexistent LLVM
tools in both input orders; linker-option metadata deliberately supplies
nonexistent
llvm-nm. These paths succeed without candidate enumeration.The script runs in the Windows E2E shards (
requires: msvc python3).258_shared_library_msvc_auto_def.shpasses with the fresh binary andnative
cl.exe. Native unannotated exports, annotation precedence and theconsumer's
dllimportrequirement for DATA retain their existing behavior.mcpp test --toolchain llvm@22.1.8run has 145 passing testexecutables and one failing executable. The sole failure is the existing
Glob.EscapedSpellingIsUtf8WhateverTheNameWindows code-page exception inunit/test_modgraph; the same filtered test fails against the unmodifiedorigin/mainbinary. This PR does not change that code.exports, linker metadata, DATA/COMDAT candidate types, invalid nm output,
both bitcode signatures, i386 decoration, both manifest readers, selected
tool argument quoting and the PE/MSVC-only planning gate. After the final
IR-scanning optimization, all eight
PeExportstests and E2E 881 pass again.The host-independent unit cases run on Linux, macOS and Windows CI; the
native DLL E2E requires Windows and usable MSVC.
clang-cl.exewas also exercised directly as the IR reader:annotated FullLTO produces an empty
EXPORTSsection, and unannotatedThinLTO produces function and DATA exports.
Intersections
PeExports.NmCandidatesKeepDataAndComdatButExcludeNonDefinitionsauto_exportPeExports.OptOutAffectsOnlyTheMsvcAbiSharedLinkFormNinjaBackend.BitcodeExportToolsComeFromTheSelectedLlvmAndAreQuotedAsWords; E2E 881 HPeExports.NamesCommentsAttributesAndDataDoNotDeclareExports; linker-metadata unit cases; E2E 881 E/FCompatibility
Existing projects keep automatic export discovery enabled. A library with
explicit exports still controls its own surface. Ordinary COFF discovery
needs no LLVM tools. Unannotated LTO inputs require
llvm-nmalongside theselected LLVM compiler; errors retain the object name and tool diagnostics.
The switch only affects MSVC-ABI PE shared links. ELF, Mach-O, MinGW, static
libraries and executables retain their export behavior. Native annotations,
link flags and explicit
exportslists remain effective with discovery off.Existing generated export commands change once when Ninja regenerates the
graph. No manifest migration is required. This is separate from #761's
same-package executable link fix and does not include that patch.
Checks before merging
The preceding revision passed platform builds and Linux/macOS E2E. Windows
E2E 881 failed before compilation because native Windows MCPP_HOME paths
were written into TOML without normalization. The shared fixture helper now
normalizes drive-absolute paths; E2E 00 covers native and mixed Windows spelling
and relative-path preservation. E2E 881 passes locally with native Windows
MCPP_HOME. The new CI run
verifies commit
a702dee4; its results are pending.Move the Chinese README's CI badge outside its navigation table to match
the English layout and correct the existing table-row mismatch.
python .github/tools/check_workflow_assertions.pypasses (22 workflows,zero problems).
check_modules_wiring.sh,check_narrow_conversions.shandgit diff --checkpass.git log origin/main..HEAD -i --grep='Co-Authored-By'prints nothing.merged by the contributor.