Fix node build on Windows#255
Merged
akoeplinger merged 1 commit intodotnet/mainfrom Dec 1, 2025
Merged
Conversation
Some recent version of MSVC regressed linking mksnapshot.exe, resulting in lots of LNK2019 errors.
lewing
approved these changes
Dec 1, 2025
akoeplinger
added a commit
that referenced
this pull request
Dec 1, 2025
Some recent version of MSVC regressed linking mksnapshot.exe, resulting in lots of LNK2019 errors. (cherry picked from commit ccf4f64)
akoeplinger
added a commit
that referenced
this pull request
Dec 1, 2025
Some recent version of MSVC regressed linking mksnapshot.exe, resulting in lots of LNK2019 errors. (cherry picked from commit ccf4f64)
akoeplinger
added a commit
that referenced
this pull request
Dec 1, 2025
Some recent version of MSVC regressed linking mksnapshot.exe, resulting in lots of LNK2019 errors. (cherry picked from commit ccf4f64)
7 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.
Some recent version of MSVC regressed linking mksnapshot.exe, resulting in lots of LNK2019 errors.
Copilot helped me find a workaround, below is the summary:
Details
GitHub Copilot: Here’s a quick roadmap of what’s going on, followed by a deeper dive:extern templateto stop the compiler from instantiating them multiple times everywhere..ccfiles such as factory-base.cc, factory.cc, ordered-hash-table.cc, and shared-function-info.cc. They use helpers from export-template.h to decide whether to decorate the instantiation with__declspec(dllexport)(when building a shared V8) or leave it undecorated (when building static libraries).BUILDING_V8_SHARED=1(via common.gypi) even when producing static libs (*.lib), those instantiation definitions becametemplate class __declspec(dllexport) …;.__declspec(dllexport), the compiler either suppresses code emission or the objects are later discarded; the static library ends up missing the symbol entirely.extern templatedeclarations, no translation unit tries to re-instantiate the template implicitly. So when the linker looks for, say,v8::internal::FactoryBase<Factory>::AllocateRawWithImmortalMaporHashTable<NameDictionary>::Shrink, it finds nothing and raises the unresolved externals you saw.BUILDING_V8_SHAREDdefine keeps V8’s template instantiations undecorated. With plain instantiations, MSVC generates the functions correctly and the link succeeds, even on the versions that exhibit the bug.You can see the mechanics here:
V8_EXPORT_PRIVATEto__declspec(dllexport)wheneverBUILDING_V8_SHAREDis defined.V8_EXPORT_PRIVATEis__declspec(dllexport), the definition becomestemplate class __declspec(dllexport) HashTable<...>;.So from a template standpoint: V8 intentionally avoids implicit instantiation by declaring every interesting template
extern template ...in headers, then explicitly instantiating them in a handful of source files. If the explicit instantiation vanishes (because the compiler drops it under that misconfigureddllexportscenario), there is literally no code emitted for the template, and the linker fails.By removing
BUILDING_V8_SHARED=1from the static-library configs (or flipping the logic toUSING_V8_SHAREDonly when you really link against a DLL), those explicit instantiations revert to plain definitions and the bug is bypassed—the compiler emits the code, the library contains the symbols, and the linker resolves them.After that, I was still hitting LNK2019 errors in
LocalFactory::true_value/false_value:Details
GitHub Copilot: Nice progress—only the `LocalFactory::true_value/false_value` pair is still missing now. Those two accessors are declared `inline` in local-factory.h, but in local-factory-inl.h the definitions currently expand toBecause the definition itself isn’t marked
inline, MSC 19.40+ treats it as an out-of-line function that should live in some object file. Before ourBUILDING_V8_SHAREDcleanup the functions were emitted via the__declspec(dllexport)instantiations in the DLL build path; once those decorations disappeared, the linker started looking for an actual symbol in the static archive and couldn’t find one.Fix
Edit local-factory-inl.h so both macro expansions add the
inlinespecifier:But that still wasn't enough, it needed one more change:
Details
GitHub Copilot: Got it—you’re still seeing the
LocalFactory::true_value/false_valueunresolved externals even after marking the accessorsinline. The missing piece is that the MSVC precompiled header (v8_pch.h, built intov8_pch.obj) includessrc/api/api-inl.h,src/objects/objects-inl.h, factory-base-inl.h, etc., but not local-factory-inl.h. When it instantiatesFactoryBase<LocalFactory>::ToBoolean, it only sees the declarations forLocalFactory::true_value/false_value, not the inline definitions, so it emits external references that never get resolved.Fix
Add the inline definitions to the PCH:
This ensures every translation unit built with the precompiled header (including
v8_pch.cppitself) sees the inline definitions forLocalFactory::true_value()andfalse_value().... and then it worked!