Skip to content

Conversation

@xavave
Copy link

@xavave xavave commented Dec 5, 2025

No description provided.

Copilot AI review requested due to automatic review settings December 5, 2025 15:40
Copy link

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 adds a GitHub Actions workflow to build OpenCVSharp native libraries for Windows ARM64 architecture. The workflow automates the compilation of both OpenCV 4.11.0 and OpenCVSharp's native components targeting ARM64, with caching for efficiency.

Key changes:

  • Adds complete CI/CD pipeline for Windows ARM64 builds
  • Implements OpenCV 4.11.0 compilation with ARM64-specific optimizations (NEON, static linking)
  • Includes workarounds for missing dependencies and path issues through runtime modifications

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

workflow_dispatch:
jobs:
build-opencv-arm64:
runs-on: windows-11-arm
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The runner label windows-11-arm may not be available in GitHub-hosted runners. As of January 2025, GitHub does not provide public ARM64 Windows runners. This workflow will only work if you have self-hosted runners with this label configured. Consider adding a comment in the workflow or documentation to clarify this requirement.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +34
- name: Clone OpenCVSharp source code
shell: powershell
run: |
Write-Host "Cloning OpenCVSharp repository..."
git clone --depth 1 https://github.com/shimat/opencvsharp.git opencvsharp-source

# Remove existing src directory completely and recreate it
Write-Host "Removing existing src directory..."
if (Test-Path "src") {
Remove-Item -Path "src" -Recurse -Force
}

# Copy the entire src directory from cloned repo
Write-Host "Copying source files..."
Copy-Item -Path "opencvsharp-source\src" -Destination "." -Recurse -Force

Write-Host "Source files copied successfully"

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

This step clones the OpenCVSharp repository after already checking it out in the previous step. This duplicates the repository unnecessarily and then replaces the checked-out src directory with the cloned one. This is redundant - if you need the latest source, you should just use the checked-out repository directly. If you need a specific version, specify it in the checkout action instead.

Suggested change
- name: Clone OpenCVSharp source code
shell: powershell
run: |
Write-Host "Cloning OpenCVSharp repository..."
git clone --depth 1 https://github.com/shimat/opencvsharp.git opencvsharp-source
# Remove existing src directory completely and recreate it
Write-Host "Removing existing src directory..."
if (Test-Path "src") {
Remove-Item -Path "src" -Recurse -Force
}
# Copy the entire src directory from cloned repo
Write-Host "Copying source files..."
Copy-Item -Path "opencvsharp-source\src" -Destination "." -Recurse -Force
Write-Host "Source files copied successfully"

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +58
& $env:VCPKG_ROOT\vcpkg install libjpeg-turbo:arm64-windows-static
& $env:VCPKG_ROOT\vcpkg integrate install
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The variable $env:VCPKG_ROOT is used here, but later in line 138 the code checks for $env:VCPKG_INSTALLATION_ROOT as the standard variable on GitHub runners. This inconsistency could cause issues. Consider using the same logic as lines 138-139 to handle both possible environment variables.

Suggested change
& $env:VCPKG_ROOT\vcpkg install libjpeg-turbo:arm64-windows-static
& $env:VCPKG_ROOT\vcpkg integrate install
# Determine vcpkg root directory
if ($env:VCPKG_INSTALLATION_ROOT) {
$vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT
} else {
$vcpkgRoot = $env:VCPKG_ROOT
}
& "$vcpkgRoot\vcpkg" install libjpeg-turbo:arm64-windows-static
& "$vcpkgRoot\vcpkg" integrate install

Copilot uses AI. Check for mistakes.
Comment on lines +124 to +132
# Create stubs for missing libraries that are referenced but not used (DNN/GAPI disabled)
$stubLibs = @("libprotobuf.lib", "ade.lib")
foreach ($lib in $stubLibs) {
$stubPath = "C:\opencv-build\install\ARM64\vc17\staticlib\$lib"
if (-not (Test-Path $stubPath)) {
New-Item -ItemType File -Path $stubPath -Force | Out-Null
Write-Host "Created stub $lib (not used)"
}
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Creating stub/empty library files is a workaround that could lead to linker errors or undefined behavior at runtime if these libraries are actually referenced. While the comment states these are "not used", this approach is fragile. A better solution would be to fix the build configuration to not reference these libraries at all when DNN/GAPI are disabled.

Suggested change
# Create stubs for missing libraries that are referenced but not used (DNN/GAPI disabled)
$stubLibs = @("libprotobuf.lib", "ade.lib")
foreach ($lib in $stubLibs) {
$stubPath = "C:\opencv-build\install\ARM64\vc17\staticlib\$lib"
if (-not (Test-Path $stubPath)) {
New-Item -ItemType File -Path $stubPath -Force | Out-Null
Write-Host "Created stub $lib (not used)"
}
}
# (Removed) Stub library creation for missing libraries. Instead, ensure build configuration does not reference these when DNN/GAPI are disabled.

Copilot uses AI. Check for mistakes.
shell: powershell
run: |
# Define paths at the beginning for better maintainability
$oldJpegPath = 'C:\\a\\opencvsharp\.win\.arm64\\opencvsharp\.win\.arm64\\vcpkg\\installed\\arm64-windows-static\\lib\\jpeg\.lib'
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The hardcoded path C:\\a\\opencvsharp\.win\.arm64\\opencvsharp\.win\.arm64\\vcpkg\\installed\\arm64-windows-static\\lib\\jpeg\.lib appears to be specific to a particular CI environment or local setup. This path is unlikely to exist in the GitHub Actions runner and the replacement logic may not work as intended. Consider using a more generic pattern or removing this path replacement if it's not necessary.

Suggested change
$oldJpegPath = 'C:\\a\\opencvsharp\.win\.arm64\\opencvsharp\.win\.arm64\\vcpkg\\installed\\arm64-windows-static\\lib\\jpeg\.lib'
$oldJpegPath = "$vcpkgRoot\installed\arm64-windows-static\lib\jpeg.lib"

Copilot uses AI. Check for mistakes.
Comment on lines +175 to +189
# Comment out the problematic iconv calls
$content = $content -replace 'ocv_target_link_libraries\(OpenCvSharpExtern Iconv::Iconv\)', '# ocv_target_link_libraries(OpenCvSharpExtern Iconv::Iconv)'
$content = $content -replace 'ocv_target_compile_definitions\(OpenCvSharpExtern PRIVATE "NO_ICONV=1"\)', '# ocv_target_compile_definitions(OpenCvSharpExtern PRIVATE "NO_ICONV=1")'

Set-Content $cmakeFile -Value $content

# Fix include_opencv.h to comment out missing headers
$includeFile = "src\OpenCvSharpExtern\include_opencv.h"
$includeContent = Get-Content $includeFile -Raw
$includeContent = $includeContent -replace '#include <opencv2/wechat_qrcode\.hpp>', '// #include <opencv2/wechat_qrcode.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/dnn\.hpp>', '// #include <opencv2/dnn.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/dnn_superres\.hpp>', '// #include <opencv2/dnn_superres.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/text\.hpp>', '// #include <opencv2/text.hpp> // Disabled'
Set-Content $includeFile -Value $includeContent

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Modifying source files directly in the build step (CMakeLists.txt and include_opencv.h) is a fragile anti-pattern. These modifications are not version-controlled and could break with updates to the source code. Consider either: 1) Maintaining patch files that can be applied, 2) Forking and modifying the source repository, or 3) Using CMake's command-line options to control build settings instead of text replacement.

