diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 254c0db..73a8baa 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -3,7 +3,7 @@ name: SporeModLoader
on: [push, pull_request]
jobs:
- build:
+ msvc-build:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
@@ -50,6 +50,14 @@ jobs:
with:
name: SporeModLoader-${{ env.GIT_REVISION }}
path: bin/*
+ # the modapi dlls cannot be compiled using mingw
+ # due to needing to keep ABI compatability with
+ # existing mods compiled with msvc
+ - name: Upload SporeModLoader (for mingw)
+ uses: actions/upload-artifact@v3
+ with:
+ name: SporeModLoader-mingw-${{ env.GIT_REVISION }}
+ path: bin/*
linux-build:
runs-on: ubuntu-20.04
steps:
@@ -61,9 +69,32 @@ jobs:
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
- name: Build SporeModManager (Linux)
run: |
- make BINARY_DIR=bin/SporeModLoader/SporeModManager -j$(nproc)
+ make SporeModManager -j$(nproc)
- name: Upload SporeModLoader (Linux)
uses: actions/upload-artifact@v3
with:
name: SporeModLoader-${{ env.GIT_REVISION }}
path: bin/*
+ mingw-build:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: 'true'
+ - name: Install Packages
+ run: |
+ sudo apt-get -y install gcc-mingw-w64-i686 g++-mingw-w64-i686
+ - name: Prepare Environment
+ run: |
+ echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
+ - name: Build SporeModLoader (mingw)
+ run: |
+ make SporeModLoader -j$(nproc)
+ - name: Build SporeModManager (mingw)
+ run: |
+ make SporeModManager.exe -j$(nproc)
+ - name: Upload SporeModLoader (mingw)
+ uses: actions/upload-artifact@v3
+ with:
+ name: SporeModLoader-mingw-${{ env.GIT_REVISION }}
+ path: bin/*
diff --git a/Makefile b/Makefile
index c973453..20750a9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,85 +1,30 @@
#
# SporeModManager Makefile
#
-THIRDPARTY_DIR := 3rdParty
-BINARY_DIR := bin
-SOURCE_DIR := SporeModManager
-EXE_FILE := SporeModManager
-VERBOSE := 0
+SOURCE_DIR := $(CURDIR)
+THIRDPARTY_DIR := $(SOURCE_DIR)/3rdParty
-PKG_CONFIG := pkg-config
CC := gcc
CXX := g++
-CFLAGS := \
- -I$(THIRDPARTY_DIR)/zlib \
- -I$(THIRDPARTY_DIR)/zlib/contrib/minizip
-CXXFLAGS := -std=c++17 \
- -I$(SOURCE_DIR) \
- -I$(THIRDPARTY_DIR)/tinyxml2 \
- -I$(THIRDPARTY_DIR)/zlib \
- -I$(THIRDPARTY_DIR)/zlib/contrib/minizip
-OPTFLAGS := -Os -flto
-LDFLAGS := -flto -s
+MINGW_CC := i686-w64-mingw32-gcc
+MINGW_CXX := i686-w64-mingw32-g++
-OBJECT_FILES := \
- $(SOURCE_DIR)/SporeModManagerHelpers/FileVersion.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/Path.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/SporeMod.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/SporeModXml.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/String.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/UI.o \
- $(SOURCE_DIR)/SporeModManagerHelpers/Zip.o \
- $(SOURCE_DIR)/SporeModManager.o \
- $(SOURCE_DIR)/main.o
+export THIRDPARTY_DIR CC CXX MINGW_CC MINGW_CXX
-HEADER_FILES := \
- $(SOURCE_DIR)/SporeModManager.hpp \
- $(SOURCE_DIR)/SporeModManagerHelpers.hpp
+all: SporeModLoader SporeModManager SporeModManager.exe
+clean:
+ $(MAKE) -C SporeModLoader clean BINARY_DIR=$(SOURCE_DIR)/bin/SporebinEP1
+ $(MAKE) -C SporeModManager clean BINARY_DIR=$(SOURCE_DIR)/bin/SporeModLoader/SporeModManager
+ $(MAKE) -C SporeModManager clean MINGW=1 BINARY_DIR=$(SOURCE_DIR)/bin/SporeModLoader/SporeModManager
-THIRDPARTY_OBJECT_FILES := \
- $(THIRDPARTY_DIR)/tinyxml2/tinyxml2.o \
- $(THIRDPARTY_DIR)/zlib/adler32.o \
- $(THIRDPARTY_DIR)/zlib/crc32.o \
- $(THIRDPARTY_DIR)/zlib/inflate.o \
- $(THIRDPARTY_DIR)/zlib/inffast.o \
- $(THIRDPARTY_DIR)/zlib/inftrees.o \
- $(THIRDPARTY_DIR)/zlib/zutil.o \
- $(THIRDPARTY_DIR)/zlib/contrib/minizip/unzip.o \
- $(THIRDPARTY_DIR)/zlib/contrib/minizip/ioapi.o
-
-THIRDPARTY_HEADER_FILES := \
- $(THIRDPARTY_DIR)/zlib/zconf.h
-
-
-ifeq ($(VERBOSE), 0)
- QUIET := @
-else
- QUIET :=
-endif
-
-%.o: %.c $(THIRDPARTY_HEADER_FILES)
- @echo "CC $<"
- $(QUIET)$(CC) -c $< -o $@ $(OPTFLAGS) $(CFLAGS)
-
-%.o: %.cpp $(HEADER_FILES) $(THIRDPARTY_HEADER_FILES)
- @echo "CXX $<"
- $(QUIET)$(CXX) -c $< -o $@ $(OPTFLAGS) $(CXXFLAGS)
-
-all: $(BINARY_DIR)/$(EXE_FILE)
-
-$(BINARY_DIR):
- $(QUIET)mkdir -p $@
-
-$(THIRDPARTY_DIR)/zlib/zconf.h:
- @echo "GEN $@"
- $(QUIET)cp $@.in $@
+SporeModLoader:
+ $(MAKE) -C $@ SOURCE_DIR=$(SOURCE_DIR)/$@ BINARY_DIR=$(SOURCE_DIR)/bin/SporebinEP1
-$(BINARY_DIR)/$(EXE_FILE): $(BINARY_DIR) $(THIRDPARTY_OBJECT_FILES) $(OBJECT_FILES)
- @echo "LD $@"
- $(QUIET)$(CXX) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) -o $@ $(LDFLAGS)
+SporeModManager:
+ $(MAKE) -C $@ SOURCE_DIR=$(SOURCE_DIR)/$@ BINARY_DIR=$(SOURCE_DIR)/bin/SporeModLoader/SporeModManager
-clean:
- rm -f $(BINARY_DIR)/$(EXE_FILE) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) $(THIRDPARTY_HEADER_FILES)
+SporeModManager.exe:
+ $(MAKE) -C $(basename $@) SOURCE_DIR=$(SOURCE_DIR)/$(basename $@) BINARY_DIR=$(SOURCE_DIR)/bin/SporeModLoader/SporeModManager MINGW=1
-.PHONY: all clean
+.PHONY: SporeModLoader SporeModManager SporeModManager.exe all clean
diff --git a/SporeModLoader/Makefile b/SporeModLoader/Makefile
new file mode 100644
index 0000000..999ec21
--- /dev/null
+++ b/SporeModLoader/Makefile
@@ -0,0 +1,57 @@
+#
+# SporeModLoader Makefile
+#
+THIRDPARTY_DIR ?= ../3rdParty
+BINARY_DIR ?= bin
+SOURCE_DIR ?= .
+DLL_FILE ?= dinput8.dll
+VERBOSE ?= 0
+
+MINGW_CXX ?= i686-w64-mingw32-g++
+CXXFLAGS := -std=c++17 \
+ -I$(SOURCE_DIR) \
+ -I$(THIRDPARTY_DIR)/Detours/src \
+ -Wno-attributes -Wp,-w
+OPTFLAGS := -Os -flto
+LDFLAGS := -s -flto
+
+OBJECT_FILES := \
+ $(SOURCE_DIR)/SporeModLoaderHelpers.obj \
+ $(SOURCE_DIR)/SporeModLoader.obj \
+ $(SOURCE_DIR)/dllmain.obj
+
+HEADER_FILES := \
+ $(SOURCE_DIR)/SporeModLoaderHelpers.hpp \
+ $(SOURCE_DIR)/SporeModLoader.hpp
+
+THIRDPARTY_OBJECT_FILES := \
+ $(THIRDPARTY_DIR)/Detours/src/detours.obj \
+ $(THIRDPARTY_DIR)/Detours/src/modules.obj \
+ $(THIRDPARTY_DIR)/Detours/src/disasm.obj \
+ $(THIRDPARTY_DIR)/Detours/src/image.obj \
+ $(THIRDPARTY_DIR)/Detours/src/creatwth.obj \
+ $(THIRDPARTY_DIR)/Detours/src/disolx86.obj
+
+ifeq ($(VERBOSE), 0)
+ QUIET := @
+else
+ QUIET :=
+endif
+
+%.obj: %.cpp $(HEADER_FILES)
+ @echo "MINGW_CXX $<"
+ $(QUIET)$(MINGW_CXX) -c $< -o $@ $(OPTFLAGS) $(CXXFLAGS)
+
+all: $(BINARY_DIR)/$(DLL_FILE)
+
+$(BINARY_DIR):
+ $(QUIET)mkdir -p $@
+
+$(BINARY_DIR)/$(DLL_FILE): $(BINARY_DIR) $(THIRDPARTY_OBJECT_FILES) $(OBJECT_FILES)
+ @echo "MINGW_LD $@"
+ $(QUIET)$(MINGW_CXX) $(THIRDPARTY_OBJECT_FILES) $(OBJECT_FILES) -static -shared $(SOURCE_DIR)/dllmain.def -o $@ $(LDFLAGS)
+
+clean:
+ rm -f $(BINARY_DIR)/$(DLL_FILE) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) $(THIRDPARTY_HEADER_FILES)
+
+.PHONY: all clean
\ No newline at end of file
diff --git a/SporeModLoader/SporeModLoader.cpp b/SporeModLoader/SporeModLoader.cpp
index 6e05d5c..e2ec859 100644
--- a/SporeModLoader/SporeModLoader.cpp
+++ b/SporeModLoader/SporeModLoader.cpp
@@ -7,7 +7,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-#include
+#include
#include "SporeModLoader.hpp"
#include "SporeModLoaderHelpers.hpp"
diff --git a/SporeModLoader/SporeModLoaderHelpers.cpp b/SporeModLoader/SporeModLoaderHelpers.cpp
index 996c056..5ccaf0e 100644
--- a/SporeModLoader/SporeModLoaderHelpers.cpp
+++ b/SporeModLoader/SporeModLoaderHelpers.cpp
@@ -7,7 +7,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-#include
+#include
#include
@@ -145,7 +145,8 @@ std::vector Path::GetModLibsPaths(void)
std::wstring filename = entry.path().filename().wstring();
for (const auto& postfix : excludePostfixes)
{
- if (filename.ends_with(postfix))
+ // HACK: TODO: rewrite ends_with in C++17
+ if (filename.find(postfix) != std::wstring::npos)
{
skipLib = true;
break;
diff --git a/SporeModLoader/dllmain.cpp b/SporeModLoader/dllmain.cpp
index 3bc4c5b..dae9b59 100644
--- a/SporeModLoader/dllmain.cpp
+++ b/SporeModLoader/dllmain.cpp
@@ -7,7 +7,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-#include
+#include
#include "detours.h"
#include "SporeModLoader.hpp"
@@ -46,7 +46,7 @@ static int SporeAppEntry_detoured(void)
// The game calls this function but ignores the result,
// so just return E_FAIL.
-HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter)
+extern "C" HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter)
{
return E_FAIL;
}
@@ -68,7 +68,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
- DetourAttach(&(PVOID&)SporeAppEntry_real, SporeAppEntry_detoured);
+ DetourAttach(&(PVOID&)SporeAppEntry_real, (PVOID)SporeAppEntry_detoured);
DetourTransactionCommit();
}
else if (dwReason == DLL_PROCESS_DETACH)
@@ -77,7 +77,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
DetourUpdateThread(GetCurrentThread());
if (SporeAppEntry_real != nullptr)
{
- DetourDetach(&(PVOID&)SporeAppEntry_real, SporeAppEntry_detoured);
+ DetourDetach(&(PVOID&)SporeAppEntry_real, (PVOID)SporeAppEntry_detoured);
}
DetourTransactionCommit();
}
diff --git a/SporeModManager/Makefile b/SporeModManager/Makefile
new file mode 100644
index 0000000..519654e
--- /dev/null
+++ b/SporeModManager/Makefile
@@ -0,0 +1,111 @@
+#
+# SporeModManager Makefile
+#
+THIRDPARTY_DIR ?= ../3rdParty
+BINARY_DIR ?= bin
+SOURCE_DIR ?= .
+EXE_FILE ?= SporeModManager
+VERBOSE ?= 0
+MINGW ?= 0
+
+CC ?= gcc
+CXX ?= g++
+MINGW_CC ?= i686-w64-mingw32-gcc
+MINGW_CXX ?= i686-w64-mingw32-g++
+
+ifeq ($(MINGW), 0)
+LDFLAGS := -flto -s
+OPTFLAGS := -Os -flto
+OBJ := o
+EXE_EXT :=
+else
+# mingw doesn't like LTO
+# and we need to statically link
+LDFLAGS := -s -municode -static
+OPTFLAGS := -Os
+OBJ := obj
+EXE_EXT := .exe
+endif
+CFLAGS := \
+ -I$(THIRDPARTY_DIR)/zlib \
+ -I$(THIRDPARTY_DIR)/zlib/contrib/minizip
+CXXFLAGS := -std=c++17 \
+ -I$(SOURCE_DIR) \
+ -I$(THIRDPARTY_DIR)/tinyxml2 \
+ -I$(THIRDPARTY_DIR)/zlib \
+ -I$(THIRDPARTY_DIR)/zlib/contrib/minizip
+
+OBJECT_FILES := \
+ $(SOURCE_DIR)/SporeModManagerHelpers/FileVersion.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/Path.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/SporeMod.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/SporeModXml.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/String.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/UI.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManagerHelpers/Zip.$(OBJ) \
+ $(SOURCE_DIR)/SporeModManager.$(OBJ) \
+ $(SOURCE_DIR)/main.$(OBJ)
+
+HEADER_FILES := \
+ $(SOURCE_DIR)/SporeModManager.hpp \
+ $(SOURCE_DIR)/SporeModManagerHelpers.hpp
+
+
+THIRDPARTY_OBJECT_FILES := \
+ $(THIRDPARTY_DIR)/tinyxml2/tinyxml2.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/adler32.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/crc32.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/inflate.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/inffast.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/inftrees.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/zutil.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/contrib/minizip/unzip.$(OBJ) \
+ $(THIRDPARTY_DIR)/zlib/contrib/minizip/ioapi.$(OBJ)
+
+THIRDPARTY_HEADER_FILES := \
+ $(THIRDPARTY_DIR)/zlib/zconf.h
+
+
+ifeq ($(VERBOSE), 0)
+ QUIET := @
+else
+ QUIET :=
+endif
+
+%.o: %.c $(THIRDPARTY_HEADER_FILES)
+ @echo "CC $<"
+ $(QUIET)$(CC) -c $< -o $@ $(OPTFLAGS) $(CFLAGS)
+
+%.o: %.cpp $(HEADER_FILES) $(THIRDPARTY_HEADER_FILES)
+ @echo "CXX $<"
+ $(QUIET)$(CXX) -c $< -o $@ $(OPTFLAGS) $(CXXFLAGS)
+
+%.obj: %.c $(THIRDPARTY_HEADER_FILES)
+ @echo "MINGW_CC $<"
+ $(QUIET)$(MINGW_CC) -c $< -o $@ $(OPTFLAGS) $(CFLAGS)
+
+%.obj: %.cpp $(HEADER_FILES) $(THIRDPARTY_HEADER_FILES)
+ @echo "MINGW_CXX $<"
+ $(QUIET)$(MINGW_CXX) -c $< -o $@ $(OPTFLAGS) $(CXXFLAGS)
+
+all: $(BINARY_DIR)/$(EXE_FILE)$(EXE_EXT)
+
+$(BINARY_DIR):
+ $(QUIET)mkdir -p $@
+
+$(THIRDPARTY_DIR)/zlib/zconf.h:
+ @echo "GEN $@"
+ $(QUIET)cp -f $@.in $@
+
+$(BINARY_DIR)/$(EXE_FILE): $(BINARY_DIR) $(THIRDPARTY_OBJECT_FILES) $(OBJECT_FILES)
+ @echo "LD $@"
+ $(QUIET)$(CXX) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) -o $@ $(LDFLAGS)
+
+$(BINARY_DIR)/$(EXE_FILE).exe: $(BINARY_DIR) $(THIRDPARTY_OBJECT_FILES) $(OBJECT_FILES)
+ @echo "MINGW_LD $@"
+ $(QUIET)$(MINGW_CXX) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) -o $@ $(LDFLAGS)
+
+clean:
+ rm -f $(BINARY_DIR)/$(EXE_FILE)$(EXE_EXT) $(OBJECT_FILES) $(THIRDPARTY_OBJECT_FILES) $(THIRDPARTY_HEADER_FILES)
+
+.PHONY: all clean