-
-
Notifications
You must be signed in to change notification settings - Fork 161
fix(windows): unbreak the MSVC compiler link and the WinUI widget backend #10384
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
Closed
+186
−0
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| Unbreak both Windows CI legs on `main`. | ||
|
|
||
| `windows-arm64-build` failed with `LNK1120: 7 unresolved externals` — the whole | ||
| `js_lru_cache_*` ABI — when linking **the `perry` compiler itself**. | ||
| `perry-runtime/src/lru_subclass.rs` declares that ABI `extern "C"` and leaves it | ||
| to whichever cache provider the program links; `perry` links neither provider, so | ||
| its link carries seven undefined references. Every other target hides this | ||
| because its linker dead-strips before it reports (the same command succeeds on | ||
| macOS while the rlib still shows all seven as `U`), whereas `link.exe` resolves | ||
| symbols before `/OPT:REF`. | ||
|
|
||
| A Cargo feature cannot express "this link has no provider": the Windows job | ||
| builds `-p perry -p perry-runtime-static -p perry-stdlib-static` in one | ||
| invocation, so perry-stdlib unifies `perry-runtime/stdlib` onto the copy of | ||
| perry-runtime that `perry` links, and anything gated on `stdlib` — including the | ||
| existing `stdlib_stubs` mechanism — is compiled out in exactly the failing | ||
| configuration. Fixed with `/ALTERNATENAME` directives in `.drectve` behind | ||
| `cfg(all(windows, target_env = "msvc"))` plus no-op fallbacks reporting through | ||
| `perry_stub_warn`; `link.exe` substitutes an alternate only for a symbol still | ||
| undefined after all inputs are read, so a real provider always wins. | ||
|
|
||
| `windows-build` failed with `error[E0425]: cannot find function reorder_child in | ||
| module widgets`, in `perry-ui-windows-winui`: it `#[path]`-includes | ||
| perry-ui-windows' `ffi/mod.rs`, so `widgets::` resolves against winui's own | ||
| module, which never gained `reorder_child`. Added in the module's established | ||
| shape — delegate to the Win32 implementation when Fluent is inactive, otherwise | ||
| reorder the node's children under `with_node_mut`. | ||
|
|
||
| Neither Windows job runs in the PR tier (`ci_plan.py`: sweep and full only), so | ||
| the fix was validated by emitting the COFF object for | ||
| `x86_64-pc-windows-msvc` and confirming the `.drectve` contents and symbol | ||
| classes directly; no Windows link was performed. |
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
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 8008
🏁 Script executed:
Repository: PerryTS/perry
Length of output: 42820
🌐 Web query:
Microsoft MSVC x86 C symbol decoration leading underscore extern C linker name💡 Result:
<search_synthesis>
On the x86 architecture, the Microsoft MSVC compiler decorates C symbols—and C++ symbols declared with extern "C"—by prepending a leading underscore to the function name when using the default cdecl calling convention [1][2][3]. This decoration is a form of name mangling intended to distinguish C symbols and ensure compatibility with specific ABI requirements [2][4]. For example, a function named test using the cdecl calling convention will be decorated as _test [1][2]. Key points regarding this decoration: - extern "C" Influence: The extern "C" specifier disables C++ name mangling (which would otherwise result in a complex decorated name) but does not disable C-style name decoration [5][6]. When extern "C" is used, the compiler applies standard C naming conventions, which for x86 cdecl includes the leading underscore [1][2]. - Calling Convention Dependence: The decoration format is tied to the calling convention [2][3]. While cdecl adds a leading underscore, other conventions use different patterns. For instance, stdcall adds a leading underscore and a trailing @ followed by the parameter list size (e.g., _test@4) [1][2][7]. - Exporting and Linkage: When creating DLLs or linking to assembly, it is common to encounter issues where the linker expects a decorated name (e.g., _test) while the developer might expect an undecorated name (e.g., test). To export a function with its exact, undecorated name, developers typically use a module-definition (.DEF) file with the EXPORTS keyword, which allows them to map an undecorated name to the decorated internal symbol [8][5][7]. - Architecture Variation: Note that this leading underscore decoration behavior is specific to x86. In 64-bit (x64) environments, MSVC generally does not apply this leading underscore decoration to C or extern "C" functions [2][4][3].
</search_synthesis>
<source_evidence>
Citations:
🌐 Web query:
Microsoft link.exe /ALTERNATENAME exact decorated symbol names x86 leading underscore💡 Result:
<search_synthesis>
The /ALTERNATENAME linker option is an undocumented, architecture-sensitive feature of the Microsoft Visual C++ (MSVC) linker used to define a weak alias or redirect an unresolved symbol to another symbol [1]. When using this switch, you must provide the exact decorated (mangled) names of the symbols, as the linker does not perform any automatic name decoration or adjustment [1][2][3]. For x86 (32-bit) targets, C symbols using the default cdecl calling convention are prefixed with a leading underscore [4][5]. Therefore, if you are creating an alias between two symbols for x86, both names in the /ALTERNATENAME argument must include this leading underscore [1][2]. Key considerations include: 1. Exact Matching: The linker expects the full mangled name [1][3]. If you are working with C++ symbols, these will often contain characters like?, @, and various codes representing the function signature [5][3]. For C functions, the decoration depends on the calling convention (e.g., stdcall adds a leading underscore and a trailing @ and parameter size) [4][5][6]. 2. Architecture Sensitivity: Because name decoration varies significantly between architectures (x86 vs. x64/ARM), you must use preprocessor directives to provide the correct decorated strings for each target [1][7]. 3. Implementation: The most common way to invoke this is via a pragma directive in your source code [1]:
#ifdefined(_M_IX86)#pragmacomment(linker, "/alternatename:_symbol= _alternate_symbol")#else#pragmacomment(linker, "/alternatename:symbol=alternate_symbol")#endifIf you are unsure of the exact decorated name for a symbol, you can use the DUMPBIN tool (/SYMBOLS option) or the linker's /MAP option to inspect the generated object files and see how the compiler has mangled the names [4][6].</search_synthesis>
<source_evidence>
Citations:
Add aliases for 32-bit MSVC symbol names.
msvc_absent_providerapplies to every Windows MSVC target, includingi686-pc-windows-msvc. On 32-bit MSVC, theextern "C"references and#[no_mangle] extern "C"fallback definitions use leading-underscore symbols./ALTERNATENAMEmatches exact decorated linker names, but these directives use undecorated names. The linker therefore cannot apply these fallbacks to the_js_lru_cache_*references.Add x86-specific directives with decorated source and fallback names, or restrict this module to the supported MSVC architectures.
🤖 Prompt for AI Agents