Skip to content

fix(windows): trim duplicate COFF archive members - #7085

Merged
proggeramlug merged 3 commits into
mainfrom
fix/6626-windows-duplicate-symbols
Jul 30, 2026
Merged

fix(windows): trim duplicate COFF archive members#7085
proggeramlug merged 3 commits into
mainfrom
fix/6626-windows-duplicate-symbols

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Closes #6626

Summary

  • run the existing symbol-set/evidence-based UI archive trim for Windows instead of skipping COFF
  • keep any object with a UI-specific symbol while dropping objects fully provided by the canonical runtime/stdlib
  • discover llvm-ar/llvm-nm beside the resolved lld-link for prebuilt Windows installs
  • rebuild large COFF archives in bounded batches to stay below CreateProcess command-line limits
  • retain /FORCE:MULTIPLE only for mixed-symbol members and external native libraries that cannot be removed wholesale

Validation

  • cargo test -p perry --bin perry strip_dedup_tests (6/6 on host)
  • Windows-only test builds real COFF objects/archives and asserts a duplicated runtime member is removed while the UI-only member survives
  • cargo fmt --all -- --check
  • git diff --check
  • actionlint .github/workflows/test.yml (only pre-existing shellcheck findings)

The required Windows build job now runs the real COFF regression test.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows linking by trimming fully duplicated UI archive members using symbol evidence before linking.
    • Kept UI-only symbols intact to avoid duplicate-definition link failures.
    • Strengthened Windows COFF deduplication by improving LLVM tool discovery, failing clearly when symbol tables can’t be read, and rebuilding archives safely.
  • Tests
    • Added Windows coverage to verify COFF .lib rebuilding and correct removal of only fully duplicated members.
  • Chores
    • Tightened Windows CI test reporting to ensure the expected test result occurs exactly once.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Windows UI archive linking now removes fully duplicated COFF members using symbol evidence, resolves LLVM tools beside lld-link, rebuilds archives in bounded batches, and adds targeted Windows CI coverage.

Changes

Windows COFF deduplication

Layer / File(s) Summary
COFF deduplication engine
crates/perry/src/commands/compile/strip_dedup.rs, crates/perry/src/commands/compile/strip_dedup/stub_symbols.rs
LLVM tool discovery, COFF error handling, bounded archive rebuilding, symbol indexing, and a Windows selective-removal test were added.
Windows linker integration and validation
crates/perry/src/commands/compile/link/build_and_run.rs, crates/perry/src/commands/compile/link/platform_cmd.rs, .github/workflows/test.yml, changelog.d/7085-windows-coff-dedup.md
Windows UI libraries now use archive trimming and the trimmed result directly; linker documentation, changelog text, and targeted CI coverage were updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WindowsBuild
  participant build_and_run_link
  participant strip_duplicate_objects_from_lib
  participant llvm_ar
  participant llvm_nm
  WindowsBuild->>build_and_run_link: build Windows target
  build_and_run_link->>strip_duplicate_objects_from_lib: trim UI archive
  strip_duplicate_objects_from_lib->>llvm_ar: list and rebuild COFF members
  strip_duplicate_objects_from_lib->>llvm_nm: inspect member symbols
  build_and_run_link->>build_and_run_link: link with trimmed archive
Loading

Possibly related PRs

  • PerryTS/perry#6610: Modifies the Windows build workflow extended here with targeted COFF deduplication coverage.

Suggested labels: tooling

Suggested reviewers: thehypnoo, andrewtdiz

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main Windows COFF deduplication change.
Description check ✅ Passed The description is mostly complete and covers the summary, linked issue, and validation, even if it doesn't mirror the template exactly.
Linked Issues check ✅ Passed The changes implement Windows COFF deduplication, tool discovery, bounded rebuilds, and a regression test as requested by #6626.
Out of Scope Changes check ✅ Passed The workflow, comment, and changelog updates all support the Windows deduplication fix and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/6626-windows-duplicate-symbols

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test.yml:
- Around line 875-877: Update the “Test COFF duplicate-symbol archive trimming”
step so it fails when the filtered Cargo test matches zero tests, rather than
accepting Cargo’s successful empty run. Preserve the existing
`coff_archive_dedup_drops_only_fully_provided_members` filter and
`perry-dev`/`perry` target, and assert from the test output or equivalent status
check that at least one test executed.

In `@crates/perry/src/commands/compile/strip_dedup.rs`:
- Around line 605-609: Update the Windows validation around provided_symbols and
staticlib_member_symbols so it distinguishes llvm-nm parsing failure from
legitimately empty symbols when nm_works is true but no stdlib_path,
runtime_path, or rlib was found. Report the COFF archive read error only for the
nm failure case, and provide a separate diagnostic for missing runtime/stdlib
libraries; preserve successful handling when symbols are empty for an explicitly
valid reason.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 120e4643-24c0-42b0-afa2-258884aef777

📥 Commits

Reviewing files that changed from the base of the PR and between 404c1c9 and 3654b51.

📒 Files selected for processing (6)
  • .github/workflows/test.yml
  • changelog.d/7085-windows-coff-dedup.md
  • crates/perry/src/commands/compile/link/build_and_run.rs
  • crates/perry/src/commands/compile/link/platform_cmd.rs
  • crates/perry/src/commands/compile/strip_dedup.rs
  • crates/perry/src/commands/compile/strip_dedup/stub_symbols.rs
💤 Files with no reviewable changes (1)
  • crates/perry/src/commands/compile/strip_dedup/stub_symbols.rs

Comment thread .github/workflows/test.yml
Comment thread crates/perry/src/commands/compile/strip_dedup.rs Outdated
Comment thread .github/workflows/test.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test.yml:
- Around line 875-885: Update the protected branch configuration to include the
windows-build status check as a required context, matching the existing job name
in test.yml. Leave the COFF regression test step unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 609d08b1-db3f-485e-89ae-359b306fab83

📥 Commits

Reviewing files that changed from the base of the PR and between 3654b51 and b2d31b5.

📒 Files selected for processing (2)
  • .github/workflows/test.yml
  • crates/perry/src/commands/compile/strip_dedup.rs

Comment on lines +875 to +885
- name: Test COFF duplicate-symbol archive trimming
shell: bash
run: |
set -o pipefail
cargo test --profile perry-dev -p perry --bin perry \
coff_archive_dedup_drops_only_fully_provided_members 2>&1 | tee test-output.log
grep -q 'test result: ok. 1 passed; 0 failed' test-output.log || {
echo "::error::expected COFF dedup test did not run exactly once"
exit 1
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files .github/workflows | sort

echo "== test.yml around referenced lines =="
if [ -f .github/workflows/test.yml ]; then
  nl -ba .github/workflows/test.yml | sed -n '840,900p'
else
  echo ".github/workflows/test.yml not found"
fi

echo "== job names in workflows =="
rg -n "^(  )+[A-Za-z0-9_-_]+\s*:|name:\s*(windows-build|.*windows.*|windows.*COFF|COFF duplicate|COFF dedup)" .github/workflows -g '*.yml' -g '*.yaml' || true

echo "== required status check references =="
rg -n "required_status_checks|windows-build|windows-build|branch protection|required contexts|required context|COFF|dedup|windows" .github README* . 2>/dev/null | head -200 || true

Repository: PerryTS/perry

Length of output: 879


🌐 Web query:

GitHub required status checks branch protection require checks before merging include jobs workflow syntax required_status_checks

💡 Result:

GitHub branch protection rules allow you to require specific status checks to pass before a pull request can be merged into a protected branch [1][2]. Core Concepts and Configuration: - Required Status Checks: These are configured under branch protection rules [1]. A check must have a successful, skipped, or neutral status to allow merging [2][3]. - Strict vs. Loose: - Strict: Enabled by the "Require branches to be up to date before merging" setting [2]. The head branch must be updated with the base branch before merging is permitted [2]. - Loose: This setting is disabled [2]. The head branch does not need to be up to date, which reduces the number of required builds but may lead to status check failures after merging if incompatible changes exist [2]. - Workflow Syntax: GitHub Actions workflows are defined in YAML [4]. While there is no specific required_status_checks key within a workflow file itself, individual jobs within a workflow act as status checks [4]. If a workflow is skipped (e.g., due to path/branch filtering or commit messages), its associated checks remain in a "Pending" state, which will block merging if those checks are marked as required [4][5]. API and Infrastructure as Code: - When using the GitHub REST API or tools like Terraform to manage branch protection, the required_status_checks object is used to define these requirements [6][7][8]. - The object includes [6][7][8]: - strict (boolean): Controls the "up to date" requirement [6][8]. - checks (array of objects): Specifies the required checks [6][7]. Each object contains a context (string) and an app_id (integer or null) to uniquely identify the check [6][8]. - contexts (array of strings): A deprecated field previously used for the same purpose [6][8]. Troubleshooting: - If a workflow condition causes a job to be skipped, the check will not report success, effectively blocking the merge [4][5]. To address this, ensure that all required checks are configured to run under the conditions present in the pull request, or maintain a secondary "dummy" workflow that always succeeds to satisfy the requirement when the primary workflow is skipped [5].

Citations:


🏁 Script executed:

#!/bin/bash
set -u

echo "== workflow files =="
git ls-files .github/workflows | sort

echo "== test.yml around referenced lines =="
if [ -f .github/workflows/test.yml ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/test.yml | sed -n '840,905p'
else
  echo ".github/workflows/test.yml not found"
fi

echo "== all workflow job names =="
awk '
  /^[[:space:]]*$|^\s*#|$0 ~ /^[[:space:]]+name:/ { next }
  /^\s{2}[A-Za-z0-9._-]+\s*:$/ {
    sub(/[[:space:]]:/, "", $2)
    print FILENAME ":" NR ": " $2
  }
' .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null | sort

echo "== focused search for windows-build and related comments =="
rg -n "windows-build|windows-build|windows-build|windows.*build|COFF|duplicate-symbol|duplicate_symbol|dedup_drops|required|branch protection|contexts|required status|branch_protection|branch-protection|protection" .github/workflows/test.yml .github/workflows/*.yml README* .github 2>/dev/null || true

Repository: PerryTS/perry

Length of output: 13331


Make windows-build a required branch-protection check.

The test.yml comment at .github/workflows/test.yml:914-915 explicitly says windows-build is not yet in branch protection’s required contexts, so this COFF regression check can fail without blocking a merge. Add windows-build as a required status check in the protected branch configuration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 875 - 885, Update the protected
branch configuration to include the windows-build status check as a required
context, matching the existing job name in test.yml. Leave the COFF regression
test step unchanged.

Source: Coding guidelines

@proggeramlug
proggeramlug merged commit c86835f into main Jul 30, 2026
8 checks passed
@proggeramlug
proggeramlug deleted the fix/6626-windows-duplicate-symbols branch July 30, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

windows-linker: bring evidence-based duplicate-symbol strip to Windows (stale-lib shadowing under /FORCE:MULTIPLE)

1 participant