From 0717efe807ae498ef92593f5b6ed46257d4e2423 Mon Sep 17 00:00:00 2001 From: luochen570 <1160510664@qq.com> Date: Sat, 30 May 2026 21:59:27 +0800 Subject: [PATCH] ci: build Windows release with MSVC Qt --- .gitea/workflows/build-windows-release.yml | 110 +++++++++++++-------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/.gitea/workflows/build-windows-release.yml b/.gitea/workflows/build-windows-release.yml index 190ff12..02544f0 100644 --- a/.gitea/workflows/build-windows-release.yml +++ b/.gitea/workflows/build-windows-release.yml @@ -13,17 +13,17 @@ permissions: jobs: build-windows-release: - name: Build Windows x64 Release + name: Build Windows x64 Release (MSVC + Qt) # Windows runner 已注册标签:windows-latest、windows-2022、self-hosted;均为 host 模式。 runs-on: windows-2022 env: BUILD_TYPE: Release - MSYS2_ROOT: C:\msys64 - MSYSTEM: UCRT64 - CHERE_INVOKING: 1 - PACKAGE_BASENAME: chengnan-windows-x64 - PACKAGE_NAME: chengnan-windows-x64 + QT_VERSION: 6.7.3 + QT_ARCH: win64_msvc2022_64 + QT_DIR_NAME: msvc2022_64 + PACKAGE_BASENAME: chengnan-windows-x64-msvc + PACKAGE_NAME: chengnan-windows-x64-msvc steps: - name: Prepare source @@ -49,49 +49,77 @@ jobs: Copy-Item -Path $src.FullName -Destination $srcFixed -Recurse -Force Write-Host "Source dir: $srcFixed" - - name: Install MSYS2 and build dependencies + - name: Install official Qt for MSVC shell: powershell run: | $ErrorActionPreference = 'Stop' - $msysRoot = $env:MSYS2_ROOT - if (-not (Test-Path "$msysRoot\usr\bin\bash.exe")) { - $installer = Join-Path $env:RUNNER_TEMP 'msys2-installer.exe' - $installerUrl = 'https://github.com/msys2/msys2-installer/releases/latest/download/msys2-x86_64-latest.exe' - Write-Host "Downloading MSYS2 installer from $installerUrl" - Invoke-WebRequest -Uri $installerUrl -OutFile $installer - & $installer in --confirm-command --accept-messages --root $msysRoot + $qtRoot = Join-Path $env:RUNNER_TEMP 'qt-msvc' + $qtPrefix = Join-Path $qtRoot "$env:QT_VERSION\$env:QT_DIR_NAME" + $windeployqt = Join-Path $qtPrefix 'bin\windeployqt.exe' + if (Test-Path $windeployqt) { + Write-Host "Qt already installed: $qtPrefix" + exit 0 } - $bash = "$msysRoot\usr\bin\bash.exe" - & $bash -lc "pacman --noconfirm -Syuu" - if ($LASTEXITCODE -ne 0) { Write-Host 'First pacman system update returned non-zero; continuing with second update.' } - & $bash -lc "pacman --noconfirm -Syuu" - if ($LASTEXITCODE -ne 0) { throw "pacman system update failed, exit code: $LASTEXITCODE" } - & $bash -lc "pacman --noconfirm -S --needed git zip unzip p7zip mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-qt6-base mingw-w64-ucrt-x86_64-qt6-imageformats" - if ($LASTEXITCODE -ne 0) { throw "pacman dependency installation failed, exit code: $LASTEXITCODE" } + $pyLauncher = Get-Command py -ErrorAction SilentlyContinue + if ($pyLauncher) { + $pythonExe = $pyLauncher.Source + $pythonArgs = @('-3') + } else { + $python = Get-Command python -ErrorAction SilentlyContinue + if (-not $python) { throw 'Python is required to install Qt with aqtinstall, but py/python was not found on PATH.' } + $pythonExe = $python.Source + $pythonArgs = @() + } - - name: Configure and build + & $pythonExe @pythonArgs -m pip install --user --upgrade aqtinstall + if ($LASTEXITCODE -ne 0) { throw "pip install aqtinstall failed, exit code: $LASTEXITCODE" } + + & $pythonExe @pythonArgs -m aqt install-qt windows desktop $env:QT_VERSION $env:QT_ARCH -O $qtRoot -m qtimageformats + if ($LASTEXITCODE -ne 0) { throw "aqt Qt installation failed, exit code: $LASTEXITCODE" } + if (-not (Test-Path $windeployqt)) { throw "Qt installation finished but windeployqt was not found: $windeployqt" } + Write-Host "Qt installed: $qtPrefix" + + - name: Configure, build, and deploy with MSVC shell: powershell run: | $ErrorActionPreference = 'Stop' - $bash = "$env:MSYS2_ROOT\usr\bin\bash.exe" - $srcWin = Join-Path $env:RUNNER_TEMP 'chengnan-work' - $src = $srcWin -replace '\\','/' - $src = $src -replace '^([A-Za-z]):','/$1' - $src = $src.ToLower() - $script = @" - set -euo pipefail - cd '$src' - export PATH=/ucrt64/bin:/usr/bin:`$PATH - cmake -S . -B build-windows -G Ninja -DCMAKE_BUILD_TYPE=Release - cmake --build build-windows --parallel `$(nproc) - rm -rf dist-windows - mkdir -p dist-windows/chengnan - cp build-windows/chengnan.exe dist-windows/chengnan/ - /ucrt64/bin/windeployqt6.exe --release --no-translations dist-windows/chengnan/chengnan.exe || /ucrt64/bin/windeployqt.exe --release --no-translations dist-windows/chengnan/chengnan.exe - printf '%s\n' 'chengnan Windows x64 package' '' 'Usage:' '1. Extract the whole directory.' '2. Double-click chengnan.exe to run.' '' 'Note:' '- This package is built by Windows Runner with MSYS2 UCRT64 + Qt.' '- Do not copy chengnan.exe alone; keep DLLs and Qt plugin directories together.' > dist-windows/chengnan/README.txt - "@ - & $bash -lc $script + $src = Join-Path $env:RUNNER_TEMP 'chengnan-work' + $qtRoot = Join-Path $env:RUNNER_TEMP 'qt-msvc' + $qtPrefix = Join-Path $qtRoot "$env:QT_VERSION\$env:QT_DIR_NAME" + + $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' + if (-not (Test-Path $vswhere)) { throw "vswhere not found: $vswhere. Install Visual Studio 2022 Build Tools with Desktop development with C++." } + $vsPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath + if ([string]::IsNullOrWhiteSpace($vsPath)) { throw 'Visual Studio 2022 C++ build tools were not found. Install Desktop development with C++.' } + $vsDevCmd = Join-Path $vsPath 'Common7\Tools\VsDevCmd.bat' + if (-not (Test-Path $vsDevCmd)) { throw "VsDevCmd.bat not found: $vsDevCmd" } + + $vsCmake = Join-Path $vsPath 'Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin' + if (Test-Path (Join-Path $vsCmake 'cmake.exe')) { $env:PATH = "$vsCmake;$env:PATH" } + if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) { throw 'cmake was not found on PATH or in Visual Studio bundled CMake.' } + + $buildDir = Join-Path $src 'build-windows' + $distDir = Join-Path $src 'dist-windows\chengnan' + $script = Join-Path $src 'build-windows.ps1' + $cmd = "`"$vsDevCmd`" -arch=x64 -host_arch=x64 && powershell -NoProfile -ExecutionPolicy Bypass -File `"$script`" -QtPrefix `"$qtPrefix`" -BuildDir `"$buildDir`" -DistDir `"$distDir`" -Generator `"Visual Studio 17 2022`" -Arch x64 -Config Release" + Write-Host "Building with Visual Studio at: $vsPath" + Write-Host "Using Qt: $qtPrefix" + & cmd.exe /c $cmd + if ($LASTEXITCODE -ne 0) { throw "MSVC build failed, exit code: $LASTEXITCODE" } + + $readme = Join-Path $distDir 'README.txt' + @( + 'chengnan Windows x64 package', + '', + 'Usage:', + '1. Extract the whole directory.', + '2. Double-click chengnan.exe to run.', + '', + 'Note:', + '- This package is built by Windows Runner with MSVC + official Qt.', + '- Do not copy chengnan.exe alone; keep DLLs and Qt plugin directories together.' + ) | Out-File -FilePath $readme -Encoding ascii - name: Package shell: powershell @@ -157,7 +185,7 @@ jobs: tag_name = $tagName target_commitish = $env:GITHUB_SHA name = $releaseName - body = "Automated Windows x64 build from Gitea Actions.`n" + body = "Automated Windows x64 MSVC build from Gitea Actions.`n" draft = $false prerelease = $isPrerelease } | ConvertTo-Json -Depth 5