Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,31 @@ From `namespace OpenCvSharp.Internal`, types in `namespace OpenCvSharp` are dire

See `src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h`, `src/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cs` for a complete example covering: factory, OutputArray methods, std::vector methods, nested Params struct with bool fields, and VectorOfVec6d.

## Repository structure

OpenCvSharp has three layers:

- **`src/OpenCvSharp/`** — managed C# wrapper (P/Invoke, types, extension methods). Target frameworks: `netstandard2.0`, `netstandard2.1`, `net8.0`. Always verify that any change is consistent across all three.
- **`src/OpenCvSharpExtern/`** — thin C++ bridge called by the C# side via P/Invoke.
- **`nuget/`** — NuGet packaging projects (runtime packages that bundle the native DLLs).

## Versioning and release process

See `docs/release-process.md` for the full release workflow.

**Key rule: do not edit version numbers in source files for routine releases.** The NuGet package version is passed via `-p:Version=...` at pack time in CI. `AssemblyVersion` and `FileVersion` are hardcoded to `4.0.0.0` in `src/Directory.Build.props` and must not be changed for patch or minor OpenCV upgrades — only bump the major component on a breaking API change or OpenCV major-version upgrade. `InformationalVersion` is set automatically by the SDK to the full NuGet version string.

## Native DLL loading (Windows)

`WindowsLibraryLoader` (`src/OpenCvSharp/Internal/PInvoke/WindowsLibraryLoader.cs`) handles native DLL loading on Windows for .NET Framework targets:

- Uses `AppContext.BaseDirectory` (not `Assembly.Location`) to avoid IL3000 warnings in AoT/single-file apps.
- For .NET Framework (net4x), looks for DLLs under `dll/x64/` relative to the base directory. The NuGet `.props` file copies DLLs there at build time.
- For .NET 5+, returns early — the .NET runtime handles native loading via the `runtimes/` folder layout.

The NuGet runtime packages (`nuget/OpenCvSharp4.runtime.win.*`) include a `.targets` file that suppresses the redundant copy NuGet's PackageReference pipeline would otherwise make to the output root for net4x consumers.

## Issue backlog

`docs/issue-backlog.md` tracks actionable issues identified from closed/stale GitHub issues. Update the checkboxes as items are resolved.

1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See `.github/copilot-instructions.md` for development instructions.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
2 changes: 1 addition & 1 deletion docs/issue-backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Check off items as they are resolved.

---

### [ ] #1704 — Assembly version reported as `0.0.0.0`
### [x] #1704 — Assembly version reported as `0.0.0.0`
Comment thread
shimat marked this conversation as resolved.
Resolved

- **State**: closed (stale)
- **URL**: https://github.com/shimat/opencvsharp/issues/1704
Expand Down
51 changes: 51 additions & 0 deletions docs/release-process.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Release Process

This document describes the steps required to publish a new version of OpenCvSharp.

---

## Version numbering

NuGet package versions follow the pattern `{opencv_version}.{YYYYMMDD}`, e.g. `4.13.0.20260530`. The `-beta` suffix is stripped by `OpenCvSharp.NupkgBetaRemover` at publish time.

The version is passed at pack time via `-p:Version=...` in CI. **No source file needs to be edited to change the version number.**

### Assembly versioning policy

Managed assembly attributes are set as follows (see `src/Directory.Build.props`):

| Attribute | Value | Rationale |
|---|---|---|
| `AssemblyVersion` | `4.0.0.0` (major-pinned, hardcoded) | Changing this on every release is a breaking change for .NET Framework consumers of the strong-named assembly — they would need binding redirects in `app.config`. Only bump the major component when there is a breaking API change. |
| `FileVersion` | `4.0.0.0` (hardcoded) | The date-based 4th component (e.g. `20260530`) exceeds the 65535 per-component limit of the Windows FILEVERSION PE resource. |
| `InformationalVersion` | Set automatically by the .NET SDK to `$(Version)` | This is the human-readable version visible in Windows file properties ("Product version") and most tooling. It tracks the NuGet version correctly with no manual action needed. |

### When to bump `AssemblyVersion`

- **Patch / minor OpenCV update** (e.g. 4.13.0 → 4.13.1, or 4.13 → 4.14): **do nothing**. The assembly version stays at `4.0.0.0`.
- **OpenCV major version bump** (e.g. 4.x → 5.x): update `AssemblyVersion` and `FileVersion` in `src/Directory.Build.props` to `5.0.0.0`. Be aware this is a breaking change for .NET Framework consumers.
- **Breaking API change in the C# wrapper** (rare): same as above — bump the major component.

---

## CI workflow

Releases are produced by running the following workflows in order:

1. **`windows.yml`** — builds `OpenCvSharpExtern.dll` (full and slim), runs tests, packs NuGet packages with a `-beta` version suffix.
2. **`linux-arm64.yml`** — builds the Linux ARM64 native library.
3. **`manylinux.yml`** — builds the Linux x64 native library.
4. **`wasm.yml`** — builds the WASM native library.
5. **`publish_nuget.yml`** — collects all artifacts, strips the `-beta` suffix via `OpenCvSharp.NupkgBetaRemover`, validates the package set, and pushes to NuGet.org.

The `OPENCV_VERSION` environment variable in `windows.yml` controls the OpenCV version embedded in the package version string. Update it there when upgrading OpenCV.

---

