Skip to content

Commit e0c03a8

Browse files
authored
Add windows arm64 build to CI (#1434)
1 parent bd5b5c4 commit e0c03a8

File tree

5 files changed

+108
-22
lines changed

5 files changed

+108
-22
lines changed

.github/workflows/windows.yml

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,31 @@ jobs:
4545
METHOD: 'aqt'
4646
GENERATOR: 'Visual Studio 17 2022'
4747
RELEASE: false
48-
os: windows-latest
48+
os: windows-2022
4949
- QT_VERSION: '6.5.3'
5050
ARCH: 'amd64'
5151
HOST_ARCH: 'amd64'
5252
COMPILER: 'msvc2019_64'
5353
METHOD: 'aqt'
54-
RELEASE: true
54+
RELEASE: false
5555
GENERATOR: 'Ninja'
56-
os: windows-latest
56+
os: windows-2022
5757
- QT_VERSION: '6.8.3'
5858
ARCH: 'amd64'
5959
HOST_ARCH: 'amd64'
6060
COMPILER: 'msvc2022_64'
6161
METHOD: 'aqt'
62-
RELEASE: false
62+
RELEASE: true
6363
GENERATOR: 'Ninja'
6464
os: windows-2025
65+
- QT_VERSION: '6.8.3'
66+
TARGET_ARCH: 'arm64'
67+
HOST_ARCH: 'amd64'
68+
COMPILER: 'msvc2022_64'
69+
CROSS_COMPILER: 'msvc2022_arm64'
70+
METHOD: 'aqt'
71+
RELEASE: true
72+
os: windows-2025
6573

6674
steps:
6775
- name: Checkout repository
@@ -72,7 +80,7 @@ jobs:
7280
id: cache
7381
with:
7482
path: ~/Cache
75-
key: ${{ runner.os }}-${{ matrix.QT_VERSION }}-${{ matrix.COMPILER }}-${{ secrets.CACHE_VERSION }}
83+
key: ${{ runner.os }}-${{ matrix.QT_VERSION }}-${{ matrix.COMPILER }}-${{ matrix.CROSS_COMPILER }}-${{ secrets.CACHE_VERSION }}
7684

7785
- name: Install Qt setup(aqt)
7886
if: steps.cache.outputs.cache-hit != 'true'
@@ -86,7 +94,11 @@ jobs:
8694
CI_BUILD_DIR: ${{ github.workspace }}
8795
shell: bash
8896
run: |
89-
./tools/ci_install_windows.sh "${{ matrix.QT_VERSION }}" "${{ matrix.COMPILER }}" "${{ matrix.METHOD }}"
97+
if [ -n "${{ matrix.CROSS_COMPILER }}" ]; then
98+
./tools/ci_install_windows.sh "${{ matrix.QT_VERSION }}" "${{ matrix.COMPILER }}" "${{ matrix.METHOD }}" "${{ matrix.CROSS_COMPILER }}"
99+
else
100+
./tools/ci_install_windows.sh "${{ matrix.QT_VERSION }}" "${{ matrix.COMPILER }}" "${{ matrix.METHOD }}"
101+
fi
90102
91103
- name: Install Inno Setup
92104
if: matrix.os == 'windows-2025'
@@ -95,18 +107,31 @@ jobs:
95107
- name: Build
96108
shell: powershell
97109
run: |
98-
.\tools\ci_setup_windows.ps1 -qtdir "$Home\Cache\Qt\${{ matrix.QT_VERSION }}\${{ matrix.COMPILER }}" -arch "${{ matrix.ARCH }}" -host_arch "${{ matrix.HOST_ARCH }}" -vcversion "${{ matrix.VCVERSION }}"
99-
.\tools\ci_script_windows.ps1 -generator "${{ matrix.GENERATOR }}" -arch "${{ matrix.ARCH }}" -toolset "${{ matrix.TOOLSET }}"
110+
if ([string]::IsNullOrEmpty("${{ matrix.CROSS_COMPILER }}")) {
111+
.\tools\ci_setup_windows.ps1 -qtdir "$Home\Cache\Qt\${{ matrix.QT_VERSION }}\${{ matrix.COMPILER }}" -arch "${{ matrix.ARCH }}" -host_arch "${{ matrix.HOST_ARCH }}" -vcversion "${{ matrix.VCVERSION }}"
112+
.\tools\ci_script_windows.ps1 -generator "${{ matrix.GENERATOR }}" -arch "${{ matrix.ARCH }}" -toolset "${{ matrix.TOOLSET }}"
113+
} else {
114+
$hash = @{}
115+
$hash["qt_root_dir"] = "$Home\Cache\Qt\${{ matrix.QT_VERSION }}"
116+
$hash["host_arch"] = "${{ matrix.HOST_ARCH }}"
117+
$hash["target_arch"] = "${{ matrix.TARGET_ARCH }}"
118+
$hash["compiler"] = "${{ matrix.COMPILER }}"
119+
$hash["cross_compiler"] = "${{ matrix.CROSS_COMPILER }}"
120+
.\tools\ci_windows_cross_compile @hash
121+
}
100122
101123
- name: Rename
102124
shell: bash
103125
run: |
104126
VERSION_ID=$(date -u +%Y%m%dT%H%MZ --date=$(git show -s --format=%aI HEAD))-$(git rev-parse --short=7 HEAD)
105-
mv bld/gui/GPSBabel-*-Setup.exe bld/gui/GPSBabel-${VERSION_ID}-Setup.exe
106-
mv bld/gui/GPSBabel-*-Manifest.txt bld/gui/GPSBabel-${VERSION_ID}-Manifest.txt
127+
SETUP=$(ls bld/gui/GPSBabel-*-Setup-*.exe | sed "s/\([^-]*\)-\([^-]*\)-\(.*\)/\1-${VERSION_ID}-\3/")
128+
mv bld/gui/GPSBabel-*-Setup-*.exe ${SETUP}
129+
MANIFEST=$(ls bld/gui/GPSBabel-*-Manifest-*.txt | sed "s/\([^-]*\)-\([^-]*\)-\(.*\)/\1-${VERSION_ID}-\3/")
130+
mv bld/gui/GPSBabel-*-Manifest-*.txt ${MANIFEST}
107131
108132
- name: Test
109133
shell: bash
134+
if: matrix.CROSS_COMPILER == ''
110135
run: |
111136
# PATH="${HOME}/Cache/Qt/${{ matrix.QT_VERSION }}/${{ matrix.COMPILER }}/bin:${PATH}"
112137
PNAME=./bld/gui/package/gpsbabel.exe GBTEMP=./gbtemp ./testo 2>&1
@@ -116,7 +141,7 @@ jobs:
116141
if: ${{ inputs.attestation && matrix.RELEASE }}
117142
uses: actions/attest-build-provenance@v2
118143
with:
119-
subject-path: 'bld/gui/GPSBabel-*-Setup.exe'
144+
subject-path: 'bld/gui/GPSBabel-*-Setup-*.exe'
120145

121146
- name: Deploy
122147
# This only handles continous releases now, for other events artifacts may be saved in
@@ -127,13 +152,13 @@ jobs:
127152
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
128153
RELEASE_NAME: Continuous-${{ runner.os }}
129154
run: |
130-
./tools/uploadtool/upload_github.sh bld/gui/GPSBabel-*-Setup.exe
155+
./tools/uploadtool/upload_github.sh bld/gui/GPSBabel-*-Setup-*.exe
131156
132157
- name: 'Upload Artifacts'
133158
uses: actions/upload-artifact@v4
134159
with:
135160
name: Windows_Installer ${{ join(matrix.*) }}
136161
path: |
137-
bld/gui/GPSBabel-*-Setup.exe
138-
bld/gui/GPSBabel-*-Manifest.txt
162+
bld/gui/GPSBabel-*-Setup-*.exe
163+
bld/gui/GPSBabel-*-Manifest-*.txt
139164
retention-days: 7

gui/CMakeLists.txt

100644100755
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,31 @@ else()
230230
if((NOT WINDEPLOYQT STREQUAL "WINDEPLOYQT-NOTFOUND") AND (NOT INNO_COMPILER STREQUAL "INNO_COMPILER-NOTFOUND"))
231231
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" _win_binary_path)
232232
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" _win_source_path)
233+
# for cross compiles we need to tell windeployqt about the target qt paths.
234+
if(CMAKE_TOOLCHAIN_FILE)
235+
get_filename_component(_qt_toolchain_dir ${CMAKE_TOOLCHAIN_FILE} DIRECTORY)
236+
get_filename_component(_qt_target_bin_dir ${_qt_toolchain_dir}/../../../bin ABSOLUTE)
237+
file(TO_NATIVE_PATH "${_qt_target_bin_dir}/qtpaths.bat" _qtpaths_file)
238+
set(_qtpaths_option --qtpaths "${_qtpaths_file}")
239+
message(STATUS "Deploying with target qtpaths \"${_qtpaths_file}\".")
240+
endif()
241+
# generate architecture for inno setup
242+
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
243+
set(_installer_arch arm64)
244+
else()
245+
set(_installer_arch x64compatible)
246+
endif()
247+
message(STATUS "CMAKE_SYSTEM_PROCESSOR is \"${CMAKE_SYSTEM_PROCESSOR}\". Building installer for architecture identifier \"${_installer_arch}\".")
233248
add_custom_target(package_app
234249
# deploy to a clean directory as different build systems create differently named debris in release.
235250
COMMAND ${CMAKE_COMMAND} -E remove_directory package
236251
COMMAND ${CMAKE_COMMAND} -E make_directory package
237252
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gpsbabelfe> package
238253
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:gpsbabel> package
239254
# use --plugindir option to locate the plugins.
240-
COMMAND ${WINDEPLOYQT} --verbose 1 --plugindir package\\plugins package\\GPSBabelFE.exe package\\GPSBabel.exe
255+
COMMAND ${WINDEPLOYQT} --verbose 1 --plugindir package\\plugins package\\GPSBabelFE.exe package\\GPSBabel.exe ${_qtpaths_option}
241256
# set location to location of generated setup.iss file.
242-
COMMAND ${INNO_COMPILER} /Doutput_dir=${_win_binary_path} /Dsource_dir=${_win_source_path} setup.iss
257+
COMMAND ${INNO_COMPILER} /Doutput_dir=${_win_binary_path} /Dsource_dir=${_win_source_path} /Darch=${_installer_arch} setup.iss
243258
DEPENDS gpsbabelfe gpsbabel gpsbabelfe_lrelease coretool_lrelease
244259
VERBATIM
245260
USES_TERMINAL)

gui/setup.iss.in

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#ifndef source_dir
1414
#define source_dir "."
1515
#endif
16+
#ifndef arch
17+
#define arch "x64compatible"
18+
#endif
1619

1720
[Setup]
1821
; NOTE: The value of AppId uniquely identifies this application.
@@ -25,13 +28,13 @@ AppPublisher=GPSBabel
2528
AppPublisherURL=https://www.gpsbabel.org
2629
AppSupportURL=https://www.gpsbabel.org
2730
AppUpdatesURL=https://www.gpsbabel.org
28-
ArchitecturesAllowed=x64
29-
ArchitecturesInstallIn64BitMode=x64
30-
DefaultDirName={pf}\GPSBabel
31+
ArchitecturesAllowed={#arch}
32+
ArchitecturesInstallIn64BitMode={#arch}
33+
DefaultDirName={commonpf}\GPSBabel
3134
DefaultGroupName=GPSBabel
3235
OutputDir="{#output_dir}"
33-
OutputBaseFilename=GPSBabel-@GB.VERSION@@GB.PACKAGE_RELEASE@-Setup
34-
OutputManifestFile=GPSBabel-@GB.VERSION@@GB.PACKAGE_RELEASE@-Manifest.txt
36+
OutputBaseFilename=GPSBabel-@GB.VERSION@@GB.PACKAGE_RELEASE@-Setup-{#arch}
37+
OutputManifestFile=GPSBabel-@GB.VERSION@@GB.PACKAGE_RELEASE@-Manifest-{#arch}.txt
3538
SetupIconFile=images\babel2.ico
3639
Compression=lzma
3740
SolidCompression=yes

tools/ci_install_windows.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ function validate() {
1919
}
2020

2121
QT_VERSION=${1:-6.5.3}
22-
COMPILER=${2:-msvc2019_64}
22+
COMPILER=${2:-msvc2022_64}
2323
METHOD=${3:-default}
24+
CROSS_COMPILER=${4}
2425

2526
if [ "${COMPILER}" = "msvc2017_64" ]; then
2627
PACKAGE_SUFFIX=win64_msvc2017_64
@@ -37,6 +38,15 @@ else
3738
exit 1
3839
fi
3940

41+
if [ -n "${CROSS_COMPILER}" ]; then
42+
if [ "${CROSS_COMPILER}" = "msvc2022_arm64" ]; then
43+
PACKAGE_SUFFIX_CROSS=win64_msvc2022_arm64_cross_compiled
44+
else
45+
echo "ERROR: unrecognized Qt cross compiler ${CROSS_COMPILER}." >&2
46+
exit 1
47+
fi
48+
fi
49+
4050
CACHEDIR=${HOME}/Cache
4151
QTDIR=${CACHEDIR}/Qt/${QT_VERSION}/${COMPILER}
4252

@@ -49,6 +59,9 @@ else
4959
if [ "${METHOD}" = "aqt" ]; then
5060
pip3 install 'aqtinstall>=3.1.20'
5161
"${CI_BUILD_DIR}/tools/ci_install_qt.sh" windows "${QT_VERSION}" "${PACKAGE_SUFFIX}" "${CACHEDIR}/Qt"
62+
if [ -n "${PACKAGE_SUFFIX_CROSS}" ]; then
63+
"${CI_BUILD_DIR}/tools/ci_install_qt.sh" windows "${QT_VERSION}" "${PACKAGE_SUFFIX_CROSS}" "${CACHEDIR}/Qt"
64+
fi
5265
echo "export PATH=${QTDIR}/bin:\$PATH" > "${CACHEDIR}/qt.env"
5366
else
5467
echo "ERROR: unknown installation method ${METHOD}." >&2

tools/ci_windows_cross_compile.ps1

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Param(
2+
$build_dir_name = "bld",
3+
$qt_root_dir = "C:/Qt/6.8.3",
4+
$host_arch = "amd64",
5+
$target_arch = "arm64",
6+
$compiler = "msvc2022_64",
7+
$cross_compiler = "msvc2022_arm64"
8+
)
9+
10+
$ErrorActionPreference = "Stop"
11+
12+
# setup visual studio development envirnonment
13+
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
14+
$installationPath = & "$vswhere" -latest -property installationPath
15+
& "$installationPath\Common7\Tools\Launch-VsDevShell.ps1" -Arch $target_arch -HostArch $host_arch -SkipAutomaticLocation
16+
17+
$src_dir = $Pwd
18+
$build_dir = Join-Path $src_dir $build_dir_name
19+
20+
# make sure we are staring with a clean build directory
21+
Remove-Item $build_dir -Recurse -ErrorAction Ignore
22+
New-Item $build_dir -type directory -Force | Out-Null
23+
Set-Location $build_dir
24+
25+
$toolchain_file = "$qt_root_dir/$cross_compiler/lib/cmake/Qt6/qt.toolchain.cmake"
26+
$qt_host_path = "$qt_root_dir/$compiler"
27+
cmake -G Ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_TOOLCHAIN_FILE:FILEPATH="$toolchain_file" -DQT_HOST_PATH:PATH="$qt_host_path" "$src_dir"
28+
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
29+
cmake --build "$build_dir" --target package_app
30+
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }

0 commit comments

Comments
 (0)