fix: critical zero-copy and format conversion bugs #583
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Windows Build | |
| # This workflow builds the project on Windows with multiple compilers: | |
| # - build-vs2022: Uses Visual Studio 2022 (stable) | |
| # - build-vs2026: Uses Visual Studio 2026 (when available on GitHub runners, skips gracefully if not) | |
| # - build-mingw: Uses MinGW-w64 (latest version) | |
| # All jobs test Debug/Release builds with static/shared library configurations. | |
| on: | |
| push: | |
| branches: [ main, ci_test ] | |
| pull_request: | |
| branches: [ main, ci_test ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-vs2022: | |
| name: Windows Build VS2022 (${{ matrix.config }}-${{ matrix.library_type }}) | |
| runs-on: windows-latest | |
| strategy: | |
| matrix: | |
| config: [Debug, Release] | |
| library_type: [static, shared] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Visual Studio environment | |
| uses: microsoft/setup-msbuild@v1.1 | |
| # Cache CMake build directory for Windows | |
| - name: Setup CMake build cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeFiles | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeCache.txt | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/**/*.obj | |
| key: ${{ runner.os }}-msvc-${{ matrix.config }}-${{ matrix.library_type }}-${{ hashFiles('CMakeLists.txt', 'src/**', 'include/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-msvc-${{ matrix.config }}-${{ matrix.library_type }}- | |
| ${{ runner.os }}-msvc-${{ matrix.config }}- | |
| - name: Configure CMake | |
| run: | | |
| $SHARED_FLAG = "" | |
| if ("${{ matrix.library_type }}" -eq "shared") { | |
| $SHARED_FLAG = "-DCCAP_BUILD_SHARED=ON" | |
| Write-Host "Configuring Windows build ${{ matrix.config }} - SHARED LIBRARY (DLL)" | |
| } else { | |
| Write-Host "Configuring Windows build ${{ matrix.config }} - STATIC LIBRARY" | |
| } | |
| New-Item -ItemType Directory -Force -Path "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cmake ../.. -G "Visual Studio 17 2022" -A x64 -DCCAP_BUILD_TESTS=ON -DCCAP_BUILD_CLI=ON $SHARED_FLAG | |
| - name: Build | |
| run: | | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cmake --build . --config ${{ matrix.config }} --parallel | |
| - name: Verify library type | |
| shell: bash | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }} | |
| run: | | |
| echo "Checking built libraries:" | |
| ls -la | grep -E "ccap" || echo "No ccap libraries found" | |
| # Verify library type | |
| # Debug versions have 'd' suffix, Release versions don't | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| LIB_BASENAME="ccapd" | |
| DLL_NAME="ccapd.dll" | |
| else | |
| LIB_BASENAME="ccap" | |
| DLL_NAME="ccap.dll" | |
| fi | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| if [ -f "$DLL_NAME" ]; then | |
| echo "✓ Windows shared library $DLL_NAME successfully built" | |
| # Check if import library exists | |
| if [ -f "${LIB_BASENAME}.lib" ]; then | |
| echo "✓ Windows import library ${LIB_BASENAME}.lib also created" | |
| fi | |
| else | |
| echo "✗ Windows shared library $DLL_NAME not found" | |
| exit 1 | |
| fi | |
| else | |
| if [ -f "${LIB_BASENAME}.lib" ]; then | |
| echo "✓ Windows static library ${LIB_BASENAME}.lib successfully built" | |
| else | |
| echo "✗ Windows static library ${LIB_BASENAME}.lib not found" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Test shared library linking (Windows) | |
| if: matrix.library_type == 'shared' | |
| shell: bash | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }} | |
| run: | | |
| echo "Testing Windows shared library linking..." | |
| # Create a simple test program | |
| cat > test_shared.cpp << 'EOF' | |
| #include "ccap_c.h" | |
| #include <stdio.h> | |
| int main() { | |
| const char* version = ccap_get_version(); | |
| printf("Library version: %s\n", version ? version : "unknown"); | |
| CcapProvider* provider = ccap_provider_create(); | |
| if (provider) { | |
| printf("Provider created successfully\n"); | |
| ccap_provider_destroy(provider); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| EOF | |
| # Find Visual Studio compiler | |
| VCVARS_PATH=$(find "/c/Program Files/Microsoft Visual Studio" -name "vcvars64.bat" 2>/dev/null | head -n1) | |
| if [ -z "$VCVARS_PATH" ]; then | |
| VCVARS_PATH=$(find "/c/Program Files (x86)/Microsoft Visual Studio" -name "vcvars64.bat" 2>/dev/null | head -n1) | |
| fi | |
| if [ -n "$VCVARS_PATH" ]; then | |
| echo "Using Visual Studio environment from: $VCVARS_PATH" | |
| # Convert path for cmd | |
| VCVARS_WIN_PATH=$(echo "$VCVARS_PATH" | sed 's|/c/|C:/|g' | sed 's|/|\\|g') | |
| # Determine library names based on config | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| LIB_NAME="ccapd.lib" | |
| DLL_NAME="ccapd.dll" | |
| else | |
| LIB_NAME="ccap.lib" | |
| DLL_NAME="ccap.dll" | |
| fi | |
| # Create a temporary batch file to avoid quote escaping issues | |
| cat > compile_test.bat << EOF | |
| @echo off | |
| call "$VCVARS_WIN_PATH" | |
| set "INCLUDE_DIR=%GITHUB_WORKSPACE%\\include" | |
| if not exist "%INCLUDE_DIR%" ( | |
| echo Include directory not found: %INCLUDE_DIR% | |
| exit /b 1 | |
| ) | |
| cl /I"%INCLUDE_DIR%" test_shared.cpp $LIB_NAME /Fe:test_shared.exe | |
| EOF | |
| # Execute the batch file | |
| cmd //c compile_test.bat | |
| # Ensure DLL is available beside the test executable | |
| if [ ! -f "./$DLL_NAME" ]; then | |
| DLL_PATH=$(find .. -name "$DLL_NAME" -print -quit) | |
| if [ -z "$DLL_PATH" ]; then | |
| echo "✗ Windows shared library $DLL_NAME not found for runtime" | |
| exit 1 | |
| fi | |
| cp "$DLL_PATH" . | |
| fi | |
| ./test_shared.exe | |
| echo "✓ Windows shared library linking test passed" | |
| else | |
| echo "⚠ Visual Studio compiler not found, skipping link test" | |
| fi | |
| - name: Run Unit Tests | |
| shell: bash | |
| run: | | |
| # Create symbolic links to make test script work with new build directory structure | |
| mkdir -p build/tests | |
| # Create symbolic link for the config directory | |
| if [ ! -L "build/${{ matrix.config }}" ]; then | |
| ln -sf "${{ matrix.config }}-${{ matrix.library_type }}" "build/${{ matrix.config }}" | |
| fi | |
| # Create symbolic link for the tests directory to match expected path structure | |
| if [ ! -L "build/tests/${{ matrix.config }}" ]; then | |
| ln -sf "../${{ matrix.config }}-${{ matrix.library_type }}/tests/${{ matrix.config }}" "build/tests/${{ matrix.config }}" | |
| fi | |
| cd scripts | |
| if [ "${{ matrix.config }}" == "Debug" ]; then | |
| # Set library path for shared library tests | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| export PATH="$PWD/../build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}:$PATH" | |
| fi | |
| ./run_tests.sh --functional --skip-build | |
| else | |
| # Set library path for shared library tests | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| export PATH="$PWD/../build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}:$PATH" | |
| fi | |
| ./run_tests.sh --performance --skip-build | |
| # Run video file playback tests (Release only) | |
| ./run_tests.sh --video --skip-build | |
| fi | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ccap-windows-vs2022-${{ matrix.config }}-${{ matrix.library_type }} | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/ccap*.* | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/0-print_camera.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/1-minimal_example.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/2-capture_grab.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/3-capture_callback.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/*_results.xml | |
| if-no-files-found: error | |
| build-vs2026: | |
| name: Windows Build VS2026 (${{ matrix.config }}-${{ matrix.library_type }}) | |
| runs-on: windows-latest | |
| strategy: | |
| matrix: | |
| config: [Debug, Release] | |
| library_type: [static, shared] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check for Visual Studio 2026 | |
| id: check-vs2026 | |
| shell: pwsh | |
| run: | | |
| Write-Host "Checking for Visual Studio 2026 on this runner..." | |
| # Use vswhere to check for VS2026 installation | |
| $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" | |
| # Check for VS2026 installation (version 18.x) | |
| $vs2026 = & $vswhere -version "[18.0,19.0)" -property installationPath 2>$null | |
| # Also check if v144 toolset exists in any VS installation | |
| $vsInstalls = & $vswhere -all -property installationPath 2>$null | |
| $v144Found = $false | |
| foreach ($install in $vsInstalls) { | |
| $v144Path = Join-Path $install "MSBuild\Microsoft\VC\v144" | |
| if (Test-Path $v144Path) { | |
| $v144Found = $true | |
| Write-Host "✓ v144 toolset (VS2026) found at: $v144Path" | |
| break | |
| } | |
| } | |
| if ($vs2026) { | |
| echo "VS_2026_AVAILABLE=true" >> $env:GITHUB_OUTPUT | |
| Write-Host "✓ Visual Studio 2026 is installed at: $vs2026" | |
| } elseif ($v144Found) { | |
| echo "VS_2026_AVAILABLE=true" >> $env:GITHUB_OUTPUT | |
| Write-Host "✓ Visual Studio 2026 v144 toolset is available" | |
| } else { | |
| echo "VS_2026_AVAILABLE=false" >> $env:GITHUB_OUTPUT | |
| Write-Host "ℹ Visual Studio 2026 (v144 toolset) is not available on this GitHub runner yet." | |
| Write-Host "" | |
| Write-Host "=== Available Visual Studio Installations (via vswhere) ===" | |
| & $vswhere -all -format text | |
| Write-Host "" | |
| Write-Host "⏭ Skipping VS2026 build - this job will complete successfully without running the build." | |
| Write-Host "Once GitHub adds VS2026 to their runners, this job will automatically start building." | |
| } | |
| - name: Setup latest CMake | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| # Use @latest to ensure CMake 3.31+ is available, which is required for VS 2026 support | |
| uses: lukka/get-cmake@latest | |
| # Cache CMake build directory for VS2026 | |
| - name: Setup CMake build cache | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeFiles | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeCache.txt | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/**/*.obj | |
| key: ${{ runner.os }}-vs2026-${{ matrix.config }}-${{ matrix.library_type }}-${{ hashFiles('CMakeLists.txt', 'src/**', 'include/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-vs2026-${{ matrix.config }}-${{ matrix.library_type }}- | |
| ${{ runner.os }}-vs2026-${{ matrix.config }}- | |
| - name: Configure CMake with VS2026 | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| run: | | |
| $SHARED_FLAG = "" | |
| if ("${{ matrix.library_type }}" -eq "shared") { | |
| $SHARED_FLAG = "-DCCAP_BUILD_SHARED=ON" | |
| Write-Host "Configuring Windows build ${{ matrix.config }} with VS2026 - SHARED LIBRARY (DLL)" | |
| } else { | |
| Write-Host "Configuring Windows build ${{ matrix.config }} with VS2026 - STATIC LIBRARY" | |
| } | |
| # Check CMake version | |
| cmake --version | |
| mkdir -p "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| # Use Visual Studio 18 2026 generator with v144 toolset | |
| Write-Host "Attempting to use Visual Studio 18 2026 generator..." | |
| cmake ../.. -G "Visual Studio 18 2026" -A x64 -T v144 -DCCAP_BUILD_TESTS=ON $SHARED_FLAG | |
| if ($LASTEXITCODE -ne 0) { | |
| Write-Host "Visual Studio 18 2026 generator not available, trying alternative with v144 toolset..." | |
| cmake ../.. -A x64 -T v144 -DCCAP_BUILD_TESTS=ON $SHARED_FLAG | |
| } | |
| - name: Build | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| run: | | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cmake --build . --config ${{ matrix.config }} --parallel | |
| - name: Verify library type | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| shell: bash | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }} | |
| run: | | |
| echo "Checking built libraries:" | |
| ls -la | grep -E "ccap" || echo "No ccap libraries found" | |
| # Verify library type | |
| # Debug versions have 'd' suffix, Release versions don't | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| LIB_BASENAME="ccapd" | |
| DLL_NAME="ccapd.dll" | |
| else | |
| LIB_BASENAME="ccap" | |
| DLL_NAME="ccap.dll" | |
| fi | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| if [ -f "$DLL_NAME" ]; then | |
| echo "✓ Windows shared library $DLL_NAME successfully built with VS2026" | |
| # Check if import library exists | |
| if [ -f "${LIB_BASENAME}.lib" ]; then | |
| echo "✓ Windows import library ${LIB_BASENAME}.lib also created" | |
| fi | |
| else | |
| echo "✗ Windows shared library $DLL_NAME not found" | |
| exit 1 | |
| fi | |
| else | |
| if [ -f "${LIB_BASENAME}.lib" ]; then | |
| echo "✓ Windows static library ${LIB_BASENAME}.lib successfully built with VS2026" | |
| else | |
| echo "✗ Windows static library ${LIB_BASENAME}.lib not found" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Test shared library linking (Windows VS2026) | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' && matrix.library_type == 'shared' | |
| shell: bash | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }} | |
| run: | | |
| echo "Testing Windows shared library linking with VS2026..." | |
| # Create a simple test program | |
| cat > test_shared.cpp << 'EOF' | |
| #include "ccap_c.h" | |
| #include <stdio.h> | |
| int main() { | |
| const char* version = ccap_get_version(); | |
| printf("Library version: %s\n", version ? version : "unknown"); | |
| CcapProvider* provider = ccap_provider_create(); | |
| if (provider) { | |
| printf("Provider created successfully\n"); | |
| ccap_provider_destroy(provider); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| EOF | |
| # Find Visual Studio 2026 compiler | |
| VCVARS_PATH=$(find "/c/Program Files/Microsoft Visual Studio/2026" -name "vcvars64.bat" 2>/dev/null | head -n1) | |
| if [ -n "$VCVARS_PATH" ]; then | |
| echo "Using Visual Studio 2026 environment from: $VCVARS_PATH" | |
| # Convert path for cmd | |
| VCVARS_WIN_PATH=$(echo "$VCVARS_PATH" | sed 's|/c/|C:/|g' | sed 's|/|\\|g') | |
| # Determine library names based on config | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| LIB_NAME="ccapd.lib" | |
| DLL_NAME="ccapd.dll" | |
| else | |
| LIB_NAME="ccap.lib" | |
| DLL_NAME="ccap.dll" | |
| fi | |
| # Create a temporary batch file to avoid quote escaping issues | |
| cat > compile_test.bat << EOF | |
| @echo off | |
| call "$VCVARS_WIN_PATH" | |
| set "INCLUDE_DIR=%GITHUB_WORKSPACE%\\include" | |
| if not exist "%INCLUDE_DIR%" ( | |
| echo Include directory not found: %INCLUDE_DIR% | |
| exit /b 1 | |
| ) | |
| cl /I"%INCLUDE_DIR%" test_shared.cpp $LIB_NAME /Fe:test_shared.exe | |
| EOF | |
| # Execute the batch file | |
| cmd //c compile_test.bat | |
| # Ensure DLL is available beside the test executable | |
| if [ ! -f "./$DLL_NAME" ]; then | |
| DLL_PATH=$(find .. -name "$DLL_NAME" -print -quit) | |
| if [ -z "$DLL_PATH" ]; then | |
| echo "✗ Windows shared library $DLL_NAME not found for runtime" | |
| exit 1 | |
| fi | |
| cp "$DLL_PATH" . | |
| fi | |
| ./test_shared.exe | |
| echo "✓ Windows shared library linking test with VS2026 passed" | |
| else | |
| echo "⚠ Visual Studio 2026 compiler not found, skipping link test" | |
| fi | |
| - name: Run Unit Tests | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| shell: bash | |
| run: | | |
| # Create symbolic links to make test script work with new build directory structure | |
| mkdir -p build/tests | |
| # Create symbolic link for the config directory | |
| if [ ! -L "build/${{ matrix.config }}" ]; then | |
| ln -sf "${{ matrix.config }}-${{ matrix.library_type }}" "build/${{ matrix.config }}" | |
| fi | |
| # Create symbolic link for the tests directory to match expected path structure | |
| if [ ! -L "build/tests/${{ matrix.config }}" ]; then | |
| ln -sf "../${{ matrix.config }}-${{ matrix.library_type }}/tests/${{ matrix.config }}" "build/tests/${{ matrix.config }}" | |
| fi | |
| cd scripts | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| # Set library path for shared library tests | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| export PATH="$PWD/../build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}:$PATH" | |
| fi | |
| ./run_tests.sh --functional --skip-build | |
| else | |
| # Set library path for shared library tests | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| export PATH="$PWD/../build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}:$PATH" | |
| fi | |
| ./run_tests.sh --performance --skip-build | |
| # Run video file playback tests (Release only) | |
| ./run_tests.sh --video --skip-build | |
| fi | |
| - name: Upload artifacts | |
| if: steps.check-vs2026.outputs.VS_2026_AVAILABLE == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ccap-windows-vs2026-${{ matrix.config }}-${{ matrix.library_type }} | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/ccap*.* | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/0-print_camera.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/1-minimal_example.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/2-capture_grab.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/${{ matrix.config }}/3-capture_callback.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/*_results.xml | |
| # Use 'warn' instead of 'error' since VS 2026 build is optional (may not be available on all runners) | |
| if-no-files-found: warn | |
| build-mingw: | |
| name: Windows Build MinGW (${{ matrix.config }}-${{ matrix.library_type }}) | |
| runs-on: windows-latest | |
| strategy: | |
| matrix: | |
| config: [Debug, Release] | |
| library_type: [static, shared] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup MinGW-w64 | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: MINGW64 | |
| update: true | |
| install: >- | |
| mingw-w64-x86_64-toolchain | |
| mingw-w64-x86_64-cmake | |
| mingw-w64-x86_64-ninja | |
| make | |
| # Cache CMake build directory for MinGW | |
| - name: Setup CMake build cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeFiles | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/CMakeCache.txt | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/**/*.o | |
| key: ${{ runner.os }}-mingw-${{ matrix.config }}-${{ matrix.library_type }}-${{ hashFiles('CMakeLists.txt', 'src/**', 'include/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-mingw-${{ matrix.config }}-${{ matrix.library_type }}- | |
| ${{ runner.os }}-mingw-${{ matrix.config }}- | |
| - name: Configure CMake with MinGW | |
| shell: msys2 {0} | |
| run: | | |
| SHARED_FLAG="" | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| SHARED_FLAG="-DCCAP_BUILD_SHARED=ON" | |
| echo "Configuring Windows build ${{ matrix.config }} with MinGW - SHARED LIBRARY (DLL)" | |
| else | |
| echo "Configuring Windows build ${{ matrix.config }} with MinGW - STATIC LIBRARY" | |
| fi | |
| # Check compiler version | |
| gcc --version | |
| cmake --version | |
| mkdir -p "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cmake ../.. -G "Ninja" -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCCAP_BUILD_TESTS=ON $SHARED_FLAG | |
| - name: Build | |
| shell: msys2 {0} | |
| run: | | |
| cd "build/${{ matrix.config }}-${{ matrix.library_type }}" | |
| cmake --build . --parallel | |
| - name: Verify library type | |
| shell: msys2 {0} | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }} | |
| run: | | |
| echo "Checking built libraries:" | |
| ls -la | grep -E "ccap" || echo "No ccap libraries found" | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| # MinGW shared libraries use .dll extension | |
| if [ -f "libccap.dll" ]; then | |
| echo "✓ Windows shared library libccap.dll successfully built with MinGW" | |
| else | |
| echo "✗ Windows shared library libccap.dll not found" | |
| exit 1 | |
| fi | |
| else | |
| # MinGW static libraries use .a extension | |
| if [ -f "libccap.a" ]; then | |
| echo "✓ Windows static library libccap.a successfully built with MinGW" | |
| else | |
| echo "✗ Windows static library libccap.a not found" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Test shared library linking (Windows MinGW) | |
| if: matrix.library_type == 'shared' | |
| shell: msys2 {0} | |
| working-directory: build/${{ matrix.config }}-${{ matrix.library_type }} | |
| run: | | |
| echo "Testing Windows shared library linking with MinGW..." | |
| # Create a simple test program | |
| cat > test_shared.cpp << 'EOF' | |
| #include "ccap_c.h" | |
| #include <stdio.h> | |
| int main() { | |
| const char* version = ccap_get_version(); | |
| printf("Library version: %s\n", version ? version : "unknown"); | |
| CcapProvider* provider = ccap_provider_create(); | |
| if (provider) { | |
| printf("Provider created successfully\n"); | |
| ccap_provider_destroy(provider); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| EOF | |
| # Compile and run with shared library | |
| g++ -I../../include test_shared.cpp -L. -lccap -o test_shared.exe | |
| ./test_shared.exe | |
| echo "✓ Windows shared library linking test with MinGW passed" | |
| - name: Run Unit Tests | |
| shell: msys2 {0} | |
| run: | | |
| # Create symbolic links to make test script work with new build directory structure | |
| mkdir -p build/tests | |
| # Create symbolic link for the config directory | |
| if [ ! -L "build/${{ matrix.config }}" ]; then | |
| ln -sf "${{ matrix.config }}-${{ matrix.library_type }}" "build/${{ matrix.config }}" | |
| fi | |
| # Create symbolic link for the tests directory to match expected path structure | |
| if [ ! -L "build/tests/${{ matrix.config }}" ]; then | |
| ln -sf "../${{ matrix.config }}-${{ matrix.library_type }}/tests" "build/tests/${{ matrix.config }}" | |
| fi | |
| cd scripts | |
| # Set library path for shared library tests | |
| if [ "${{ matrix.library_type }}" = "shared" ]; then | |
| export PATH="$PWD/../build/${{ matrix.config }}-${{ matrix.library_type }}:$PATH" | |
| fi | |
| # Run appropriate tests based on config | |
| if [ "${{ matrix.config }}" = "Debug" ]; then | |
| ./run_tests.sh --functional --skip-build | |
| else | |
| ./run_tests.sh --performance --skip-build | |
| # Run video file playback tests (Release only) | |
| ./run_tests.sh --video --skip-build | |
| fi | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ccap-windows-mingw-${{ matrix.config }}-${{ matrix.library_type }} | |
| path: | | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/libccap.* | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/0-print_camera.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/1-minimal_example.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/2-capture_grab.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/3-capture_callback.exe | |
| build/${{ matrix.config }}-${{ matrix.library_type }}/*_results.xml | |
| if-no-files-found: warn | |
| # Test building with file playback disabled (VS2022 Release only) | |
| build-vs2022-no-file-playback: | |
| name: Windows VS2022 Release - No File Playback | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Visual Studio environment | |
| uses: microsoft/setup-msbuild@v1.1 | |
| - name: Configure CMake (File Playback Disabled) | |
| run: | | |
| Write-Host "Configuring Windows Release build with CCAP_ENABLE_FILE_PLAYBACK=OFF" | |
| New-Item -ItemType Directory -Force -Path "build/Release-no-file-playback" | |
| cd "build/Release-no-file-playback" | |
| cmake ../.. -G "Visual Studio 17 2022" -A x64 -DCCAP_BUILD_TESTS=ON -DCCAP_ENABLE_FILE_PLAYBACK=OFF | |
| - name: Build | |
| run: | | |
| cd "build/Release-no-file-playback" | |
| cmake --build . --config Release --parallel | |
| - name: Verify build | |
| shell: bash | |
| working-directory: build/Release-no-file-playback/Release | |
| run: | | |
| echo "Verifying build with file playback disabled:" | |
| ls -la | grep -E "ccap" || echo "No ccap libraries found" | |
| # Verify library exists | |
| if [ -f "ccap.lib" ]; then | |
| echo "✓ Static library ccap.lib successfully built" | |
| else | |
| echo "✗ Static library ccap.lib not found" | |
| exit 1 | |
| fi | |
| # Verify example programs are built | |
| if [ -f "0-print_camera.exe" ]; then | |
| echo "✓ Example programs built successfully" | |
| else | |
| echo "✗ Example programs not found" | |
| exit 1 | |
| fi | |
| echo "✓ Build verification passed - file playback disabled build works correctly" |