Skip to content

Commit 36da39c

Browse files
authored
Build windows Arm64 binaries (#1369)
IB-6662, IB-8805 Signed-off-by: Raul Metsma <raul@metsma.ee>
1 parent 5aa99b8 commit 36da39c

File tree

12 files changed

+160
-128
lines changed

12 files changed

+160
-128
lines changed

.github/workflows/build.yml

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ jobs:
4242
key: vcpkg-macOS-${{ hashFiles('prepare_osx_build_environment.sh') }}
4343
- name: Build libraries
4444
run: |
45-
mkdir -p ${LIBS_PATH}/Qt-6.10.1-OpenSSL
45+
mkdir -p ${LIBS_PATH}/Qt-6.10.2-OpenSSL
4646
./prepare_osx_build_environment.sh -p ${LIBS_PATH}
4747
- name: Install Qt
4848
uses: jurplel/install-qt-action@v4
4949
with:
50-
version: 6.10.1
50+
version: 6.10.2
5151
arch: clang_64
52+
cache: true
5253
- name: Build
5354
run: |
5455
cmake "-GNinja" -B build -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo \
@@ -140,10 +141,11 @@ jobs:
140141
path: build/qdigidoc4*.rpm
141142
windows:
142143
name: Build on Windows
143-
runs-on: windows-2025
144+
runs-on: ${{ matrix.platform == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
144145
strategy:
145146
matrix:
146147
vcver: [143]
148+
platform: [x64, arm64]
147149
env:
148150
VER_SUFFIX: .VS${{ matrix.vcver }}
149151
steps:
@@ -153,7 +155,7 @@ jobs:
153155
with:
154156
workflow: build.yml
155157
branch: master
156-
name: msi_${{ matrix.vcver }}_x64
158+
name: msi_${{ matrix.vcver }}_${{ matrix.platform }}
157159
path: ./
158160
repo: open-eid/libdigidocpp
159161
- name: Install artifact
@@ -164,39 +166,34 @@ jobs:
164166
uses: actions/cache@v5
165167
with:
166168
path: ${{ github.workspace }}/vcpkg_cache
167-
key: vcpkg-${{ matrix.vcver }}-${{ hashFiles('vcpkg.json') }}
168-
- name: Prepare vcpkg
169-
uses: lukka/run-vcpkg@v11
170-
with:
171-
vcpkgJsonGlob: ./vcpkg.json
172-
runVcpkgInstall: true
173-
env:
174-
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite
175-
VCPKG_INSTALLED_DIR: ${{ github.workspace }}/build/vcpkg_installed
169+
key: vcpkg-${{ matrix.vcver }}-${{ matrix.platform }}-${{ hashFiles('vcpkg.json') }}
176170
- name: Install Qt
177171
uses: jurplel/install-qt-action@v4
178172
with:
179-
version: 6.10.1
180-
arch: win64_msvc2022_64
173+
version: 6.10.2
174+
arch: ${{ matrix.platform == 'arm64' && 'win64_msvc2022_arm64' || 'win64_msvc2022_64' }}
175+
cache: true
181176
- name: Setup dev env
182177
uses: ilammy/msvc-dev-cmd@v1
183178
with:
184-
arch: x64
179+
arch: ${{ matrix.platform }}
185180
- name: Install WiX
186181
run: |
187182
dotnet tool install -g wix --version 6.0.2
188183
wix extension -g add WixToolset.UI.wixext/6.0.2
189184
- name: Build
185+
env:
186+
VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite
190187
run: |
191188
cmake "-GNinja" -B build -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo `
192-
-DCMAKE_TOOLCHAIN_FILE=${{ env.RUNVCPKG_VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
189+
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
193190
cmake --build build --target msi
194191
cmake --build build --target msishellext
195192
cmake --build build --target appx
196193
- name: Archive artifacts
197194
uses: actions/upload-artifact@v6
198195
with:
199-
name: msi_${{ matrix.vcver }}_x64
196+
name: msi_${{ matrix.vcver }}_${{ matrix.platform }}
200197
path: |
201198
build/*.msi
202199
build/*.appx

client/Application.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ class Application::Private
294294
std::unique_ptr<MacMenuBar> bar;
295295
QSigner *signer {};
296296

297-
QTranslator appTranslator, commonTranslator, qtTranslator;
297+
QTranslator appTranslator, qtTranslator;
298298
QString lang;
299299
QTimer lastWindowTimer;
300300
volatile bool ready = false;
@@ -418,7 +418,6 @@ Application::Application( int &argc, char **argv )
418418
});
419419

420420
installTranslator( &d->appTranslator );
421-
installTranslator( &d->commonTranslator );
422421
installTranslator( &d->qtTranslator );
423422
loadTranslation(Settings::LANGUAGE);
424423

@@ -671,7 +670,6 @@ void Application::loadTranslation( const QString &lang )
671670
else QLocale::setDefault(QLocale(QLocale::Estonian, QLocale::Estonia));
672671

673672
void(d->appTranslator.load(QLatin1String(":/translations/%1.qm").arg(lang)));
674-
void(d->commonTranslator.load(QLatin1String(":/translations/common_%1.qm").arg(lang)));
675673
void(d->qtTranslator.load(QLatin1String(":/translations/qtbase_%1.qm").arg(lang)));
676674
if( d->closeAction ) d->closeAction->setText( tr("Close Window") );
677675
if( d->newClientAction ) d->newClientAction->setText( tr("New Window") );

client/CMakeLists.txt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
get_target_property(qtCore_install_prefix Qt6::qmake IMPORTED_LOCATION)
2-
get_filename_component(qtCore_install_prefix ${qtCore_install_prefix} DIRECTORY)
31
get_filename_component(TSL_FILENAME ${TSL_URL} NAME_WLE)
42
set(TSL_LIST ${TSL_FILENAME} ${TSL_INCLUDE})
53
list(TRANSFORM TSL_LIST APPEND .xml)
@@ -9,14 +7,11 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${TSL_FILENAME}.xml)
97
else()
108
set(TSL_DIR ${CMAKE_CURRENT_BINARY_DIR})
119
list(TRANSFORM TSL_LIST PREPEND ${TSL_DIR}/)
12-
add_executable(TSLDownload TSLDownload.cpp)
13-
target_link_libraries(TSLDownload Qt6::Network)
14-
set_target_properties(TSLDownload PROPERTIES AUTOMOC OFF)
10+
find_package(Python REQUIRED)
1511
add_custom_command(
1612
OUTPUT ${TSL_LIST}
17-
DEPENDS TSLDownload
18-
COMMAND $<TARGET_FILE:TSLDownload> ${CMAKE_CURRENT_BINARY_DIR} ${TSL_URL} ${TSL_INCLUDE}
19-
WORKING_DIRECTORY ${qtCore_install_prefix}
13+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/download_tsl.py
14+
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/download_tsl.py ${CMAKE_CURRENT_BINARY_DIR} ${TSL_URL} ${TSL_INCLUDE}
2015
)
2116
endif()
2217

@@ -92,9 +87,6 @@ qt_add_translations(${PROJECT_NAME} TS_FILES
9287
translations/en.ts
9388
translations/et.ts
9489
translations/ru.ts
95-
../common/translations/common_en.ts
96-
../common/translations/common_et.ts
97-
../common/translations/common_ru.ts
9890
../common/translations/qtbase_et.ts
9991
../common/translations/qtbase_ru.ts
10092
RESOURCE_PREFIX /translations
@@ -242,10 +234,11 @@ elseif(WIN32)
242234
${CMAKE_SOURCE_DIR}/common/WelcomeDlg.wxs
243235
${CMAKE_SOURCE_DIR}/common/WixUI_Minimal.wxs
244236
)
237+
get_filename_component(QT_BASE_DIR "${Qt6_DIR}/../../.." ABSOLUTE)
245238
add_custom_target(msi DEPENDS ${PROJECT_NAME}
246239
COMMAND ${WIX_CMD} -o "${MSI_FILE}.msi"
247240
#Build MSI with QT
248-
COMMAND ${WIX_CMD} -d qt_path=${qtCore_install_prefix} -o "${MSI_FILE}.qt.msi"
241+
COMMAND ${WIX_CMD} -d qt_path=${QT_BASE_DIR}/bin -o "${MSI_FILE}.qt.msi"
249242
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
250243
)
251244
if(SIGNCERT)
@@ -262,11 +255,16 @@ elseif(WIN32)
262255
endif()
263256
set(PLATFORM $ENV{PLATFORM})
264257
configure_file(${CMAKE_SOURCE_DIR}/AppxManifest.xml.cmake ${CMAKE_BINARY_DIR}/AppxManifest.xml)
265-
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
266-
set(OPENSSL_SUFFIX "-x64")
267-
else()
258+
if(PLATFORM STREQUAL "x86")
268259
set(OPENSSL_SUFFIX "")
260+
else()
261+
set(OPENSSL_SUFFIX "-${PLATFORM}")
269262
endif()
263+
set(QT_PATHS ${QT_BASE_DIR}/bin/qtpaths.exe)
264+
if(EXISTS ${QT_BASE_DIR}/bin/host-qtpaths.bat)
265+
set(QT_PATHS ${QT_BASE_DIR}/bin/host-qtpaths.bat)
266+
endif()
267+
270268
add_custom_target(appx DEPENDS ${PROJECT_NAME}
271269
COMMAND ${CMAKE_COMMAND} -E remove ${MSI_FILE}.appx
272270
COMMAND ${CMAKE_COMMAND} -E remove_directory appx
@@ -284,7 +282,7 @@ elseif(WIN32)
284282
COMMAND ${CMAKE_COMMAND} -E copy ${LIBS_PATH}/digidocpp.conf appx
285283
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Assets appx/Assets
286284
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBS_PATH}/schema appx/schema
287-
COMMAND Qt::windeployqt --no-translations --no-compiler-runtime --no-patchqt --force-openssl
285+
COMMAND Qt::windeployqt --no-translations --no-compiler-runtime --no-patchqt --force-openssl --qtpaths ${QT_PATHS}
288286
--skip-plugin-types generic,networkinformation,iconengines --exclude-plugins qjpeg,qico,qgif,qcertonlybackend,qschannelbackend appx
289287
COMMAND ${CMAKE_COMMAND} -E copy ${LIBS_PATH}/digidoc-tool.exe appx
290288
COMMAND makeappx.exe pack -d appx -p ${MSI_FILE}.appx

client/TSLDownload.cpp

Lines changed: 0 additions & 79 deletions
This file was deleted.

client/download_tsl.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import sys
2+
import shutil
3+
import os
4+
import xml.etree.ElementTree as ET
5+
import urllib.request
6+
import urllib.error
7+
import urllib.parse
8+
import time
9+
10+
def download_tsl_file(url, output_path, filename):
11+
output_file = os.path.join(output_path, filename)
12+
print(f"Downloading TSL list from: {url}")
13+
retries = 3
14+
for attempt in range(retries):
15+
try:
16+
with urllib.request.urlopen(url, timeout=60) as response, open(output_file, 'wb') as f:
17+
shutil.copyfileobj(response, f)
18+
print(f"Saved to: {output_file}")
19+
return output_file
20+
except (urllib.error.HTTPError, urllib.error.URLError) as e:
21+
print(f"Attempt {attempt + 1}/{retries} failed: {e}")
22+
if attempt + 1 < retries:
23+
sleep_time = 10 * (attempt + 1)
24+
print(f"Retrying in {sleep_time} seconds...")
25+
time.sleep(sleep_time)
26+
else:
27+
print("All retry attempts failed.")
28+
sys.exit(1)
29+
except IOError as e:
30+
print(f"Error saving TSL list {output_file}: {e}")
31+
sys.exit(1)
32+
33+
def download_tsl_files(output_path, list_url, territories):
34+
master_list_filename = os.path.basename(urllib.parse.urlparse(list_url).path)
35+
if not master_list_filename:
36+
master_list_filename = "eu-lotl.xml" # Fallback filename
37+
file = download_tsl_file(list_url, output_path, master_list_filename)
38+
try:
39+
root = ET.parse(file)
40+
ns = {'tsl': "http://uri.etsi.org/02231/v2#"}
41+
for pointer in root.findall('.//tsl:OtherTSLPointer', ns):
42+
territory = pointer.find('.//tsl:SchemeTerritory', ns)
43+
if territory is None or territory.text not in territories:
44+
continue
45+
46+
mime = pointer.find('.//tslx:MimeType', {'tslx': 'http://uri.etsi.org/02231/v2/additionaltypes#'})
47+
if mime is None or mime.text != 'application/vnd.etsi.tsl+xml':
48+
continue
49+
50+
location = pointer.find('.//tsl:TSLLocation', ns)
51+
if location is not None:
52+
download_tsl_file(location.text, output_path, f"{territory.text}.xml")
53+
54+
except ET.ParseError as e:
55+
print(f"Error parsing XML: {e}")
56+
sys.exit(1)
57+
58+
if __name__ == "__main__":
59+
if len(sys.argv) < 4:
60+
print("Usage: python download_tsl.py <output_path> <url> <territory1> [territory2] ...")
61+
sys.exit(1)
62+
63+
output_path = sys.argv[1]
64+
url = sys.argv[2]
65+
territories_to_download = sys.argv[3:]
66+
67+
if not os.path.isdir(output_path):
68+
print(f"Error: Output path '{output_path}' is not a directory.")
69+
sys.exit(1)
70+
71+
download_tsl_files(output_path, url, territories_to_download)
72+
print("TSL download process finished.")

client/translations/en.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,17 @@
459459
<translation>Cannot connect to certificate status service!</translation>
460460
</message>
461461
</context>
462+
<context>
463+
<name>Configuration</name>
464+
<message>
465+
<source>The configuration file located on the server cannot be validated.</source>
466+
<translation>The configuration file located on the server cannot be validated.</translation>
467+
</message>
468+
<message>
469+
<source>Your computer&apos;s configuration file is later than the server has.</source>
470+
<translation>Your computer&apos;s configuration file is later than the server has.</translation>
471+
</message>
472+
</context>
462473
<context>
463474
<name>ContainerPage</name>
464475
<message>

client/translations/et.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,17 @@
459459
<translation>Kehtivuskinnitusteenus ei ole kättesaadav!</translation>
460460
</message>
461461
</context>
462+
<context>
463+
<name>Configuration</name>
464+
<message>
465+
<source>The configuration file located on the server cannot be validated.</source>
466+
<translation>Serveris olev konfiguratsioonifail ei valideeru.</translation>
467+
</message>
468+
<message>
469+
<source>Your computer&apos;s configuration file is later than the server has.</source>
470+
<translation>Sinu arvutis on uuem konfiguratsioonifail kui serveris.</translation>
471+
</message>
472+
</context>
462473
<context>
463474
<name>ContainerPage</name>
464475
<message>

client/translations/ru.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,17 @@
459459
<translation>Услуга подтверждения действительности не доступна!</translation>
460460
</message>
461461
</context>
462+
<context>
463+
<name>Configuration</name>
464+
<message>
465+
<source>The configuration file located on the server cannot be validated.</source>
466+
<translation>Находящийся на сервере конфигурационный файл не валидируется.</translation>
467+
</message>
468+
<message>
469+
<source>Your computer&apos;s configuration file is later than the server has.</source>
470+
<translation>Находящийся на Вашем компьютере конфигурационный файл новее файла на сервере.</translation>
471+
</message>
472+
</context>
462473
<context>
463474
<name>ContainerPage</name>
464475
<message>

0 commit comments

Comments
 (0)