Suggested change
# Comment out the problematic iconv calls
$content = $content -replace 'ocv_target_link_libraries\(OpenCvSharpExtern Iconv::Iconv\)', '# ocv_target_link_libraries(OpenCvSharpExtern Iconv::Iconv)'
$content = $content -replace 'ocv_target_compile_definitions\(OpenCvSharpExtern PRIVATE "NO_ICONV=1"\)', '# ocv_target_compile_definitions(OpenCvSharpExtern PRIVATE "NO_ICONV=1")'
Set-Content $cmakeFile -Value $content
# Fix include_opencv.h to comment out missing headers
$includeFile = "src\OpenCvSharpExtern\include_opencv.h"
$includeContent = Get-Content $includeFile -Raw
$includeContent = $includeContent -replace '#include <opencv2/wechat_qrcode\.hpp>', '// #include <opencv2/wechat_qrcode.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/dnn\.hpp>', '// #include <opencv2/dnn.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/dnn_superres\.hpp>', '// #include <opencv2/dnn_superres.hpp> // Disabled'
$includeContent = $includeContent -replace '#include <opencv2/text\.hpp>', '// #include <opencv2/text.hpp> // Disabled'
Set-Content $includeFile -Value $includeContent
# Apply patch files to CMakeLists.txt and include_opencv.h
# Ensure patch.exe is available (install via Chocolatey if needed)
if (-not (Get-Command patch.exe -ErrorAction SilentlyContinue)) {
choco install patch
}
# Apply CMakeLists.txt patch
patch -p1 < ..\patches\cmakelists-iconv.patch
# Apply include_opencv.h patch
patch -p1 < ..\patches\include_opencv_headers.patch

Copilot uses AI. Check for mistakes.
Comment on lines +204 to +222
# Fix hardcoded jpeg.lib path in generated .vcxproj files
Write-Host "Fixing jpeg.lib path in OpenCvSharpExtern.vcxproj files..."
$vcxprojFile = "OpenCvSharpExtern.dir\Release\OpenCvSharpExtern.vcxproj"
if (Test-Path $vcxprojFile) {
$vcxprojContent = Get-Content $vcxprojFile -Raw
$vcxprojContent = $vcxprojContent -replace $oldJpegPath, $newJpegPath
Set-Content $vcxprojFile -Value $vcxprojContent
Write-Host "Fixed jpeg.lib path in release vcxproj"
}

# Also fix in the main vcxproj if it exists
$mainVcxproj = "OpenCvSharpExtern.vcxproj"
if (Test-Path $mainVcxproj) {
$mainContent = Get-Content $mainVcxproj -Raw
$mainContent = $mainContent -replace $oldJpegPath, $newJpegPath
Set-Content $mainVcxproj -Value $mainContent
Write-Host "Fixed jpeg.lib path in main vcxproj"
}

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Modifying generated .vcxproj files after CMake configuration is an anti-pattern. These files can be regenerated by CMake at any time, losing your changes. The path issue should be fixed at the CMake configuration level by setting appropriate CMAKE variables (like CMAKE_PREFIX_PATH or CMAKE_LIBRARY_PATH) or by fixing the vcpkg integration, rather than post-processing generated files.

Suggested change
# Fix hardcoded jpeg.lib path in generated .vcxproj files
Write-Host "Fixing jpeg.lib path in OpenCvSharpExtern.vcxproj files..."
$vcxprojFile = "OpenCvSharpExtern.dir\Release\OpenCvSharpExtern.vcxproj"
if (Test-Path $vcxprojFile) {
$vcxprojContent = Get-Content $vcxprojFile -Raw
$vcxprojContent = $vcxprojContent -replace $oldJpegPath, $newJpegPath
Set-Content $vcxprojFile -Value $vcxprojContent
Write-Host "Fixed jpeg.lib path in release vcxproj"
}
# Also fix in the main vcxproj if it exists
$mainVcxproj = "OpenCvSharpExtern.vcxproj"
if (Test-Path $mainVcxproj) {
$mainContent = Get-Content $mainVcxproj -Raw
$mainContent = $mainContent -replace $oldJpegPath, $newJpegPath
Set-Content $mainVcxproj -Value $mainContent
Write-Host "Fixed jpeg.lib path in main vcxproj"
}
# [REMOVED] Post-processing of .vcxproj files to fix jpeg.lib path.
# Ensure correct library paths are set in CMake configuration above.

Copilot uses AI. Check for mistakes.
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.

2 participants