From d0d15508548a26d4739c76296b45a6223bb1063e Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 8 Mar 2026 12:05:58 -0700
Subject: [PATCH] Added GitHub workflows
---
.github/workflows/main.yml | 69 ++++++++++++++++++
CMakeLists.txt | 113 +++++++++++++++++++++++-------
cmake/CPackProjectConfig.cmake.in | 23 ++++++
utils/files.c | 10 ++-
4 files changed, 188 insertions(+), 27 deletions(-)
create mode 100644 .github/workflows/main.yml
create mode 100644 cmake/CPackProjectConfig.cmake.in
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..ad7caa2c
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,69 @@
+name: Build
+
+on: [push, pull_request]
+
+jobs:
+ Build:
+ name: ${{ matrix.platform.name }}
+ runs-on: ${{ matrix.platform.os }}
+
+ defaults:
+ run:
+ shell: ${{ matrix.platform.shell }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ platform:
+ - { name: Windows (MSVC), os: windows-latest, shell: sh, msvc: 1, artifact: 'Maelstrom-windows',
+ cmake: '-GNinja -DCMAKE_POLICY_DEFAULT_CMP0141=NEW -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase -DCMAKE_EXE_LINKER_FLAGS=-DEBUG -DCMAKE_SHARED_LINKER_FLAGS=-DEBUG' }
+ - { name: Linux, os: ubuntu-latest, shell: sh, linux: 1, cmake: '-GNinja', artifact: 'Maelstrom-linux' }
+ - { name: macOS, os: macos-latest, shell: sh, artifact: 'Maelstrom-macos',
+ cmake: '-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0' }
+
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ submodules: ${{ 'recursive' }}
+ - uses: ilammy/msvc-dev-cmd@v1
+ if: ${{ matrix.platform.msvc }}
+ with:
+ arch: x64
+ - name: 'Install Linux dependencies'
+ if: ${{ matrix.platform.linux }}
+ run: |
+ sudo apt-get update -y
+ sudo apt-get install -y \
+ gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev \
+ libusb-1.0-0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \
+ libxss-dev libwayland-dev libxtst-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \
+ libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
+ - name: Configure (CMake)
+ run: |
+ export CMAKE_CONFIGURATION_TYPES=Release
+ cmake -B build \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INSTALL_PREFIX=prefix_cmake \
+ -DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=$PWD/build \
+ -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=$PWD/build \
+ ${{ matrix.platform.cmake }}
+ - name: Build (CMake)
+ id: build
+ run: cmake --build build/ --config Release --parallel --verbose
+ - name: Install (CMake)
+ if: ${{ always() && steps.build.outcome == 'success' }}
+ run: |
+ set -eu
+ rm -fr DESTDIR-cmake
+ cmake --install build/ --config Release
+ echo "Maelstrom=$(pwd)/prefix_cmake" >> $GITHUB_ENV
+ ( cd prefix_cmake; find . ) | LC_ALL=C sort -u
+ - name: Package (CPack)
+ if: ${{ always() && steps.build.outcome == 'success' }}
+ run: |
+ cmake --build build/ --target package
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v6
+ with:
+ name: "${{ matrix.platform.artifact }}"
+ path: '${{ github.workspace }}/build/dist/Maelstrom*'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38dbae82..b6ba107c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,13 @@
cmake_minimum_required(VERSION 3.0...4.0)
-project(Maelstrom C CXX)
-include(GNUInstallDirs)
+set(MAJOR_VERSION 4)
+set(MINOR_VERSION 0)
+set(MICRO_VERSION 0)
-if(WIN32)
- set(GAME_INSTALLDIR ".")
-else()
- set(GAME_INSTALLDIR "${CMAKE_INSTALL_PREFIX}/games/${PROJECT_NAME}")
-endif()
+project(Maelstrom
+ LANGUAGES C CXX
+ VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}"
+)
# set the output directory for built objects.
# This makes sure that the dynamic library goes into the build directory automatically.
@@ -18,6 +18,9 @@ add_subdirectory(maclib)
add_subdirectory(external/SDL EXCLUDE_FROM_ALL)
add_subdirectory(external/SDL_net EXCLUDE_FROM_ALL)
+SDL_DetectTargetCPUArchitectures(SDL_CPU_NAMES)
+SDL_DetectCMakePlatform()
+
set(MAELSTROM_SOURCES
game/about.cpp
game/about.h
@@ -162,33 +165,93 @@ dep_option(STEAM "Build with Steam support" ON "WIN32 OR LINUX OR MACOS" OFF)
if(STEAM)
target_compile_definitions(Maelstrom PRIVATE ENABLE_STEAM)
- target_include_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/public")
- if(WIN32)
- target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/win64")
- target_link_libraries(Maelstrom PRIVATE steam_api64)
- elseif(LINUX)
- target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/linux64")
- target_link_libraries(Maelstrom PRIVATE steam_api)
- elseif(MACOS)
- target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/osx")
- target_link_libraries(Maelstrom PRIVATE steam_api)
- endif()
+ add_library(SteamworksSDK::steam_api SHARED IMPORTED)
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/public")
+ if(WIN32)
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/win64/steam_api64.dll")
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/win64/steam_api64.lib")
+ elseif(LINUX)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/linux32/libsteam_api.so")
+ else()
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/linux64/libsteam_api.so")
+ endif()
+ elseif(MACOS)
+ set_property(TARGET SteamworksSDK::steam_api PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/osx/libsteam_api.dylib")
+ endif()
+ target_link_libraries(Maelstrom PRIVATE SteamworksSDK::steam_api)
endif()
target_link_libraries(Maelstrom PRIVATE SDLmac)
target_link_libraries(Maelstrom PRIVATE SDL3::SDL3)
target_link_libraries(Maelstrom PRIVATE SDL3_net::SDL3_net)
-install(TARGETS Maelstrom DESTINATION "${GAME_INSTALLDIR}")
-install(DIRECTORY Data DESTINATION "${GAME_INSTALLDIR}")
+option(STANDALONE_INSTALL "Build Maelstrom installed into a single directory" TRUE)
+
+if(STANDALONE_INSTALL)
+ set(CMAKE_INSTALL_BINDIR ".")
+ set(CMAKE_INSTALL_LIBDIR ".")
+ set(CMAKE_INSTALL_DOCDIR "Docs")
+ set(GAME_INSTALL_DATADIR ".")
+ if(APPLE)
+ set_property(TARGET Maelstrom SDL3-shared SDL3_net-shared PROPERTY INSTALL_RPATH "@executable_path")
+ else()
+ set_property(TARGET Maelstrom SDL3-shared SDL3_net-shared PROPERTY INSTALL_RPATH "$ORIGIN")
+ endif()
+else()
+ include(GNUInstallDirs)
+ set(GAME_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}")
+
+ target_compile_definitions(Maelstrom PRIVATE MAELSTROM_DATA=\"${CMAKE_INSTALL_PREFIX}/${GAME_INSTALL_DATADIR}/Data/\")
+endif()
+
+install(TARGETS Maelstrom SDL3-shared SDL3_net-shared LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" NAMELINK_SKIP RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+if(STEAM)
+ install(IMPORTED_RUNTIME_ARTIFACTS SteamworksSDK::steam_api)
+endif()
+install(DIRECTORY Data DESTINATION "${GAME_INSTALL_DATADIR}")
file(GLOB docs "Docs/*.txt" "README*")
-install(FILES ${docs} "COPYING" DESTINATION "${GAME_INSTALLDIR}/Docs")
+install(FILES ${docs} "COPYING" TYPE DOC)
+
+#
+# Uninstall
+#
+configure_file(cmake/cmake_uninstall.cmake.in cmake_uninstall.cmake IMMEDIATE @ONLY)
-if(NOT TARGET uninstall)
- configure_file(cmake/cmake_uninstall.cmake.in cmake_uninstall.cmake IMMEDIATE @ONLY)
+add_custom_target(uninstall
+ COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
- add_custom_target(uninstall
- COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+#
+# Source package
+#
+find_package(Git QUIET)
+
+if(GIT_FOUND)
+ add_custom_target(package_sources
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/dist
+ COMMAND ${GIT_EXECUTABLE} archive HEAD -o "${PROJECT_BINARY_DIR}/dist/${PROJECT_NAME}-${PROJECT_VERSION}.zip" --prefix "${PROJECT_NAME}-${PROJECT_VERSION}/"
+ COMMAND ${GIT_EXECUTABLE} archive HEAD -o "${PROJECT_BINARY_DIR}/dist/${PROJECT_NAME}-${PROJECT_VERSION}.tar.gz" --prefix "${PROJECT_NAME}-${PROJECT_VERSION}/"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Creating source archive..."
+ VERBATIM
+ )
+else()
+ message(WARNING "Git not found, 'package_sources' target will not be available.")
endif()
+#
+# Binary package
+#
+
+if(MSVC)
+ set(CPACK_GENERATOR "ZIP")
+else()
+ set(CPACK_GENERATOR "TGZ")
+endif()
+configure_file(cmake/CPackProjectConfig.cmake.in CPackProjectConfig.cmake @ONLY)
+set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CPackProjectConfig.cmake")
+# CPACK_SOURCE_PACKAGE_FILE_NAME must end with "-src" (so we can block creating a source archive)
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-src")
+set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/dist")
+include(CPack)
diff --git a/cmake/CPackProjectConfig.cmake.in b/cmake/CPackProjectConfig.cmake.in
new file mode 100644
index 00000000..8b8045df
--- /dev/null
+++ b/cmake/CPackProjectConfig.cmake.in
@@ -0,0 +1,23 @@
+if(CPACK_PACKAGE_FILE_NAME MATCHES ".*-src$")
+ message(FATAL_ERROR "Creating source archives is not supported.")
+endif()
+
+set(PROJECT_NAME "@PROJECT_NAME@")
+set(PROJECT_VERSION "@PROJECT_VERSION@")
+set(PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@")
+set(SDL_CMAKE_PLATFORM "@SDL_CMAKE_PLATFORM@")
+set(SDL_CPU_NAMES "@SDL_CPU_NAMES@")
+list(SORT SDL_CPU_NAMES)
+
+string(TOLOWER "${SDL_CMAKE_PLATFORM}" SDL_CMAKE_PLATFORM)
+string(TOLOWER "${SDL_CPU_NAMES}" SDL_CPU_NAMES)
+if(lower_sdl_cmake_platform STREQUAL lower_sdl_cpu_names)
+ set(SDL_CPU_NAMES_WITH_DASHES)
+endif()
+
+string(REPLACE ";" "-" SDL_CPU_NAMES_WITH_DASHES "${SDL_CPU_NAMES}")
+if(SDL_CPU_NAMES_WITH_DASHES)
+ set(SDL_CPU_NAMES_WITH_DASHES "-${SDL_CPU_NAMES_WITH_DASHES}")
+endif()
+
+set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${SDL_CMAKE_PLATFORM}${SDL_CPU_NAMES_WITH_DASHES}")
diff --git a/utils/files.c b/utils/files.c
index fcb60395..1f057ff7 100644
--- a/utils/files.c
+++ b/utils/files.c
@@ -30,7 +30,6 @@ static char datapath[PATH_MAX];
bool InitFilesystem(const char *org, const char *app)
{
- const char *basepath;
const char *env = SDL_getenv("MAELSTROM_DATA");
storage_org = org;
@@ -41,7 +40,12 @@ bool InitFilesystem(const char *org, const char *app)
return true;
}
- basepath = SDL_GetBasePath();
+#ifdef MAELSTROM_DATA
+ SDL_strlcpy(datapath, MAELSTROM_DATA, sizeof(datapath));
+ return true;
+
+#else
+ const char *basepath = SDL_GetBasePath();
if (basepath) {
SDL_snprintf(datapath, sizeof(datapath), "%sData/", basepath);
if (SDL_GetPathInfo(datapath, NULL)) {
@@ -61,6 +65,8 @@ bool InitFilesystem(const char *org, const char *app)
SDL_strlcpy(datapath, "./", sizeof(datapath));
return true;
+
+#endif // MAELSTROM_DATA
}
SDL_IOStream *OpenRead(const char *file)