Skip to content

Fix duplicate native DLLs in net4x output directory - #1886

Merged
shimat merged 6 commits into
mainfrom
fix/1765-dll-double-copy
May 30, 2026
Merged

shimat merged 6 commits into
mainfrom
fix/1765-dll-double-copy

Conversation

@shimat

@shimat shimat commented May 30, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1765

Problem

When a .NET Framework (net4x) project references OpenCvSharp4.runtime.win or OpenCvSharp4.runtime.win.slim via PackageReference, two separate mechanisms both copy the native DLLs into the build output:

  1. The .props file (imported via build/netstandard/) copies them to dll/x64/, where WindowsLibraryLoader looks at runtime.
  2. NuGet's PackageReference pipeline also copies runtimes/win-x64/native/ assets to the output root as part of its native asset resolution.

The root copies are never loaded by OpenCvSharp and serve no purpose, but they inflate the output directory and can interfere with deployment tooling that packages everything in the output folder.

Fix

Add a .targets file for each runtime package (OpenCvSharp4.runtime.win and OpenCvSharp4.runtime.win.slim) that runs after ResolvePackageAssets and removes the package's entries from RuntimeCopyLocalItems when targeting net4x. This suppresses the redundant root copy. The dll/x64/ placement from the .props file is unaffected, so runtime behavior is unchanged.

This fix only applies to SDK-style projects using PackageReference. Old-style packages.config projects do not process runtimes/ assets automatically and have no duplicate in the first place, so the target is a no-op for them.

Summary by CodeRabbit

  • Bug Fixes

    • Closed two backlog issues (assembly version reporting and duplicate native DLL copying).
  • Chores

    • Updated NuGet packaging to include additional build targets and prevent certain native runtime files from being copied to the output root for affected frameworks.
  • Documentation

    • Added release process and repository/Copilot guidance; added a pointer in contributor guidance.

Review Change Stack

@shimat shimat self-assigned this May 30, 2026
@coderabbitai

coderabbitai Bot commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e806be92-b686-4782-94a2-1142dd8539b9

📥 Commits

Reviewing files that changed from the base of the PR and between b6b15c0 and 7301dfe.

📒 Files selected for processing (1)
  • CLAUDE.md

📝 Walkthrough

Walkthrough

Adds conditional MSBuild .targets that remove package native assets from RuntimeCopyLocalItems for .NET Framework, packages those targets into NuGet builds for multiple TFMs, updates release/contributor documentation, and marks issues #1704 and #1765 resolved in the backlog.

Changes

Native DLL Copy Prevention

Layer / File(s) Summary
MSBuild targets for native asset removal
nuget/OpenCvSharp4.runtime.win.targets, nuget/OpenCvSharp4.runtime.win.slim.targets
Two new .targets files define conditional targets that execute after ResolvePackageAssets for .NET Framework (net4*/v4*) and remove package native assets from RuntimeCopyLocalItems to avoid root-level duplication.
NuGet package configuration for targets files
nuget/OpenCvSharp4.runtime.win.csproj, nuget/OpenCvSharp4.runtime.win.slim.csproj
Both NuGet project files are updated to include the new .targets files under build/netstandard, build/netcoreapp, and build/net8.0, ensuring the targets are available to package consumers.
Release process and contributor guidance
docs/release-process.md, .github/copilot-instructions.md, CLAUDE.md
Adds a release-process document describing versioning and CI release steps, Copilot contributor instructions covering repo structure and native DLL loading, and a pointer in CLAUDE.md.
Issue backlog update
docs/issue-backlog.md
Checklist entries for issues #1704 and #1765 were toggled from unchecked to checked.

Sequence Diagram(s)

sequenceDiagram
  participant ResolvePackageAssets
  participant OpenCvSharp4RuntimeWin_RemoveRootNativeAssets
  participant OpenCvSharp4RuntimeWinSlim_RemoveRootNativeAssets
  participant RuntimeCopyLocalItems

  ResolvePackageAssets->>OpenCvSharp4RuntimeWin_RemoveRootNativeAssets: AfterTargets invoke (net4*/v4*)
  ResolvePackageAssets->>OpenCvSharp4RuntimeWinSlim_RemoveRootNativeAssets: AfterTargets invoke (net4*/v4*)
  OpenCvSharp4RuntimeWin_RemoveRootNativeAssets->>RuntimeCopyLocalItems: remove OpenCvSharp4.runtime.win entries
  OpenCvSharp4RuntimeWinSlim_RemoveRootNativeAssets->>RuntimeCopyLocalItems: remove OpenCvSharp4.runtime.win.slim entries
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • shimat/opencvsharp#1816: Related to Windows slim runtime packaging/workflow and the slim package behavior that this PR modifies.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes (core fixes) are in-scope. However, documentation additions (.github/copilot-instructions.md, CLAUDE.md, docs/release-process.md, docs/issue-backlog.md) are beyond the scope of fixing issue #1765 and appear to be preparatory or auxiliary additions. Remove or separate documentation-only changes (copilot instructions, release process docs, backlog updates) into a dedicated PR focused on documentation; keep this PR focused on the technical fix for #1765.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change—fixing duplicate native DLLs in net4x output by adding .targets files to suppress redundant NuGet copies.
Linked Issues check ✅ Passed The PR fully addresses issue #1765 by adding .targets files that prevent duplicate native DLL copies to the output root for net4x SDK-style projects using PackageReference.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1765-dll-double-copy

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 `@docs/issue-backlog.md`:
- Line 22: Update the resolved checklist entry that currently references "`#1704`"
to the correct issue number "`#1765`" (the duplicate native DLLs fix) in the
docs/issue-backlog.md checklist item that reads "### [x] `#1704` — Assembly
version reported as `0.0.0.0`"; if you intentionally meant to mark `#1704` as
resolved, replace the checklist text to explain why `#1704` is closed by this PR
instead of changing the issue number.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 20a3b379-448e-4d3e-b108-4fc19d76867e

