Skip to content

Set per-target compile PDB for cDAC descriptor object libraries#127836

Merged
steveisok merged 3 commits intodotnet:mainfrom
lewing:fix-cdac-descriptor-pdb-lnk4099
May 6, 2026
Merged

Set per-target compile PDB for cDAC descriptor object libraries#127836
steveisok merged 3 commits intodotnet:mainfrom
lewing:fix-cdac-descriptor-pdb-lnk4099

Conversation

@lewing
Copy link
Copy Markdown
Member

@lewing lewing commented May 5, 2026

Note

This PR was authored with assistance from GitHub Copilot.

Problem

The OBJECT libraries created by generate_data_descriptors() in src/coreclr/clrdatadescriptors.cmake compile contract-descriptor.c and contractpointerdata.cpp with MSVC defaults, which routes debug info into the compiler-default vc140.pdb. That PDB does not travel with the .obj files when they are archived into a static library such as Runtime.ServerGC.lib.

Downstream linkers — in particular the NativeAOT publish of ILCompiler, crossgen2, and ilasm on Windows — then emit LNK4099 ("PDB 'vc140.pdb' was not found") for each affected object, which is fatal under /WX.

Symptom

The dotnet/runtimedotnet/dotnet codeflow PR dotnet/dotnet#6423 is blocked: the VMR Vertical Build Windows_x64 and VMR Vertical Build Windows_x86 legs both fail with 22 LNK4099 errors apiece, e.g.:

Runtime.ServerGC.lib(contract-descriptor.c.obj) : error LNK4099:
  PDB 'vc140.pdb' was not found with 'Runtime.ServerGC.lib(contract-descriptor.c.obj)'
  or at '...\artifacts\bin\ILCompiler_publish\x64\Release\native\vc140.pdb';
  linking object as if no debug info
   [src\coreclr\tools\aot\ILCompiler\ILCompiler_publish.csproj]
Runtime.ServerGC.lib(contractpointerdata.cpp.obj) : error LNK4099: ...

repeated for crossgen2_publish.csproj and ilasm.csproj. Linux/macOS/WASM/iOS/Android verticals all pass — LNK4099 is MSVC-specific.

The regression was introduced by #126972 ("[NativeAOT] Add cDAC data descriptor infrastructure"), which wired the new descriptor OBJECT libraries into the NativeAOT runtime so they end up archived inside Runtime.ServerGC.lib.

Fix

Set COMPILE_PDB_NAME and COMPILE_PDB_OUTPUT_DIRECTORY on ${LIBRARY} so each descriptor library produces its own deterministic PDB that the consuming linker can locate. This matches the convention already used by install_static_library in eng/native/functions.cmake.

Validation

  • CMake reconfigures cleanly.
  • Ninja built nativeaot_gc_svr_descriptor, nativeaot_gc_wks_descriptor, nativeaot_cdac_contract_descriptor, and cdac_contract_descriptor without errors on linux-x64.
  • The actual LNK4099 resolution can only be verified on a Windows NativeAOT publish leg in CI; please pay particular attention to the Windows legs and to the next forward-flow into dotnet/dotnet.

cc @max-charlamb (author of #126972)

The OBJECT libraries created by generate_data_descriptors() compile
contract-descriptor.c and contractpointerdata.cpp with MSVC defaults,
which routes debug info into the compiler-default vc140.pdb. That PDB
does not travel with the .obj files when they are archived into a
static library such as Runtime.ServerGC.lib. Downstream linkers - in
particular the NativeAOT publish of ILCompiler, crossgen2, and ilasm
on Windows - then emit LNK4099 ("PDB 'vc140.pdb' was not found") for
each affected object, which is fatal under /WX.

Set COMPILE_PDB_NAME and COMPILE_PDB_OUTPUT_DIRECTORY so each
descriptor library produces its own deterministic PDB that the
consuming linker can locate, matching the convention already used by
install_static_library in eng/native/functions.cmake.

This unblocks the dotnet/runtime -> dotnet/dotnet codeflow PR
(dotnet/dotnet#6423), where the VMR Vertical Build Windows_x64 and
Windows_x86 legs were failing with 22 LNK4099 errors after
PR dotnet#126972 (cDAC data descriptor infrastructure) wired the new
descriptor object libraries into the NativeAOT runtime.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 5, 2026 21:00
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

@jkotas jkotas requested a review from max-charlamb May 5, 2026 21:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates CoreCLR’s cDAC descriptor OBJECT libraries so that, when built with MSVC, they emit per-target compile PDBs instead of falling back to the default vc140.pdb name. This is intended to prevent downstream Windows NativeAOT publish link failures caused by LNK4099 when those object files are later archived into static libraries (e.g., Runtime.ServerGC.lib) and linked under /WX.

Changes:

  • Add MSVC-only set_target_properties to set COMPILE_PDB_NAME and COMPILE_PDB_OUTPUT_DIRECTORY for descriptor object library targets created by generate_data_descriptors().

Comment thread src/coreclr/clrdatadescriptors.cmake Outdated
Append $<CONFIG> to COMPILE_PDB_OUTPUT_DIRECTORY so multi-config
generators (VS, Ninja Multi-Config) place each configuration's PDB
in its own directory, avoiding cross-config overwrites or parallel
build races. Single-config generators (the default in this repo)
already use a config-specific binary directory, so behavior there
is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@max-charlamb max-charlamb left a comment

Choose a reason for hiding this comment

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

Thanks for the fix. This change looks reasonable if it fixes the VMR. It shouldn't have an impact on the actual data descriptor.

@lewing lewing enabled auto-merge (squash) May 5, 2026 22:20
@steveisok steveisok self-requested a review May 6, 2026 00:19
PADDED_RELOC_SIZE is 'static const unsigned', so comparing a signed
'int i' against 'PADDED_RELOC_SIZE - 1' triggers
-Werror=sign-compare under GCC, breaking the linux-x64 checked
Native_GCC build leg.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 6, 2026 00:20
@steveisok
Copy link
Copy Markdown
Member

#127773 introduced a GCC 15 -Werror sign-compare regression. Pushed a commit to fix that along with the original change.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/jit/emitwasm.cpp
@steveisok steveisok disabled auto-merge May 6, 2026 02:34
@steveisok steveisok merged commit 1f84bc9 into dotnet:main May 6, 2026
109 of 131 checks passed
steveisok added a commit to dotnet/dotnet that referenced this pull request May 6, 2026
The per-target compile PDB introduced by dotnet/runtime#127836 only renamed
the missing PDB - the external PDB still stays in the producer's binary dir
and is not visible to downstream linkers consuming Runtime.ServerGC.lib /
Runtime.WorkstationGC.lib. The result was that the LNK4099 errors changed
shape (from missing 'vc140.pdb' to missing per-target named PDBs) but
remained fatal under /WX in the VMR Windows verticals.

Adding /Z7 makes each .obj carry its CodeView debug info inline, so the
data travels with the object file when it is archived into a static lib
and reaches the consumer's linker without needing a separate .pdb file.
This unblocks the VMR Vertical Build Windows_x64 / Windows_x86 legs in
PR 6423 and similar codeflow PRs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants