Skip to content

Commit 55ba2d7

Browse files
committed
add option to build static exe
1 parent 5c06fb0 commit 55ba2d7

10 files changed

Lines changed: 625 additions & 131 deletions

File tree

.github/workflows/release.yml

Lines changed: 154 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,213 @@
1-
name: Release Build
1+
name: Build & Release
22

33
on:
44
push:
55
branches: [ "main", "master" ]
66
workflow_dispatch:
7-
inputs:
8-
version:
9-
description: 'Release version (e.g., 1.0.0)'
10-
required: true
11-
type: string
12-
changelog:
13-
description: 'Changelog/Release notes (use " - " to separate items)'
14-
required: false
15-
type: string
16-
default: 'Manual release'
7+
# No inputs needed - manual runs are just for testing
178

189
permissions:
1910
contents: write
2011

12+
env:
13+
QT_VERSION: '6.6.0'
14+
2115
jobs:
22-
build-and-release:
23-
if: github.event_name == 'workflow_dispatch' || contains(github.event.head_commit.message, 'release:')
16+
build:
2417
runs-on: windows-latest
2518

2619
steps:
2720
- uses: actions/checkout@v4
2821
with:
2922
fetch-depth: 0
3023

31-
- name: Install Qt
32-
uses: jurplel/install-qt-action@v3
24+
- name: Setup MSVC
25+
uses: ilammy/msvc-dev-cmd@v1
3326
with:
34-
version: '6.6.0'
35-
host: 'windows'
36-
target: 'desktop'
37-
arch: 'win64_mingw'
38-
modules: 'qtnetworkauth'
39-
cache: true
40-
41-
- name: Setup MinGW
42-
run: |
43-
choco install mingw --version=11.2.0.07112021 --force -y
44-
echo "C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
45-
shell: pwsh
27+
arch: x64
4628

4729
- name: Setup CMake
4830
uses: jwlawson/actions-setup-cmake@v1.14
4931
with:
5032
cmake-version: '3.27.x'
5133

52-
- name: Configure CMake
34+
- name: Setup Ninja
35+
uses: ashutoshvarma/setup-ninja@v1.1
36+
37+
- name: Cache Static Qt
38+
id: cache-qt-static
39+
uses: actions/cache@v4
40+
with:
41+
path: C:\Qt\Static
42+
key: qt-static-${{ env.QT_VERSION }}-msvc-v6
43+
restore-keys: |
44+
qt-static-${{ env.QT_VERSION }}-msvc-
45+
46+
- name: Download and Build Static Qt
47+
if: steps.cache-qt-static.outputs.cache-hit != 'true'
48+
shell: pwsh
5349
run: |
54-
mkdir build
55-
cd build
56-
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ..
57-
shell: cmd
50+
Write-Host "Downloading Qt ${{ env.QT_VERSION }} source..."
51+
52+
# Install aqtinstall
53+
pip install aqtinstall
54+
55+
# Download Qt source (qtbase only)
56+
New-Item -ItemType Directory -Force -Path "C:\Qt\Source"
57+
aqt install-src windows ${{ env.QT_VERSION }} --outputdir "C:\Qt\Source" --archives qtbase
58+
59+
# Navigate to qtbase source directory (it's inside Src/qtbase)
60+
$qtbasePath = "C:\Qt\Source\${{ env.QT_VERSION }}\Src\qtbase"
61+
if (-not (Test-Path $qtbasePath)) {
62+
Write-Host "ERROR: qtbase not found at $qtbasePath"
63+
Get-ChildItem "C:\Qt\Source" -Recurse -Depth 4 | Select-Object FullName
64+
exit 1
65+
}
66+
67+
Set-Location $qtbasePath
68+
Write-Host "Building from: $qtbasePath"
69+
70+
# Verify configure.bat exists
71+
if (-not (Test-Path "configure.bat")) {
72+
Write-Host "ERROR: configure.bat not found!"
73+
Get-ChildItem
74+
exit 1
75+
}
76+
77+
# Configure Qt for static build with MSVC
78+
Write-Host "Configuring Qt for static build..."
79+
& cmd /c "configure.bat -release -static -static-runtime -prefix C:\Qt\Static\${{ env.QT_VERSION }} -opensource -confirm-license -nomake examples -nomake tests -schannel -no-opengl -no-feature-sql"
80+
81+
if ($LASTEXITCODE -ne 0) {
82+
Write-Host "Qt configure failed!"
83+
exit 1
84+
}
85+
86+
Write-Host "Building Qt (this takes 1-2 hours)..."
87+
cmake --build . --parallel
88+
89+
if ($LASTEXITCODE -ne 0) {
90+
Write-Host "Qt build failed!"
91+
exit 1
92+
}
93+
94+
Write-Host "Installing Qt..."
95+
cmake --install .
96+
97+
Write-Host "Static Qt build complete!"
5898
59-
- name: Build
99+
- name: Build SteamLuaPatcher (Static)
100+
shell: pwsh
60101
run: |
61-
cd build
102+
# Set Qt path
103+
$env:CMAKE_PREFIX_PATH = "C:\Qt\Static\${{ env.QT_VERSION }}"
104+
$env:Qt6_DIR = "C:\Qt\Static\${{ env.QT_VERSION }}"
105+
106+
# Clean and create build directory
107+
if (Test-Path build) { Remove-Item -Recurse -Force build }
108+
New-Item -ItemType Directory -Force -Path build
109+
Set-Location build
110+
111+
Write-Host "Configuring CMake with static Qt..."
112+
cmake -G "Ninja" `
113+
-DCMAKE_BUILD_TYPE=Release `
114+
-DBUILD_STATIC=ON `
115+
-DCMAKE_PREFIX_PATH="C:\Qt\Static\${{ env.QT_VERSION }}" `
116+
..
117+
118+
if ($LASTEXITCODE -ne 0) {
119+
Write-Host "CMake configuration failed!"
120+
exit 1
121+
}
122+
123+
Write-Host "Building..."
62124
cmake --build . --config Release
63-
shell: cmd
125+
126+
if ($LASTEXITCODE -ne 0) {
127+
Write-Host "Build failed!"
128+
exit 1
129+
}
64130
65-
- name: Create Distribution Package
66-
run: |
67-
mkdir dist
68-
copy build\SteamLuaPatcher.exe dist\
69-
if exist logo.ico copy logo.ico dist\
70-
cd dist
71-
windeployqt SteamLuaPatcher.exe --release --no-translations
72-
shell: cmd
73-
74-
- name: Create Installer (Optional - using NSIS)
131+
- name: Prepare Artifact
132+
shell: pwsh
75133
run: |
76-
echo "Skipping installer creation - direct exe distribution"
77-
shell: cmd
134+
# Create dist folder
135+
New-Item -ItemType Directory -Force -Path dist
136+
137+
# Copy standalone exe
138+
Copy-Item "build\SteamLuaPatcher.exe" "dist\"
139+
140+
# Get file info
141+
$exe = Get-Item "dist\SteamLuaPatcher.exe"
142+
$sizeMB = [math]::Round($exe.Length / 1MB, 2)
143+
Write-Host "Standalone executable size: $sizeMB MB"
78144
79-
- name: Package Release
80-
run: |
81-
cd dist
82-
7z a ..\SteamLuaPatcher-Windows.zip *
83-
shell: cmd
145+
- name: Upload Build Artifact
146+
uses: actions/upload-artifact@v4
147+
with:
148+
name: SteamLuaPatcher-Standalone
149+
path: dist/SteamLuaPatcher.exe
150+
retention-days: 30
84151

