Fix link formatting in README for qBittorrent project reference #64
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: Build Windows ARM64 Native | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*-arm64' | |
| permissions: | |
| contents: write | |
| env: | |
| qbt_version: "5.2.3" | |
| qt_version: "6.10.3" | |
| vcpkg_triplet: "arm64-windows-static-release" | |
| libt_variant: "lt20" | |
| libt_ref: "da7a68a440b7abf4eb1a237df7168be0b8b17084" | |
| libt_version_display: "2.0.13+gitda7a68a440" | |
| boost_version: "1.91.0" | |
| artifact_name: "arm64-native-lt20" | |
| jobs: | |
| build-windows-arm64-native: | |
| name: Build Native ARM64 (lt20) | |
| runs-on: windows-latest | |
| env: | |
| boost_root: "${{ github.workspace }}/../boost" | |
| libtorrent_root: "${{ github.workspace }}/../libtorrent-msvc-arm64" | |
| qt_target_root: "${{ github.workspace }}/../qt-msvc-arm64" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup MSVC cross toolchain | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: amd64_arm64 | |
| - name: Install build tools | |
| shell: pwsh | |
| run: | | |
| choco install ninja | |
| - name: Setup vcpkg | |
| uses: lukka/run-vcpkg@v11 | |
| with: | |
| vcpkgGitCommitId: '84bab45d415d22042bd0b9081aea57f362da3f35' | |
| vcpkgDirectory: C:/vcpkg | |
| doNotUpdateVcpkg: true | |
| - name: Normalize vcpkg paths | |
| shell: pwsh | |
| run: | | |
| if (-not $env:RUNVCPKG_VCPKG_ROOT) { | |
| throw "RUNVCPKG_VCPKG_ROOT is not set" | |
| } | |
| $vcpkgRoot = $env:RUNVCPKG_VCPKG_ROOT -replace '\\', '/' | |
| "VCPKG_ROOT=$vcpkgRoot" >> $env:GITHUB_ENV | |
| "VCPKG_CMAKE_ROOT=$vcpkgRoot" >> $env:GITHUB_ENV | |
| - name: Install vcpkg dependencies | |
| shell: pwsh | |
| run: | | |
| $packages = @( | |
| "openssl:${{ env.vcpkg_triplet }}", | |
| "zlib:${{ env.vcpkg_triplet }}" | |
| ) | |
| & "$env:VCPKG_ROOT/vcpkg.exe" upgrade --no-dry-run | |
| & "$env:VCPKG_ROOT/vcpkg.exe" install --clean-after-build @packages | |
| - name: Build source URLs | |
| shell: pwsh | |
| run: | | |
| $boostVersion = "${{ env.boost_version }}" | |
| $boostVersionUnderscored = $boostVersion -replace '\.', '_' | |
| "BOOST_URL=https://archives.boost.io/release/$boostVersion/source/boost_${boostVersionUnderscored}.7z" >> $env:GITHUB_ENV | |
| "QBT_URL=https://github.com/qbittorrent/qBittorrent/archive/refs/tags/release-${{ env.qbt_version }}.tar.gz" >> $env:GITHUB_ENV | |
| - name: Download Boost | |
| shell: pwsh | |
| run: | | |
| aria2c "$env:BOOST_URL" -d "${{ runner.temp }}" -o "boost.7z" | |
| 7z x "${{ runner.temp }}/boost.7z" -o"${{ github.workspace }}/.." | |
| Move-Item "${{ github.workspace }}/../boost_*" "${{ env.boost_root }}" | |
| - name: Install Qt host tools | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| aqtversion: '==3.3.*' | |
| version: "${{ env.qt_version }}" | |
| archives: 'qtbase qttools' | |
| set-env: 'false' | |
| dir: 'C:' | |
| - name: Show tool versions | |
| shell: pwsh | |
| run: | | |
| cmake --version | |
| ninja --version | |
| - name: Build Qt for ARM64 | |
| shell: pwsh | |
| run: | | |
| $env:Path = "C:\Qt\${{ env.qt_version }}\msvc2022_64\bin;" + $env:Path | |
| $vcpkgRoot = $env:VCPKG_ROOT | |
| git clone https://github.com/qt/qt5.git qt6 | |
| Set-Location qt6 | |
| git checkout "v${{ env.qt_version }}" | |
| ./configure -init-submodules -submodules qtbase,qtsvg | |
| Remove-Item CMakeCache.txt -ErrorAction SilentlyContinue | |
| ./configure -opensource -confirm-license -nomake tests -nomake examples ` | |
| -static -static-runtime -release -xplatform win32-arm64-msvc ` | |
| -prefix "${{ env.qt_target_root }}" ` | |
| -qt-host-path "C:/Qt/${{ env.qt_version }}/msvc2022_64" ` | |
| -qt-zlib -schannel -no-openssl -qt-sqlite -sql-sqlite -no-sql-mysql -no-sql-odbc -no-sql-psql -c++std c++20 | |
| cmake --build . | |
| cmake --install . | |
| - name: Build libtorrent for ARM64 | |
| shell: pwsh | |
| run: | | |
| git init libtorrent | |
| Set-Location libtorrent | |
| git remote add origin https://github.com/arvidn/libtorrent.git | |
| git fetch --depth 1 origin ${{ env.libt_ref }} | |
| git checkout FETCH_HEAD | |
| git submodule update --init --recursive --depth 1 | |
| $boostRoot = (Get-Item "${{ env.boost_root }}").FullName.Replace('\\', '/') | |
| New-Item -ItemType Directory -Path "${{ env.libtorrent_root }}" -Force | Out-Null | |
| $libtorrentRoot = [System.IO.Path]::GetFullPath("${{ env.libtorrent_root }}").Replace('\\', '/') | |
| $toolchain = "$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| cmake ` | |
| -B build ` | |
| -G Ninja ` | |
| -DCMAKE_BUILD_TYPE=Release ` | |
| -DCMAKE_INSTALL_PREFIX="$libtorrentRoot" ` | |
| -DCMAKE_TOOLCHAIN_FILE="$toolchain" ` | |
| -DBOOST_ROOT="$boostRoot" ` | |
| -DBUILD_SHARED_LIBS=OFF ` | |
| -Dmmap-disk-io=OFF ` | |
| -Ddeprecated-functions=ON ` | |
| -Dstatic_runtime=ON ` | |
| -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL=TRUE ` | |
| -DVCPKG_TARGET_TRIPLET=${{ env.vcpkg_triplet }} | |
| cmake --build build | |
| cmake --install build | |
| - name: Build qBittorrent for ARM64 | |
| shell: pwsh | |
| run: | | |
| $qtTargetRoot = (Get-Item "${{ env.qt_target_root }}").FullName.Replace('\\', '/') | |
| $hostQtRoot = "C:/Qt/${{ env.qt_version }}/msvc2022_64" | |
| $vcpkgInstalled = "$env:VCPKG_ROOT/installed/${{ env.vcpkg_triplet }}" | |
| $boostRoot = (Get-Item "${{ env.boost_root }}").FullName.Replace('\\', '/') | |
| $libtorrentDir = (Get-Item "${{ env.libtorrent_root }}").FullName.Replace('\\', '/') + '/lib/cmake/LibtorrentRasterbar' | |
| $env:Path = "$qtTargetRoot/bin;$env:Path" | |
| aria2c "$env:QBT_URL" | |
| tar -xf "qbittorrent-release-${{ env.qbt_version }}.tar.gz" | |
| Set-Location "qbittorrent-release-${{ env.qbt_version }}" | |
| $qbtSourceDir = (Get-Location).Path | |
| $cmakePreloadFile = Join-Path $qbtSourceDir "ci-preload.cmake" | |
| $commonConfigPath = "cmake/Modules/CommonConfig.cmake" | |
| $commonConfig = Get-Content $commonConfigPath -Raw | |
| $commonConfig = $commonConfig -replace "QT_DISABLE_DEPRECATED_UP_TO=0x060500", "QT_DISABLE_DEPRECATED_UP_TO=0x040800" | |
| Set-Content $commonConfigPath -Value $commonConfig | |
| $cmakePreload = @( | |
| 'find_package(ZLIB REQUIRED)' | |
| 'if(TARGET ZLIB::ZLIB)' | |
| ' set_property(TARGET ZLIB::ZLIB PROPERTY IMPORTED_GLOBAL TRUE)' | |
| 'endif()' | |
| 'find_package(OpenSSL REQUIRED)' | |
| 'if(TARGET OpenSSL::SSL)' | |
| ' set_property(TARGET OpenSSL::SSL PROPERTY IMPORTED_GLOBAL TRUE)' | |
| 'endif()' | |
| 'if(TARGET OpenSSL::Crypto)' | |
| ' set_property(TARGET OpenSSL::Crypto PROPERTY IMPORTED_GLOBAL TRUE)' | |
| 'endif()' | |
| ) -join "`n" | |
| Set-Content -Path $cmakePreloadFile -Value $cmakePreload | |
| $cmakePreloadPath = (Get-Item $cmakePreloadFile).FullName.Replace('\\', '/') | |
| cmake ` | |
| -B build ` | |
| -G Ninja ` | |
| -DCMAKE_BUILD_TYPE=RelWithDebInfo ` | |
| -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase ` | |
| -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="$cmakePreloadPath" ` | |
| -DCMAKE_PREFIX_PATH="$qtTargetRoot;$hostQtRoot;$vcpkgInstalled" ` | |
| -DQT_HOST_PATH="$hostQtRoot" ` | |
| -DCMAKE_FIND_PACKAGE_TARGETS_GLOBAL=ON ` | |
| -DOPENSSL_ROOT_DIR="$vcpkgInstalled" ` | |
| -DZLIB_ROOT="$vcpkgInstalled" ` | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` | |
| -DVCPKG_MANIFEST_MODE=OFF ` | |
| -DBOOST_ROOT="$boostRoot" ` | |
| -DLibtorrentRasterbar_DIR="$libtorrentDir" ` | |
| -DMSVC_RUNTIME_DYNAMIC=OFF ` | |
| -DSTACKTRACE=OFF ` | |
| -DQT_NO_PRIVATE_MODULE_WARNING=ON ` | |
| -DVCPKG_TARGET_TRIPLET=${{ env.vcpkg_triplet }} | |
| cmake --build build | |
| - name: Package artifact | |
| shell: pwsh | |
| run: | | |
| $releaseDir = "release" | |
| $artifactDir = "artifact" | |
| $archiveName = "qbittorrent_${{ env.qbt_version }}_arm64.zip" | |
| New-Item -ItemType Directory -Path $releaseDir -Force | Out-Null | |
| New-Item -ItemType Directory -Path $artifactDir -Force | Out-Null | |
| Copy-Item "qbittorrent-release-${{ env.qbt_version }}/build/qbittorrent.exe" $releaseDir | |
| Copy-Item "qbittorrent-release-${{ env.qbt_version }}/dist/windows/qt.conf" $releaseDir | |
| Set-Location $releaseDir | |
| 7z a "../$archiveName" * | |
| Set-Location .. | |
| Move-Item $archiveName $artifactDir | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.artifact_name }} | |
| path: artifact | |
| smoke-test-windows-arm64-native: | |
| name: Smoke test Native ARM64 (lt20) | |
| needs: build-windows-arm64-native | |
| runs-on: windows-latest | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ env.artifact_name }} | |
| path: artifact | |
| - name: Validate ARM64 qBittorrent artifact | |
| shell: pwsh | |
| run: | | |
| $zipFile = Get-ChildItem artifact -Filter "qbittorrent_*.zip" -File | Select-Object -First 1 | |
| if (-not $zipFile) { | |
| throw "No packaged artifact zip found in downloaded build output" | |
| } | |
| $smokeRoot = Join-Path $env:RUNNER_TEMP "qbittorrent-smoke-${{ env.libt_variant }}" | |
| New-Item -ItemType Directory -Path $smokeRoot -Force | Out-Null | |
| Expand-Archive -Path $zipFile.FullName -DestinationPath $smokeRoot -Force | |
| $exePath = Join-Path $smokeRoot "qbittorrent.exe" | |
| if (-not (Test-Path $exePath)) { | |
| throw "qbittorrent.exe was not found after extracting the build artifact" | |
| } | |
| $qtConfPath = Join-Path $smokeRoot "qt.conf" | |
| if (-not (Test-Path $qtConfPath)) { | |
| throw "qt.conf was not found after extracting the build artifact" | |
| } | |
| $exeBytes = [System.IO.File]::ReadAllBytes($exePath) | |
| if ($exeBytes.Length -lt 0x40) { | |
| throw "qbittorrent.exe is too small to be a valid PE file" | |
| } | |
| if ($exeBytes[0] -ne 0x4D -or $exeBytes[1] -ne 0x5A) { | |
| throw "qbittorrent.exe is missing the MZ header" | |
| } | |
| $peOffset = [System.BitConverter]::ToInt32($exeBytes, 0x3C) | |
| if ($peOffset -lt 0 -or ($peOffset + 6) -ge $exeBytes.Length) { | |
| throw "qbittorrent.exe has an invalid PE header offset" | |
| } | |
| if ($exeBytes[$peOffset] -ne 0x50 -or $exeBytes[$peOffset + 1] -ne 0x45 -or $exeBytes[$peOffset + 2] -ne 0x00 -or $exeBytes[$peOffset + 3] -ne 0x00) { | |
| throw "qbittorrent.exe is missing the PE signature" | |
| } | |
| $machine = [System.BitConverter]::ToUInt16($exeBytes, $peOffset + 4) | |
| if ($machine -ne 0xAA64) { | |
| throw "Expected ARM64 machine type 0xAA64, got 0x$('{0:X4}' -f $machine)" | |
| } | |
| Write-Host "Artifact validation passed: qbittorrent.exe is ARM64 (machine 0x$('{0:X4}' -f $machine))." | |
| publish-release: | |
| name: Publish release assets | |
| needs: build-windows-arm64-native | |
| if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'push' && github.ref == 'refs/heads/main') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Publish tagged release | |
| if: startsWith(github.ref, 'refs/tags/') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ env.qbt_version }}-arm64 | |
| name: qBittorrent ${{ env.qbt_version }} (Windows ARM64 Native) | |
| files: | | |
| artifacts/${{ env.artifact_name }}/qbittorrent_${{ env.qbt_version }}_arm64.zip | |
| draft: false | |
| prerelease: false | |
| body: | | |
| Native Windows ARM64 builds produced by ci_windows_arm64_native.yaml | |
| Library versions: | |
| - qBittorrent: ${{ env.qbt_version }} | |
| - Qt: ${{ env.qt_version }} | |
| - vcpkg triplet: ${{ env.vcpkg_triplet }} | |
| - libtorrent (${{ env.libt_variant }}): ${{ env.libt_version_display }} | |
| - Boost (${{ env.libt_variant }}): ${{ env.boost_version }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish branch release | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: native-arm64-main-${{ github.run_number }} | |
| target_commitish: ${{ github.sha }} | |
| name: qBittorrent native ARM64 ${{ github.run_number }} | |
| files: | | |
| artifacts/${{ env.artifact_name }}/qbittorrent_${{ env.qbt_version }}_arm64.zip | |
| draft: false | |
| prerelease: false | |
| body: | | |
| Native ARM64 builds from branch main. | |
| Commit: ${{ github.sha }} | |
| Library versions: | |
| - qBittorrent: ${{ env.qbt_version }} | |
| - Qt: ${{ env.qt_version }} | |
| - vcpkg triplet: ${{ env.vcpkg_triplet }} | |
| - libtorrent (${{ env.libt_variant }}): ${{ env.libt_version_display }} | |
| - Boost (${{ env.libt_variant }}): ${{ env.boost_version }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |