1
0
mirror of https://github.com/luanti-org/luanti.git synced 2025-12-17 04:25:26 +01:00

Add self-extracting launcher for Windows

This commit is contained in:
sfan5
2025-12-02 21:18:24 +01:00
parent 92709b4671
commit ac7fb75ea3
7 changed files with 180 additions and 18 deletions

View File

@@ -33,40 +33,64 @@ on:
jobs: jobs:
mingw: mingw:
name: "MinGW cross-compiler (${{ matrix.bits }}-bit)" name: "MinGW cross-compiler (${{ matrix.config.bits }}-bit)"
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
bits: [32, 64] config:
- { bits: 32, nsis: false }
- { bits: 64, nsis: true }
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
- name: Install compiler - name: Install compiler
run: | run: |
sudo dpkg --add-architecture i386 source ./util/ci/common.sh
sudo apt-get update install_mingw_deps '${{matrix.config.bits}}' '${{matrix.config.nsis}}'
sudo apt-get install -y --no-install-recommends gettext wine wine${{ matrix.bits }} if '${{matrix.config.nsis}}'; then
echo 'CMAKE_CXX_COMPILER_LAUNCHER=ccache' >>$GITHUB_ENV
fi
sudo ./util/buildbot/download_toolchain.sh /usr sudo ./util/buildbot/download_toolchain.sh /usr
- name: Build - name: Build
run: | run: |
EXISTING_MINETEST_DIR=$PWD \ EXISTING_MINETEST_DIR=$PWD \
./util/buildbot/buildwin${{ matrix.bits }}.sh B ./util/buildbot/buildwin${{ matrix.config.bits }}.sh B
mkdir -p artifact
cp -v B/build/*.zip artifact/
# Check that the resulting binary can run (DLLs etc.) # Check that the resulting binary can run (DLLs etc.)
- name: Runtime test - name: Runtime test
run: | run: |
dest=$(mktemp -d) dest=$(mktemp -d)
unzip -q -d "$dest" B/build/*.zip unzip -q -d "$dest" artifact/*.zip
cd "$dest"/luanti-*-win* cd "$dest"/luanti-*-win*
wine bin/luanti.exe --version wine bin/luanti.exe --version
- name: Build for NSIS
run: |
EXISTING_MINETEST_DIR=$PWD \
./util/buildbot/buildwin${{ matrix.config.bits }}.sh B -DRUN_IN_PLACE=0
dest=$(mktemp -d)
unzip -q -d "$dest" B/build/*.zip
cd "$dest"/luanti-*-nsis
makensis -WX -V3 sfx-launcher.nsi
cp -v "$dest"/*.exe $GITHUB_WORKSPACE/artifact/
if: ${{ matrix.config.nsis }}
- uses: actions/upload-artifact@v5 - uses: actions/upload-artifact@v5
with: with:
name: "mingw${{ matrix.bits }}" name: "mingw${{ matrix.config.bits }}"
path: B/build/*.zip path: artifact/*.zip
if-no-files-found: error if-no-files-found: error
- uses: actions/upload-artifact@v5
with:
name: "mingw${{ matrix.config.bits }}-nsis"
path: artifact/*.exe
if-no-files-found: error
if: ${{ matrix.config.nsis }}
msvc: msvc:
name: VS 2022 ${{ matrix.config.arch }} name: VS 2022 ${{ matrix.config.arch }}
runs-on: windows-2025 runs-on: windows-2025

View File

@@ -301,7 +301,7 @@ add_subdirectory(lib/tiniergltf)
# Be sure to add all relevant definitions above this # Be sure to add all relevant definitions above this
add_subdirectory(src) add_subdirectory(src)
# CPack # Package generation
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A free open-source voxel game engine with easy modding and game creation.") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A free open-source voxel game engine with easy modding and game creation.")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
@@ -327,6 +327,21 @@ if(WIN32)
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32")
endif() endif()
if(NOT RUN_IN_PLACE)
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-nsis")
install(FILES "misc/luanti-icon.ico" DESTINATION ".")
install(FILES "misc/sfx-launcher.nsi" DESTINATION ".")
# normalize to 0/1
set(DEVELOPMENT_BUILD01 0)
if(DEVELOPMENT_BUILD)
set(DEVELOPMENT_BUILD01 1)
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/misc/meta.nsh.in"
"${CMAKE_CURRENT_BINARY_DIR}/misc/meta.nsh" @ONLY ESCAPE_QUOTES)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/misc/meta.nsh" DESTINATION ".")
endif()
# we just generate a ZIP file and someone has to run makensis manually
set(CPACK_GENERATOR ZIP) set(CPACK_GENERATOR ZIP)
elseif(APPLE) elseif(APPLE)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)

6
misc/meta.nsh.in Normal file
View File

@@ -0,0 +1,6 @@
!define PROJECT_NAME "@PROJECT_NAME@"
!define PROJECT_NAME_C "@PROJECT_NAME_CAPITALIZED@"
!define VERSION_STRING "@VERSION_STRING@"
!define DEVELOPMENT_BUILD @DEVELOPMENT_BUILD01@
!define INPATH "."
!define ICONPATH "./luanti-icon.ico"

100
misc/sfx-launcher.nsi Normal file
View File

@@ -0,0 +1,100 @@
!include "meta.nsh"
# useful docs: <https://nsis.sourceforge.io/Docs/Chapter4.html>
OutFile "..\${PROJECT_NAME_C}-${VERSION_STRING}.exe"
Name "${PROJECT_NAME_C}"
Icon "${ICONPATH}"
SetCompressor /SOLID lzma
SetDateSave off
RequestExecutionLevel user
VIAddVersionKey "CompanyName" "${PROJECT_NAME_C} community"
VIAddVersionKey "FileDescription" "${PROJECT_NAME_C} self-extracting launcher"
VIAddVersionKey "FileVersion" "${VERSION_STRING}"
VIAddVersionKey "ProductName" "${PROJECT_NAME_C}"
VIAddVersionKey "InternalName" "${PROJECT_NAME}"
VIAddVersionKey "LegalCopyright" "(c) 2010-2025 Perttu Ahola (celeron55) and contributors"
# these are required, but don't take arbitrary strings
VIProductVersion "0.0.0.0"
VIFileVersion "0.0.0.0"
!if ${DEVELOPMENT_BUILD} == 1
# since the version string needs to be unique for the "extract once" logic to work,
# and dev builds may not have one we choose to just always extract
!define TARGET_DIR "$TEMP\${PROJECT_NAME}-dev"
!else
!if ${DEVELOPMENT_BUILD} == 0
!define TARGET_DIR "$LOCALAPPDATA\${PROJECT_NAME}\${VERSION_STRING}"
# signals successful extraction
!define DUMMY_FILE "${TARGET_DIR}\.extracted"
!else
!error invalid value for DEVELOPMENT_BUILD
!endif
!endif
!define EXE_FILE "${TARGET_DIR}\bin\${PROJECT_NAME}.exe"
!include "LogicLib.nsh"
!include "FileFunc.nsh"
# including MUI.nsh would cause a warning, so we have to use numbers :(
# these are LCIDs (Language Code Identifiers)
LangString BannerText 1033 "Extracting, please wait..."
LangString BannerText 1031 "Extrahiere, bitte warten..."
LangString ErrorText 1033 "An error occurred!"
LangString ErrorText 1031 "Ein Fehler ist aufgetreten!"
Var needExtract
Function .onInit
SetSilent silent
StrCpy $needExtract 1
!if ${DEVELOPMENT_BUILD} == 0
# the *.* checks if a directory exists
${If} ${FileExists} "${EXE_FILE}"
${AndIf} ${FileExists} "${TARGET_DIR}\builtin\*.*"
${AndIf} ${FileExists} "${TARGET_DIR}\client\*.*"
${AndIf} ${FileExists} "${TARGET_DIR}\textures\*.*"
${AndIf} ${FileExists} "${DUMMY_FILE}"
StrCpy $needExtract 0
${EndIf}
!endif
FunctionEnd
Section
ClearErrors
${If} $needExtract == 1
Banner::show /NOUNLOAD "$(BannerText)"
!if ${DEVELOPMENT_BUILD} == 1
RMDir /r "${TARGET_DIR}"
!endif
CreateDirectory "${TARGET_DIR}"
SetOutPath "${TARGET_DIR}"
File /r /x *.nsi /x *.nsh "${INPATH}\*.*"
${If} ${Errors}
MessageBox MB_ICONSTOP "$(ErrorText)"
Abort
${EndIf}
!if ${DEVELOPMENT_BUILD} == 0
FileOpen $0 "${DUMMY_FILE}" w
FileClose $0
SetFileAttributes "${DUMMY_FILE}" HIDDEN
!endif
Banner::destroy
${EndIf}
!if ${DEVELOPMENT_BUILD} == 0
# replace shortcut with last-launched version regardless of if we had to extract
# (last param is the description text)
CreateShortcut /NoWorkingDir "$DESKTOP\${PROJECT_NAME_C}.lnk" "${EXE_FILE}" \
"" "" "" "" "" "${PROJECT_NAME_C} ${VERSION_STRING}"
CreateShortcut /NoWorkingDir "$SMPROGRAMS\${PROJECT_NAME_C}.lnk" "${EXE_FILE}" \
"" "" "" "" "" "${PROJECT_NAME_C} ${VERSION_STRING}"
!endif
Exec '"${EXE_FILE}"'
SectionEnd

View File

@@ -2,11 +2,12 @@
set -e set -e
topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ $# -ne 1 ]; then if [ $# -lt 1 ]; then
echo "Usage: $0 <build directory>" echo "Usage: $0 <build directory> [extra cmake args...]"
exit 1 exit 1
fi fi
builddir=$1 builddir=$1
shift
mkdir -p $builddir mkdir -p $builddir
builddir="$( cd "$builddir" && pwd )" builddir="$( cd "$builddir" && pwd )"
libdir=$builddir/libs libdir=$builddir/libs
@@ -63,6 +64,7 @@ cmake_args=(
-DENABLE_LEVELDB=1 -DENABLE_LEVELDB=1
) )
add_cmake_libs add_cmake_libs
cmake_args+=("$@")
cmake -S $sourcedir -B build "${cmake_args[@]}" cmake -S $sourcedir -B build "${cmake_args[@]}"
cmake --build build -j$(nproc) cmake --build build -j$(nproc)

View File

@@ -2,11 +2,12 @@
set -e set -e
topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ $# -ne 1 ]; then if [ $# -lt 1 ]; then
echo "Usage: $0 <build directory>" echo "Usage: $0 <build directory> [extra cmake args...]"
exit 1 exit 1
fi fi
builddir=$1 builddir=$1
shift
mkdir -p $builddir mkdir -p $builddir
builddir="$( cd "$builddir" && pwd )" builddir="$( cd "$builddir" && pwd )"
libdir=$builddir/libs libdir=$builddir/libs
@@ -44,7 +45,7 @@ download "$libhost/llvm/libjpeg-$libjpeg_version-win64.zip"
download "$libhost/llvm/libpng-$libpng_version-win64.zip" download "$libhost/llvm/libpng-$libpng_version-win64.zip"
download "$libhost/llvm/sdl2-$sdl2_version-win64.zip" download "$libhost/llvm/sdl2-$sdl2_version-win64.zip"
# Set source dir, downloading Minetest as needed # Set source dir, downloading Luanti as needed
get_sources get_sources
# Build the thing # Build the thing
@@ -63,6 +64,7 @@ cmake_args=(
-DENABLE_LEVELDB=1 -DENABLE_LEVELDB=1
) )
add_cmake_libs add_cmake_libs
cmake_args+=("$@")
cmake -S $sourcedir -B build "${cmake_args[@]}" cmake -S $sourcedir -B build "${cmake_args[@]}"
cmake --build build -j$(nproc) cmake --build build -j$(nproc)

View File

@@ -32,6 +32,19 @@ install_linux_deps() {
fi fi
} }
# Linux -> win32 cross-compiling only
install_mingw_deps() {
local bits=$1
local nsis=$2
local pkgs=(gettext wine wine$bits)
[[ "$nsis" == "true" ]] && pkgs+=(nsis ccache)
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y --no-install-recommends "${pkgs[@]}"
}
# macOS build only # macOS build only
install_macos_brew_deps() { install_macos_brew_deps() {
# Uninstall the bundled cmake, it is outdated, and brew does not want to install the newest version with this one present since they are from different taps. # Uninstall the bundled cmake, it is outdated, and brew does not want to install the newest version with this one present since they are from different taps.
@@ -50,8 +63,8 @@ install_macos_brew_deps() {
} }
install_macos_precompiled_deps() { install_macos_precompiled_deps() {
osver=$1 local osver=$1
arch=$2 local arch=$2
local pkgs=( local pkgs=(
cmake wget cmake wget