Skip to content

Commit a12fa15

Browse files
authored
Merge pull request #60 from kambala-decapitator/windows-msvc
[Windows] add MSVC support
2 parents b57d5b3 + 2612498 commit a12fa15

File tree

12 files changed

+2627
-48
lines changed

12 files changed

+2627
-48
lines changed

.github/workflows/build.yaml

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,57 @@ jobs:
1414
platform: macos
1515
preset: release-macos
1616
artifact: '*.dmg'
17+
- os: windows-latest
18+
platform: windows-msvc
19+
preset: release-msvc
20+
artifact: '*.Win32.exe'
21+
useQtAction: true
22+
- os: windows-latest
23+
platform: windows-mingw
24+
preset: release-ninja
1725
steps:
1826
- name: Checkout
1927
uses: actions/checkout@v4
2028
- name: Setup
29+
shell: bash
2130
run: |
22-
ci/${{ matrix.platform }}/setup.sh
31+
setupScript='ci/${{ matrix.platform }}/setup.sh'
32+
[ ! -f "$setupScript" ] || "$setupScript"
2333
env:
2434
MACOS_ASC_API_KEY: ${{ secrets.MACOS_ASC_API_KEY }}
2535
MACOS_CODE_SIGN_KEY_BASE64: ${{ secrets.MACOS_CODE_SIGN_KEY_BASE64 }}
2636
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
37+
- name: Install Qt
38+
uses: jurplel/install-qt-action@v3
39+
if: ${{ matrix.useQtAction }}
40+
with:
41+
version: '6.6.2'
42+
arch: 'win64_msvc2019_64'
43+
archives: 'qtbase qttools opengl32sw d3dcompiler_47'
44+
extra: '--external 7z'
45+
cache: true
46+
setup-python: false
47+
- name: Prepare MSVC environment
48+
uses: ilammy/msvc-dev-cmd@v1
49+
if: ${{ matrix.platform == 'windows-msvc' }}
50+
with:
51+
arch: x64
52+
toolset: 14.29
53+
- name: Setup msys2
54+
uses: msys2/setup-msys2@v2
55+
if: ${{ matrix.platform == 'windows-mingw' }}
56+
with:
57+
update: true
58+
install: >-
59+
mingw-w64-x86_64-cmake
60+
mingw-w64-x86_64-gcc
61+
mingw-w64-x86_64-ninja
62+
mingw-w64-x86_64-qt6-base
63+
mingw-w64-x86_64-qt6-tools
64+
- name: Put MSYS2_MinGW64 on PATH
65+
if: ${{ matrix.platform == 'windows-mingw' }}
66+
run: |
67+
echo "${{ runner.temp }}/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
2768
- name: Configure
2869
run: |
2970
cmake --preset ${{ matrix.preset || 'release' }}
@@ -44,3 +85,4 @@ jobs:
4485
with:
4586
path: build/${{ matrix.artifact }}
4687
name: ${{ matrix.platform }}
88+
compression-level: 0

CMakeLists.txt

Lines changed: 72 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,31 @@ set(CMAKE_AUTOMOC ON)
2020
set(CMAKE_AUTORCC ON)
2121
set(CMAKE_AUTOUIC ON)
2222

23-
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core)
23+
include(GNUInstallDirs)
24+
# GNU dirs must be adjusted before finding Qt for qt_deploy_runtime_dependencies to use customzied vars
25+
if(WIN32)
26+
set(CMAKE_INSTALL_BINDIR .)
27+
endif()
28+
29+
# options
30+
if(WIN32)
31+
option(DUMMY_WRITE "Write image to local file named 'dummy_image_file' instead to real device (for testing)")
32+
endif()
2433

34+
# dependencies
35+
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core)
2536
set(qtComponents Gui Network Widgets LinguistTools)
2637
if(LINUX)
2738
list(APPEND qtComponents DBus)
2839
endif()
2940
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${qtComponents})
3041

42+
if(MSVC_TOOLSET_VERSION EQUAL 142)
43+
list(APPEND CMAKE_PREFIX_PATH "windows/msvc2019/zlib")
44+
endif()
45+
find_package(ZLIB REQUIRED)
46+
47+
# executable
3148
qt_add_executable(LibreELEC.USB-SD.Creator WIN32 MACOSX_BUNDLE
3249
creator.cpp creator.h creator.ui
3350
deviceenumerator.h
@@ -58,7 +75,7 @@ target_link_libraries(LibreELEC.USB-SD.Creator PUBLIC
5875
Qt${QT_VERSION_MAJOR}::Gui
5976
Qt${QT_VERSION_MAJOR}::Network
6077
Qt${QT_VERSION_MAJOR}::Widgets
61-
z
78+
ZLIB::ZLIB
6279
)
6380

6481
string(TIMESTAMP nowDateTime UTC)
@@ -67,6 +84,7 @@ target_compile_definitions(LibreELEC.USB-SD.Creator PRIVATE
6784
"BUILD_VERSION=\"${PROJECT_VERSION}\""
6885
"COPYRIGHT_YEARS=\"${copyrightYears}\""
6986
$<$<CONFIG:Debug>:ALWAYS_DEBUG_OUTPUT>
87+
$<$<BOOL:${DUMMY_WRITE}>:WINDOWS_DUMMY_WRITE>
7088
)
7189

7290
qt_add_translations(LibreELEC.USB-SD.Creator
@@ -107,6 +125,12 @@ qt_add_translations(LibreELEC.USB-SD.Creator
107125
)
108126

109127
if(WIN32)
128+
if(MSVC)
129+
set_target_properties(LibreELEC.USB-SD.Creator PROPERTIES
130+
LINK_OPTIONS "/MANIFEST:NO" # disable default manifest
131+
)
132+
endif()
133+
110134
target_sources(LibreELEC.USB-SD.Creator PUBLIC
111135
deviceenumerator_windows.cpp deviceenumerator_windows.h
112136
diskwriter_windows.cpp diskwriter_windows.h
@@ -115,6 +139,14 @@ if(WIN32)
115139
)
116140

117141
configure_file("windows/winapp.rc.in" "${CMAKE_SOURCE_DIR}/windows/winapp.rc" @ONLY)
142+
143+
set(qtDeployExecutable "$<TARGET_FILE_NAME:LibreELEC.USB-SD.Creator>")
144+
set(qtDeployExtraCommands "
145+
# windeployqt also packages extra libs that aren't needed
146+
foreach(dll in Qt${QT_VERSION_MAJOR}Svg opengl32sw D3Dcompiler_47)
147+
file(REMOVE \"\\\${QT_DEPLOY_PREFIX}/\\\${QT_DEPLOY_BIN_DIR}/\\\${dll}.dll\")
148+
endforeach()
149+
")
118150
elseif(APPLE)
119151
set_target_properties(LibreELEC.USB-SD.Creator PROPERTIES
120152
OUTPUT_NAME "${projectDisplayName}"
@@ -126,32 +158,24 @@ elseif(APPLE)
126158
privileges_unix.cpp privileges_unix.h
127159
)
128160

129-
set(bundleContentsDir "$<TARGET_BUNDLE_CONTENT_DIR:LibreELEC.USB-SD.Creator>")
130161
install(FILES "dmg_osx/icon.icns"
131-
DESTINATION "${bundleContentsDir}/Resources"
162+
DESTINATION "$<TARGET_BUNDLE_CONTENT_DIR:LibreELEC.USB-SD.Creator>/Resources"
132163
)
133164

134-
qt_generate_deploy_script(
135-
TARGET LibreELEC.USB-SD.Creator
136-
OUTPUT_SCRIPT qtDeployScript
137-
CONTENT "
138-
qt_deploy_runtime_dependencies(
139-
EXECUTABLE \"$<TARGET_BUNDLE_DIR:LibreELEC.USB-SD.Creator>\"
140-
GENERATE_QT_CONF
141-
NO_APP_STORE_COMPLIANCE
142-
VERBOSE
143-
)
144-
# macdeployqt also packages extra frameworks that aren't needed
145-
foreach(qtModule in Pdf Svg)
146-
file(REMOVE_RECURSE \"${bundleContentsDir}/Frameworks/Qt\\\${qtModule}.framework\")
147-
endforeach()
148-
149-
# codesign
150-
execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/dmg_osx/codesign.sh\"
151-
WORKING_DIRECTORY \"${bundleContentsDir}\"
152-
)
153-
")
154-
install(SCRIPT ${qtDeployScript})
165+
set(qtDeployExecutable "$<TARGET_FILE_NAME:LibreELEC.USB-SD.Creator>.app")
166+
set(qtDeployExtraCommands "
167+
set(bundleContentsDir \"\\\${QT_DEPLOY_PREFIX}/${qtDeployExecutable}/Contents\")
168+
169+
# macdeployqt also packages extra frameworks that aren't needed
170+
foreach(qtModule in Pdf Svg)
171+
file(REMOVE_RECURSE \"\\\${bundleContentsDir}/Frameworks/Qt\\\${qtModule}.framework\")
172+
endforeach()
173+
174+
# codesign
175+
execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/dmg_osx/codesign.sh\"
176+
WORKING_DIRECTORY \"\\\${bundleContentsDir}\"
177+
)
178+
")
155179
elseif(LINUX)
156180
set_target_properties(LibreELEC.USB-SD.Creator PROPERTIES SUFFIX .Linux.bin)
157181

@@ -166,15 +190,37 @@ elseif(LINUX)
166190
)
167191
endif()
168192

193+
# install
169194
install(TARGETS LibreELEC.USB-SD.Creator
170195
BUNDLE
171196
DESTINATION .
172197
)
198+
if(qtDeployExecutable)
199+
qt_generate_deploy_script(
200+
TARGET LibreELEC.USB-SD.Creator
201+
OUTPUT_SCRIPT qtDeployScript
202+
CONTENT "
203+
qt_deploy_runtime_dependencies(
204+
EXECUTABLE \"${qtDeployExecutable}\"
205+
GENERATE_QT_CONF
206+
NO_APP_STORE_COMPLIANCE
207+
NO_COMPILER_RUNTIME
208+
NO_TRANSLATIONS
209+
VERBOSE
210+
)
211+
${qtDeployExtraCommands}
212+
"
213+
)
214+
install(SCRIPT ${qtDeployScript})
215+
endif()
173216

174217
# cpack
175218
set(CPACK_PACKAGE_NAME "${projectDisplayName}")
176219
set(CPACK_PACKAGE_VENDOR "LibreELEC")
177-
if(APPLE)
220+
if(WIN32)
221+
set(CPACK_PACKAGE_FILE_NAME "LibreELEC.USB-SD.Creator.Win32")
222+
set(CPACK_GENERATOR INNOSETUP)
223+
elseif(APPLE)
178224
set(CPACK_PACKAGE_FILE_NAME "LibreELEC.USB-SD.Creator.macOS")
179225

180226
set(notarizeScript "${CMAKE_BINARY_DIR}/notarize.cmake")

CMakePresets.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@
1010
}
1111
},
1212
{
13-
"name": "release-macos",
13+
"name": "release-ninja",
1414
"inherits": "release",
15-
"generator": "Ninja",
15+
"generator": "Ninja"
16+
},
17+
{
18+
"name": "release-macos",
19+
"inherits": "release-ninja",
1620
"cacheVariables": {
1721
"CMAKE_OSX_ARCHITECTURES": "x86_64;arm64",
1822
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0"
1923
}
24+
},
25+
{
26+
"name": "release-msvc",
27+
"inherits": "release",
28+
"generator": "NMake Makefiles"
2029
}
2130
],
2231
"buildPresets": [

diskwriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <QStringList>
2626
#include <QByteArray>
2727

28-
#include "zlib.h"
28+
#include <zlib.h>
2929

3030
class DiskWriter : public QObject
3131
{

main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ void noMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
4646

4747
int main(int argc, char *argv[])
4848
{
49+
qputenv("QT_QPA_PLATFORM", "windows:darkmode=0");
4950
QApplication app(argc, argv);
5051

5152
const auto cmdArgs = app.arguments();
@@ -88,7 +89,7 @@ int main(int argc, char *argv[])
8889
}
8990
}
9091

91-
Privileges privileges = Privileges();
92+
Privileges privileges;
9293
privileges.Whoami();
9394

9495
QString argFile;

privileges.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
#ifndef PRIVILEGES_H
2020
#define PRIVILEGES_H
2121

22+
#include <QString>
23+
2224
class Privileges {
2325
public:
24-
Privileges() {}
2526
void SetRoot() {}
2627
void SetUser() {}
2728
void SetRealUser() {}
2829
void Whoami() {}
29-
void SaveUserEnv(pid_t) {}
3030
QString GetUserEnvDbusSession()
3131
{
3232
return QString();

translator.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ void Translator::fillLanguages(QMenu *menuPtr, QPushButton *langBtnPtr)
4646
QStringList qmFiles;
4747
// languages from resources
4848
qmFiles << QDir(":/lang").entryList(QStringList("*.qm"));
49-
// languages from a local disk (mostly for testing purposes)
50-
qmFiles << QDir(".").entryList(QStringList("*.qm"));
5149

5250
// add menu entry for all the files
5351
QList<QAction *> actions;

0 commit comments

Comments
 (0)