85-
- name: Extract Version from Commit Message
86-
id: get_info
152+
# Only create release if commit message contains "release:"
153+
- name: Check for Release
154+
id: check_release
155+
if: github.event_name == 'push'
87156
shell: pwsh
88157
run: |
89-
# Check if this is a manual trigger
90-
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
91-
$version = "${{ github.event.inputs.version }}"
92-
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
93-
echo "Manual trigger - Version: $version"
158+
$msg = "${{ github.event.head_commit.message }}"
159+
if ($msg -match "(?i)release:\s*v?([\d\.]+)") {
160+
$version = $matches[1]
161+
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
162+
echo "IS_RELEASE=true" >> $env:GITHUB_OUTPUT
163+
Write-Host "Release detected: v$version"
94164
} else {
95-
# Extract from commit message
96-
$msg = "${{ github.event.head_commit.message }}"
97-
if ($msg -match "(?i)release:\s*v?([\d\.]+)") {
98-
$version = $matches[1]
99-
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
100-
echo "Commit trigger - Found version: $version"
101-
} else {
102-
echo "VERSION=latest" >> $env:GITHUB_OUTPUT
103-
echo "No specific version found, using 'latest'"
104-
}
165+
echo "IS_RELEASE=false" >> $env:GITHUB_OUTPUT
166+
Write-Host "Not a release commit"
105167
}
106168
107169
- name: Generate Changelog
108170
id: changelog
171+
if: steps.check_release.outputs.IS_RELEASE == 'true'
109172
shell: pwsh
110173
run: |
111-
# Check if this is a manual trigger
112-
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
113-
$changelog = "${{ github.event.inputs.changelog }}"
114-
if ($changelog) {
115-
# Split by " - " if multiple items
116-
$parts = $changelog -split " - "
117-
$formattedLog = ""
118-
foreach ($part in $parts) {
119-
$part = $part.Trim()
120-
if ($part) {
121-
$formattedLog += "- $part`n"
122-
}
123-
}
124-
$changelog = $formattedLog
125-
} else {
126-
$changelog = "- Manual release"
127-
}
128-
echo "Manual trigger changelog"
129-
} else {
130-
# Extract from commit message
131-
$msg = "${{ github.event.head_commit.message }}"
132-
$parts = $msg -split " - "
133-
$changelog = ""
134-
foreach ($part in $parts) {
135-
if ($part -match "^release:") { continue }
136-
$changelog += "- $part`n"
137-
}
138-
if (-not $changelog) {
139-
$changelog = $msg
140-
}
174+
$msg = "${{ github.event.head_commit.message }}"
175+
$parts = $msg -split " - "
176+
$changelog = ""
177+
foreach ($part in $parts) {
178+
if ($part -match "^release:") { continue }
179+
$part = $part.Trim()
180+
if ($part) {
181+
$changelog += "- $part`n"
182+
}
183+
}
184+
if (-not $changelog) {
185+
$changelog = "- Bug fixes and improvements"
141186
}
142187
143188
# Escape for GitHub Actions output
144189
$changelog = $changelog -replace '%', '%25' -replace '\n', '%0A' -replace '\r', '%0D'
145190
echo "LOGS=$changelog" >> $env:GITHUB_OUTPUT
146191
147192
- name: Create Release
193+
if: steps.check_release.outputs.IS_RELEASE == 'true'
148194
uses: softprops/action-gh-release@v1
149195
with:
150-
tag_name: v${{ steps.get_info.outputs.VERSION }}
151-
name: Release v${{ steps.get_info.outputs.VERSION }}
196+
tag_name: v${{ steps.check_release.outputs.VERSION }}
197+
name: Release v${{ steps.check_release.outputs.VERSION }}
152198
body: |
153-
## Changes
199+
## What's New
154200
${{ steps.changelog.outputs.LOGS }}
155201
156-
## Installation
157-
1. Download `SteamLuaPatcher-Windows.zip`
158-
2. Extract the archive
159-
3. Run `SteamLuaPatcher.exe`
202+
## Download & Run
203+
1. Download `SteamLuaPatcher.exe` below
204+
2. Double-click to run - **no installation required!**
205+
206+
> 📦 **This is a standalone executable** - no DLLs, no folders, just one file!
160207
161208
## Requirements
162-
- Windows 10/11
163-
- Visual C++ Redistributable (usually pre-installed)
209+
- Windows 10/11 (64-bit)
164210
files: |
165-
SteamLuaPatcher-Windows.zip
166211
dist/SteamLuaPatcher.exe
167212
draft: false
168213
prerelease: false

CMakeLists.txt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ set(CMAKE_AUTOMOC ON)
77
set(CMAKE_AUTORCC ON)
88
set(CMAKE_AUTOUIC ON)
99

10-
# Find Qt6
10+
# Option for static build
11+
option(BUILD_STATIC "Build with static Qt libraries" OFF)
12+
13+
# Find Qt6 - Core components only
1114
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network)
1215

1316
# Application icon resource (optional)
@@ -42,6 +45,11 @@ set(HEADERS
4245
src/config.h
4346
)
4447

48+
# Add static plugin initialization for static builds
49+
if(BUILD_STATIC)
50+
list(APPEND SOURCES src/static_plugins.cpp)
51+
endif()
52+
4553
# Create executable
4654
if(WIN32 AND APP_ICON_RESOURCE_WINDOWS)
4755
add_executable(SteamLuaPatcher WIN32 ${SOURCES} ${HEADERS} ${APP_ICON_RESOURCE_WINDOWS})
@@ -57,6 +65,31 @@ target_link_libraries(SteamLuaPatcher PRIVATE
5765
Qt6::Network
5866
)
5967

68+
# Static build configuration
69+
if(BUILD_STATIC)
70+
# Link static Qt plugins (only core plugins available in qtbase)
71+
target_link_libraries(SteamLuaPatcher PRIVATE
72+
Qt6::QWindowsIntegrationPlugin
73+
Qt6::QGifPlugin
74+
Qt6::QJpegPlugin
75+
Qt6::QICOPlugin
76+
Qt6::QWindowsVistaStylePlugin
77+
)
78+
79+
# Windows static linking flags for MSVC
80+
if(MSVC)
81+
set_property(TARGET SteamLuaPatcher PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
82+
endif()
83+
84+
# Windows static linking flags for MinGW
85+
if(MINGW)
86+
target_link_options(SteamLuaPatcher PRIVATE -static -static-libgcc -static-libstdc++)
87+
endif()
88+
89+
# Define static build macro
90+
target_compile_definitions(SteamLuaPatcher PRIVATE QT_STATIC_BUILD)
91+
endif()
92+
6093
# Windows-specific settings
6194
if(WIN32)
6295
set_target_properties(SteamLuaPatcher PROPERTIES

0 commit comments

Comments
 (0)