diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index e23cd17e..37bc0b88 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -65,7 +65,7 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: 6.10.2 + version: 6.11.1 arch: clang_64 cache: true diff --git a/.github/workflows/cmake-windows.yml b/.github/workflows/cmake-windows.yml index 4e3485bb..7ad52e60 100644 --- a/.github/workflows/cmake-windows.yml +++ b/.github/workflows/cmake-windows.yml @@ -3,18 +3,12 @@ name: CMake (Windows) on: [push, pull_request] env: - BUILD_TYPE: RelWithDebInfo BUILD_NUMBER: ${{github.run_number}} CMAKE_BUILD_PARALLEL_LEVEL: 4 - # Use libelectronic-id vcpkg manifest for dependencies - VCPKG_MANIFEST_DIR: ./lib/libelectronic-id jobs: build: - runs-on: ${{ matrix.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }} - strategy: - matrix: - arch: [x64, arm64] + runs-on: windows-2022 steps: - name: Checkout code @@ -24,64 +18,61 @@ jobs: persist-credentials: false - name: Cache vcpkg - id: cache uses: actions/cache@v5 with: path: | ${{ github.workspace }}/vcpkg_cache ~/.dotnet/tools ~/.wix - key: vcpkg-${{ matrix.arch }}-${{ hashFiles(format('{0}/vcpkg.json', env.VCPKG_MANIFEST_DIR)) }} + key: vcpkg-${{ hashFiles('./lib/libelectronic-id/vcpkg.json') }} - - name: Install Qt + - name: Install Qt x64 uses: jurplel/install-qt-action@v4 with: - version: 6.10.2 - arch: ${{ matrix.arch == 'arm64' && 'win64_msvc2022_arm64' || 'win64_msvc2022_64' }} + version: 6.11.1 + arch: win64_msvc2022_64 cache: true + aqtsource: git+https://github.com/miurahr/aqtinstall.git - - name: Setup MS Visual C++ dev env - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.arch }} - - - name: Install WiX - if: steps.cache.outputs.cache-hit != 'true' + - name: Save Qt base path + shell: pwsh run: | - dotnet tool install --global wix --version 6.0.2 - wix extension -g add WixToolset.UI.wixext/6.0.2 - wix extension -g add WixToolset.Util.wixext/6.0.2 - wix extension -g add WixToolset.BootstrapperApplications.wixext/6.0.2 + echo "QT_DIR=$(Split-Path $env:QT_ROOT_DIR)" >> $env:GITHUB_ENV - - name: Configure - env: - VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite - run: | - cmake "-GNinja" -S . -B build ` - "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ` - "-DCMAKE_BUILD_TYPE=${env:BUILD_TYPE}" ` - "-DVCPKG_MANIFEST_DIR=${{ env.VCPKG_MANIFEST_DIR }}" + - name: Install Qt arm64 + uses: jurplel/install-qt-action@v4 + with: + version: 6.11.1 + arch: win64_msvc2022_arm64_cross_compiled + cache: true + aqtsource: git+https://github.com/miurahr/aqtinstall.git - name: Build + shell: pwsh + env: + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite run: | - cmake --build build --config ${env:BUILD_TYPE} - cmake --build build --config ${env:BUILD_TYPE} --target installer - cmake --build build --config ${env:BUILD_TYPE} --target bundle + .\build.ps1 -vcpkgroot C:\vcpkg -qt_dir $env:QT_DIR - name: Test - if: ${{ matrix.arch == 'x64' }} - run: ctest -V -C ${env:BUILD_TYPE} --test-dir build + shell: pwsh + run: | + $env:QT_QPA_PLATFORM = 'offscreen' + ctest -V -C RelWithDebInfo --test-dir build\x64 - name: Upload artifacts uses: actions/upload-artifact@v7 with: - name: web-eid-app-windows-build-${{matrix.arch}}-${{github.run_number}} + name: web-eid-app-windows-${{github.run_number}} path: | - build/src/app/*.msi - build/src/app/*.exe + build\*.exe + build\x64\src\app\**\*.msi + build\arm64\src\app\**\*.msi - name: Upload debug artifacts uses: actions/upload-artifact@v7 with: - name: web-eid-app-windows-debug-${{matrix.arch}}-${{github.run_number}} - path: build/**/*.pdb \ No newline at end of file + name: web-eid-app-windows-debug-${{github.run_number}} + path: | + build\x64\**\*.pdb + build\arm64\**\*.pdb diff --git a/CMakeLists.txt b/CMakeLists.txt index 303ae180..85f7e9c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ elseif($ENV{CI_PIPELINE_IID}) else() set(BUILD_NUMBER 0) endif() -project(web-eid VERSION 2.9.0.${BUILD_NUMBER} +project(web-eid VERSION 2.10.0.${BUILD_NUMBER} DESCRIPTION "Web eID browser extension helper application" HOMEPAGE_URL https://github.com/web-eid/web-eid-app ) diff --git a/README.md b/README.md index 71a195d6..b1ce552b 100644 --- a/README.md +++ b/README.md @@ -281,24 +281,13 @@ sudo apt install \ ### Windows - Download Visual Studio 2022 community installer from https://visualstudio.microsoft.com/ and install _Desktop C++ Development_ -- Install WIX toolset - - dotnet tool install --global wix --version 6.0.2 - wix extension -g add WixToolset.UI.wixext/6.0.2 - wix extension -g add WixToolset.Util.wixext/6.0.2 - wix extension -g add WixToolset.Bal.wixext/6.0.2 - - Download and install Git for Windows from https://git-scm.com/download/win - Download and install CMake from https://cmake.org/download/ -- Install _vcpkg_ by running the following commands in Powershell: - - git clone https://github.com/microsoft/vcpkg.git C:\vcpkg - cd C:\vcpkg - .\bootstrap-vcpkg.bat - .\vcpkg integrate install - - Install _Qt_ with the official [_Qt Online Installer_](https://www.qt.io/download-qt-installer), - choose _Custom installation > Qt 6.10.0 > MSVC 2022 64-bit_. + choose _Custom installation > Qt 6.11.1_ and select the architecture(s) you need: + - _MSVC 2022 64-bit_ — for building the x64 binary + - _MSVC 2022 ARM64_ — for building the ARM64 binary natively on an ARM64 host + - _MSVC 2022 ARM64 (cross-compiled)_ — for building the ARM64 binary on an x64 host ### macOS @@ -326,40 +315,59 @@ sudo apt install \ ### Building and testing in Windows -Use _Powershell_ to run the following commands to build the project. +#### Single-arch dev build -- Set the _Qt_ installation directory variable: +Use this when developing or testing for one architecture. In addition to the prerequisites +above, install the following: - $QT_ROOT = "C:\Qt\6.10.0\msvc2022_64" +- Install _vcpkg_: + + git clone https://github.com/microsoft/vcpkg.git C:\vcpkg + C:\vcpkg\bootstrap-vcpkg.bat + +- Install _WiX_ toolset: + + dotnet tool install --global wix --version 6.0.2 + wix extension -g add WixToolset.UI.wixext/6.0.2 + wix extension -g add WixToolset.Util.wixext/6.0.2 + wix extension -g add WixToolset.BootstrapperApplications.wixext/6.0.2 -- Set the _vcpkg_ installation directory variable: +Then run in Powershell: - $VCPKG_ROOT = "C:\vcpkg" + $QT_ROOT = "C:\Qt\6.11.1\msvc2022_64" # adjust arch suffix as needed + $VCPKG_ROOT = "C:\vcpkg" + $BUILD_TYPE = "RelWithDebInfo" -- Set the build type variable: + cmake -A x64 -B build -S . ` + "-DCMAKE_PREFIX_PATH=${QT_ROOT}" ` + "-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" ` + "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" ` + "-DVCPKG_MANIFEST_DIR=lib/libelectronic-id" - $BUILD_TYPE = "RelWithDebInfo" + cmake --build build --config ${BUILD_TYPE} --target installer -- Run _CMake_: +The resulting `.qt.msi` in `build\src\app\` can be installed directly for testing. - cmake -A x64 -B build -S . - "-DCMAKE_PREFIX_PATH=${QT_ROOT}" ` - "-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" ` - "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" ` - "-DVCPKG_MANIFEST_DIR=lib/libelectronic-id" +To run tests: -- Run the build and installer build: + $env:PATH += ";${QT_ROOT}\bin" + ctest -V -C ${BUILD_TYPE} --test-dir build - cmake --build build --config ${BUILD_TYPE} - cmake --build build --config ${BUILD_TYPE} --target installer +#### Dual-arch installer (x64 + ARM64) -- Add _Qt_ binary directory to path: +Use `build.ps1` to build both architectures and produce a combined installer bundle. +WiX and vcpkg are installed automatically if not already present. - $env:PATH += ";${QT_ROOT}\bin" + powershell -ExecutionPolicy ByPass -File build.ps1 -- Run tests: +Key parameters (all optional, with auto-detected defaults): - ctest -V -C ${BUILD_TYPE} --test-dir build +| Parameter | Default | Description | +|-----------------|----------------------|---------------------------------------------| +| `-qt_dir` | `C:\Qt\6.11.1` | Qt installation base directory | +| `-vcpkgroot` | `$env:VCPKG_ROOT` | vcpkg root directory | +| `-crosscompile` | auto-detected | `$true` on x64 host, `$false` on ARM64 host | +| `-sign` | _(none)_ | Certificate CN for code signing | ## Adding and updating translations diff --git a/build.ps1 b/build.ps1 index 9b8315d1..fcd77841 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,10 +1,90 @@ +#powershell -ExecutionPolicy ByPass -File build.ps1 param( + [string]$webeid = $PSScriptRoot, [string]$cmake = "C:\Program Files\CMake\bin\cmake.exe", - [string]$vcpkgroot = "C:\vcpkg", - [string]$qtdir = "C:\Qt\6.10.0\msvc2022_64", + [string]$vcpkgroot = $env:VCPKG_ROOT, + [string]$build_number = $(if ($null -eq $env:BUILD_NUMBER) {"0"} else {$env:BUILD_NUMBER}), + [string]$version = (Select-String -Path "$webeid/CMakeLists.txt" -Pattern 'project\(web-eid VERSION (\d+\.\d+\.\d+)').Matches[0].Groups[1].Value + ".$build_number", + [bool]$crosscompile = ($env:PROCESSOR_ARCHITECTURE -eq "AMD64"), + [string]$qt_dir = "C:\Qt\6.11.1", + [string]$qt_x64 = "$qt_dir\msvc2022_64", + [string]$qt_arm64 = $(if ($crosscompile) { "$qt_dir\msvc2022_arm64_cross_compiled" } else { "$qt_dir\msvc2022_arm64" }), [string]$buildtype = "RelWithDebInfo", - [string]$arch = "x64" + [string]$sign = $null ) -& $cmake -S . -B build\windows -A $arch -DCMAKE_BUILD_TYPE=$buildtype "-DCMAKE_PREFIX_PATH=$qtdir" "-DCMAKE_TOOLCHAIN_FILE=$vcpkgroot\scripts\buildsystems\vcpkg.cmake" "-DVCPKG_MANIFEST_DIR=lib/libelectronic-id" -& $cmake --build build\windows --config $buildtype +$ErrorActionPreference = "Stop" + +Try { & wix > $null } Catch { + & dotnet tool install --global --version 6.0.2 wix + & wix extension add -g WixToolset.UI.wixext/6.0.2 + & wix extension add -g WixToolset.Util.wixext/6.0.2 + & wix extension add -g WixToolset.BootstrapperApplications.wixext/6.0.2 +} + +if(!(Test-Path -Path $vcpkgroot)) { + $vcpkgroot = "$webeid\vcpkg" + & git clone https://github.com/microsoft/vcpkg $vcpkgroot + & $vcpkgroot\bootstrap-vcpkg.bat +} + +$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" +$vcvars = & $vswhere -latest -find "VC\Auxiliary\Build\vcvarsall.bat" + +$msi = @{} + +foreach ($arch in @("x64", "arm64")) { + $env:PLATFORM = $arch + $buildpath = "$webeid\build\$arch" + $qt_path = if ($arch -eq "arm64") { $qt_arm64 } else { $qt_x64 } + + $vsarch = if ($arch -eq "arm64") { if ($crosscompile) { "amd64_arm64" } else { "arm64" } } else { "amd64" } + cmd /c "`"$vcvars`" $vsarch && set" | Where-Object { $_ -match '=' } | ForEach-Object { + $name, $value = $_ -split '=', 2 + [System.Environment]::SetEnvironmentVariable($name, $value) + } + + $cmakeargs = @( + "-A", $(if ($arch -eq "arm64") { "ARM64" } else { "x64" }), + "-S", $webeid, + "-B", $buildpath, + "-DCMAKE_BUILD_TYPE=$buildtype", + "-DCMAKE_PREFIX_PATH=$qt_path", + "-DCMAKE_TOOLCHAIN_FILE=$vcpkgroot\scripts\buildsystems\vcpkg.cmake", + "-DVCPKG_MANIFEST_DIR=$webeid\lib\libelectronic-id" + ) + if ($arch -eq "arm64" -and $crosscompile) { + $cmakeargs += "-DQT_HOST_PATH=$($qt_x64 -replace '\\','/')" + } + if ($sign) { $cmakeargs += "-DSIGNCERT=$sign" } + + & $cmake @cmakeargs + & $cmake --build $buildpath --config $buildtype + & $cmake --build $buildpath --config $buildtype --target installer + + $msi[$arch] = "$buildpath\src\app\$buildtype\web-eid_$version.$arch" +} + +# Bundle +$bundle = "$webeid\build\web-eid_$version.exe" +& wix build -nologo ` + -ext WixToolset.BootstrapperApplications.wixext ` + -ext WixToolset.Util.wixext ` + -d webeid_x64="$($msi['x64'])" ` + -d webeid_arm64="$($msi['arm64'])" ` + -d MSI_VERSION=$version ` + -d path="$webeid\install" ` + "$webeid\install\plugins.wxs" ` + -o $bundle + +if ($sign) { + $signargs = @("sign", "/a", "/v", "/s", "MY", "/n", $sign, + "/fd", "SHA256", "/du", "http://installer.id.ee", + "/tr", "http://timestamp.digicert.com", "/td", "SHA256") + $engine = "$webeid\build\web-eid_$version.engine.exe" + & wix burn detach -nologo $bundle -engine $engine + & signtool.exe @signargs $engine + & wix burn reattach -nologo $bundle -engine $engine -o $bundle + & signtool.exe @signargs $bundle + Remove-Item $engine +} diff --git a/install/plugins.wxs b/install/plugins.wxs index 49745862..95c09ac6 100644 --- a/install/plugins.wxs +++ b/install/plugins.wxs @@ -32,10 +32,21 @@ Key="SOFTWARE\Microsoft\Edge\Extensions\gnmckgbandlkacikdndelhfghdejfido" Value="update_url" After="WebEIDInstalled" /> + - + + + + + + + + + diff --git a/lib/libelectronic-id b/lib/libelectronic-id index 8804358c..6670c289 160000 --- a/lib/libelectronic-id +++ b/lib/libelectronic-id @@ -1 +1 @@ -Subproject commit 8804358c0afb10911ae68aee37db9beb275a7053 +Subproject commit 6670c289dd1d5d760bb66026f2ff7d401be7e0f3 diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 4c59ed11..18c981ed 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -43,17 +43,6 @@ if(WIN32) COMMAND ${WIX_CMD} -d qt_path=${Qt6_DIR}/../../../bin -o "${BASE_FILE}.qt.msi" WORKING_DIRECTORY $ ) - add_custom_target(bundle DEPENDS installer - COMMAND wix.exe build -nologo - -ext WixToolset.BootstrapperApplications.wixext - -ext WixToolset.Util.wixext - -d webeid="${BASE_FILE}" - -d MSI_VERSION=${PROJECT_VERSION} - -d path="${CMAKE_SOURCE_DIR}/install" - "${CMAKE_SOURCE_DIR}/install/plugins.wxs" - -o "${BASE_FILE}.exe" - WORKING_DIRECTORY $ - ) if(SIGNCERT) list(APPEND SIGNCMD signtool.exe sign /a /v /s MY /n "${SIGNCERT}" /fd SHA256 /du http://installer.id.ee /tr http://timestamp.digicert.com /td SHA256) @@ -65,14 +54,6 @@ if(WIN32) COMMAND ${SIGNCMD} "${BASE_FILE}.msi" "${BASE_FILE}.qt.msi" WORKING_DIRECTORY $ ) - add_custom_command(TARGET bundle POST_BUILD - COMMAND wix.exe burn detach -nologo "${BASE_FILE}.exe" -engine "${BASE_FILE}.engine.exe" - COMMAND ${SIGNCMD} "${BASE_FILE}.engine.exe" - COMMAND wix.exe burn reattach -nologo "${BASE_FILE}.exe" -engine "${BASE_FILE}.engine.exe" -o "${BASE_FILE}.exe" - COMMAND ${SIGNCMD} "${BASE_FILE}.exe" - COMMAND del "${BASE_FILE}.engine.exe" - WORKING_DIRECTORY $ - ) endif() elseif(APPLE) set(WEBEID_PATH /Applications/Utilities/web-eid.app/Contents/MacOS/web-eid)