📥 Commits

Reviewing files that changed from the base of the PR and between aee67d6 and 0253b53.

📒 Files selected for processing (5)
  • docs/issue-backlog.md
  • nuget/OpenCvSharp4.runtime.win.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.targets
  • nuget/OpenCvSharp4.runtime.win.targets

Comment thread docs/issue-backlog.md
shimat and others added 4 commits May 30, 2026 20:52
When a net4x project references OpenCvSharp4.runtime.win via PackageReference,
two separate mechanisms both copy the native DLLs to the build output:

1. The .props file (at build/netstandard/) copies them to dll/x64/, which is
   where WindowsLibraryLoader looks at runtime.
2. NuGet''s PackageReference pipeline also copies runtimes/win-x64/native/
   assets to the output root, which are never loaded by OpenCvSharp.

Add a .targets file for each runtime package (full and slim) that removes the
package''s entries from RuntimeCopyLocalItems after ResolvePackageAssets runs,
suppressing the redundant root copy for net4x targets. The dll/x64/ placement
from the .props file is unaffected, so runtime behavior is unchanged.

This fix applies only to SDK-style projects using PackageReference. Old-style
packages.config projects do not process runtimes/ assets automatically, so
there is no duplicate in that case and the target has no effect.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
docs/release-process.md: document the release workflow and assembly
versioning policy (when to bump AssemblyVersion, how the NuGet version
flows through CI, steps for upgrading OpenCV).

CLAUDE.md: AI-facing instructions covering repository structure, the
versioning convention, WindowsLibraryLoader behavior, and NuGet runtime
package layout.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Merge the repository overview, versioning policy, WindowsLibraryLoader
notes, and issue backlog pointer from CLAUDE.md into the existing
.github/copilot-instructions.md to avoid maintaining two parallel files.
Remove CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude Code reads CLAUDE.md automatically at session start.
A one-line pointer avoids duplicating content while keeping
.github/copilot-instructions.md as the single source of truth.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@shimat
shimat force-pushed the fix/1765-dll-double-copy branch from a5685e7 to dbed22b Compare May 30, 2026 11:53
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/release-process.md (1)

1-52: ⚠️ Potential issue | 🟠 Major

Fix UTF-8 with BOM encoding for docs/release-process.md

  • docs/release-process.md is missing the UTF-8 BOM (file starts with 23 20 52 = # R), so it violates the UTF-8 BOM requirement for .md files.
  • Re-save it as UTF-8 with BOM:
$enc = New-Object System.Text.UTF8Encoding $true
$content = [System.IO.File]::ReadAllText("docs\release-process.md", [System.Text.Encoding]::UTF8)
[System.IO.File]::WriteAllText("docs\release-process.md", $content, $enc)
🤖 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 `@docs/release-process.md` around lines 1 - 52, docs/release-process.md is
missing the UTF‑8 BOM; re-save that file with UTF‑8 BOM encoding so it meets the
.md BOM requirement (e.g. use the provided PowerShell snippet that creates a
UTF8Encoding(true) and writes the file back, or re-save via your editor/IDE with
“UTF-8 with BOM”); ensure the file start bytes include the BOM (EF BB BF) before
the existing content.
🤖 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 `@CLAUDE.md`:
- Line 1: CLAUDE.md currently lacks the UTF‑8 BOM (it starts with the bytes for
"See"), so re-save the file using UTF‑8 with BOM encoding; open CLAUDE.md and
change the file encoding to "UTF-8 with BOM" (or run a script that reads the
file as UTF‑8 and writes it back using an UTF8Encoding instance with
emitBOM=true) so the file begins with EF BB BF while preserving the existing
content.

---

Outside diff comments:
In `@docs/release-process.md`:
- Around line 1-52: docs/release-process.md is missing the UTF‑8 BOM; re-save
that file with UTF‑8 BOM encoding so it meets the .md BOM requirement (e.g. use
the provided PowerShell snippet that creates a UTF8Encoding(true) and writes the
file back, or re-save via your editor/IDE with “UTF-8 with BOM”); ensure the
file start bytes include the BOM (EF BB BF) before the existing content.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ad6b4999-0d29-41b3-9d2f-784d87b2ff0e

📥 Commits

Reviewing files that changed from the base of the PR and between a5685e7 and dbed22b.

📒 Files selected for processing (8)
  • .github/copilot-instructions.md
  • CLAUDE.md
  • docs/issue-backlog.md
  • docs/release-process.md
  • nuget/OpenCvSharp4.runtime.win.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.targets
  • nuget/OpenCvSharp4.runtime.win.targets
🚧 Files skipped from review as they are similar to previous changes (5)
  • docs/issue-backlog.md
  • nuget/OpenCvSharp4.runtime.win.slim.csproj
  • nuget/OpenCvSharp4.runtime.win.slim.targets
  • nuget/OpenCvSharp4.runtime.win.csproj
  • nuget/OpenCvSharp4.runtime.win.targets

Comment thread CLAUDE.md Outdated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

Repository owner deleted a comment from coderabbitai Bot May 30, 2026
@shimat
shimat merged commit dcc308b into main May 30, 2026
10 checks passed
@shimat
shimat deleted the fix/1765-dll-double-copy branch May 30, 2026 12:45
@shimat shimat added the bug Confirmed defect in OpenCvSharp label Jul 25, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Jul 25, 2026
4 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Confirmed defect in OpenCvSharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native DLLs are copied twice

1 participant