## Upgrading OpenCV

1. Update the `opencv` and `opencv_contrib` submodules to the new tag.
2. Update `OPENCV_VERSION` in `.github/workflows/windows.yml`.
3. Update the ffmpeg DLL filename references in `nuget/OpenCvSharp4.runtime.win.props` and `nuget/OpenCvSharp4.runtime.win.csproj` if the ffmpeg DLL name changed (e.g. `opencv_videoio_ffmpeg4130_64.dll` → `opencv_videoio_ffmpeg4140_64.dll`).
4. Run the full CI pipeline and verify all tests pass.
5. `AssemblyVersion` does **not** need to be changed for a minor/patch OpenCV upgrade.
3 changes: 3 additions & 0 deletions nuget/OpenCvSharp4.runtime.win.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<None Include="OpenCvSharp4.runtime.win.props" Pack="true" PackagePath="build/netstandard" />
<None Include="OpenCvSharp4.runtime.win.props" Pack="true" PackagePath="build/netcoreapp" />
<None Include="OpenCvSharp4.runtime.win.props" Pack="true" PackagePath="build/net8.0" />
<None Include="OpenCvSharp4.runtime.win.targets" Pack="true" PackagePath="build/netstandard" />
<None Include="OpenCvSharp4.runtime.win.targets" Pack="true" PackagePath="build/netcoreapp" />
<None Include="OpenCvSharp4.runtime.win.targets" Pack="true" PackagePath="build/net8.0" />
<None Include="icon/opencvsharp.png" Pack="true" PackagePath="" />
<None Include="README.runtime.md" Pack="true" PackagePath="" />
</ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions nuget/OpenCvSharp4.runtime.win.slim.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<None Include="OpenCvSharp4.runtime.win.slim.props" Pack="true" PackagePath="build/netstandard" />
<None Include="OpenCvSharp4.runtime.win.slim.props" Pack="true" PackagePath="build/netcoreapp" />
<None Include="OpenCvSharp4.runtime.win.slim.props" Pack="true" PackagePath="build/net8.0" />
<None Include="OpenCvSharp4.runtime.win.slim.targets" Pack="true" PackagePath="build/netstandard" />
<None Include="OpenCvSharp4.runtime.win.slim.targets" Pack="true" PackagePath="build/netcoreapp" />
<None Include="OpenCvSharp4.runtime.win.slim.targets" Pack="true" PackagePath="build/net8.0" />
<None Include="icon/opencvsharp.png" Pack="true" PackagePath="" />
<None Include="README.runtime.md" Pack="true" PackagePath="" />
</ItemGroup>
Expand Down
24 changes: 24 additions & 0 deletions nuget/OpenCvSharp4.runtime.win.slim.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
For .NET Framework (net4x) targets using PackageReference, NuGet's build pipeline automatically
copies runtimes/win-x64/native/ assets to the output root directory. However, the companion
.props file already places these DLLs under dll/x64/, which is where WindowsLibraryLoader looks
at runtime. The root copies are therefore redundant and bloat the output directory.

This target removes the package's native assets from RuntimeCopyLocalItems — the item group
populated by ResolvePackageAssets — so NuGet does not copy them to the output root.
The dll/x64/ placement from the .props file is unaffected.

Note: RuntimeCopyLocalItems is only present in SDK-style projects using PackageReference.
Old-style (packages.config) projects do not process runtimes/ assets at all, so this target
has no effect there (which is fine — no duplicate exists in that case either).
-->
<Target Name="OpenCvSharp4RuntimeWinSlim_RemoveRootNativeAssets"
AfterTargets="ResolvePackageAssets"
Condition="$(TargetFramework.StartsWith('net4')) Or $(TargetFrameworkVersion.StartsWith('v4'))">
<ItemGroup>
<RuntimeCopyLocalItems Remove="@(RuntimeCopyLocalItems)"
Condition="'%(NuGetPackageId)' == 'OpenCvSharp4.runtime.win.slim'" />
</ItemGroup>
</Target>
</Project>
24 changes: 24 additions & 0 deletions nuget/OpenCvSharp4.runtime.win.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
For .NET Framework (net4x) targets using PackageReference, NuGet's build pipeline automatically
copies runtimes/win-x64/native/ assets to the output root directory. However, the companion
.props file already places these DLLs under dll/x64/, which is where WindowsLibraryLoader looks
at runtime. The root copies are therefore redundant and bloat the output directory.

This target removes the package's native assets from RuntimeCopyLocalItems — the item group
populated by ResolvePackageAssets — so NuGet does not copy them to the output root.
The dll/x64/ placement from the .props file is unaffected.

Note: RuntimeCopyLocalItems is only present in SDK-style projects using PackageReference.
Old-style (packages.config) projects do not process runtimes/ assets at all, so this target
has no effect there (which is fine — no duplicate exists in that case either).
-->
<Target Name="OpenCvSharp4RuntimeWin_RemoveRootNativeAssets"
AfterTargets="ResolvePackageAssets"
Condition="$(TargetFramework.StartsWith('net4')) Or $(TargetFrameworkVersion.StartsWith('v4'))">
<ItemGroup>
<RuntimeCopyLocalItems Remove="@(RuntimeCopyLocalItems)"
Condition="'%(NuGetPackageId)' == 'OpenCvSharp4.runtime.win'" />
</ItemGroup>
</Target>
</Project>
Loading