Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion 3rdparty/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ NC := \033[0m
# Optional audiofile: only the legacy `audiofile-patched/` tree (from zip), not the
# submodule path, so default Windows deps stay minimal and build with current GCC.
AUDIOFILE_SRC := $(shell if [ -d "audiofile-patched" ]; then echo "audiofile-patched"; else echo ""; fi)
HOST_CONFIGURE_ARG := $(if $(MACOS_MINGW_CROSS),--host=$(MINGW_HOST),)
CMAKE_CROSS_ARGS := $(if $(MACOS_MINGW_CROSS),-DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=$(CC),)

.PHONY: all clean distclean libspectrum audiofile libxml2 mbedtls libssh2 check-tools check-libspectrum check-libssh2 extract-audiofile extract-libxml2 libspectrum-with-audiofile

Expand Down Expand Up @@ -100,7 +102,7 @@ libspectrum: dist-dirs check-libspectrum
if [ ! -f configure ]; then \
./autogen.sh; \
fi && \
./configure --with-fake-glib --without-libaudiofile --without-libgcrypt \
./configure $(HOST_CONFIGURE_ARG) --with-fake-glib --without-libaudiofile --without-libgcrypt \
--without-zlib --without-bzip2 --prefix="$(DIST_PREFIX)" && \
$(MAKE) && \
$(MAKE) install
Expand Down Expand Up @@ -181,6 +183,7 @@ libssh2: mbedtls dist-dirs check-libssh2
cd libssh2/src/build && \
cmake .. \
-G "Unix Makefiles" \
$(CMAKE_CROSS_ARGS) \
-DCMAKE_INSTALL_PREFIX="$(DIST_PREFIX)" \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
Expand Down
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ archive: 3rdparty fusepb
-scheme FuseX \
-configuration Deployment \
-archivePath "$(CURDIR)/$(ARCHIVE_PATH)" \
SYMROOT=build \
BUILD_DIR=build \
CONFIGURATION_BUILD_DIR=build/Deployment \
$(XCODEBUILD_SIGN_ARGS)
@echo "Archive created at: $(ARCHIVE_PATH)"

Expand Down
107 changes: 89 additions & 18 deletions build_win32.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# FuseX — Windows distribution build (MSYS2 MinGW 64-bit).
# Prerequisite: MSYS2 with mingw-w64-x86_64 toolchain, perl, zip, 7zip (optional), NSIS (optional).
# FuseX — Windows distribution build (MSYS2 or a macOS MinGW cross-toolchain).
# Prerequisite: MinGW-w64, perl, zip, 7zip (optional), NSIS (optional).

set -e

Expand All @@ -11,18 +11,39 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

if [[ -z "${MSYSTEM:-}" ]]; then
echo -e "${RED}Error: run this from MSYS2 (e.g. \"MSYS2 MinGW 64-bit\"), not plain PowerShell.${NC}"
HOST_OS="$(uname -s)"
if [[ "$HOST_OS" == "Darwin" ]]; then
MACOS_MINGW_CROSS=1
export MACOS_MINGW_CROSS
MINGW_HOST="${MINGW_HOST:-x86_64-w64-mingw32}"
export MINGW_HOST
export CC="${MINGW_CC:-${MINGW_HOST}-gcc}"
export CXX="${MINGW_CXX:-${MINGW_HOST}-g++}"
export AR="${MINGW_AR:-${MINGW_HOST}-ar}"
export RANLIB="${MINGW_RANLIB:-${MINGW_HOST}-ranlib}"
export STRIP="${MINGW_STRIP:-${MINGW_HOST}-strip}"
export WINDRES="${MINGW_WINDRES:-${MINGW_HOST}-windres}"
echo -e "${GREEN}Using macOS MinGW cross-toolchain: ${MINGW_HOST}${NC}"
elif [[ -z "${MSYSTEM:-}" ]]; then
echo -e "${RED}Error: run this from MSYS2 or from macOS with MinGW-w64 installed.${NC}"
exit 1
fi

if [[ "$MSYSTEM" != "MINGW64" && "$MSYSTEM" != "UCRT64" ]]; then
elif [[ "$MSYSTEM" != "MINGW64" && "$MSYSTEM" != "UCRT64" ]]; then
echo -e "${YELLOW}Warning: MINGW64 or UCRT64 is recommended (current: $MSYSTEM).${NC}"
fi

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"

if [[ "$HOST_OS" == "Darwin" ]]; then
# Homebrew users often export native include/library flags globally. Those
# paths must not enter Windows objects during a cross-build.
export CFLAGS="${MINGW_CFLAGS:-}"
export CPPFLAGS="${MINGW_CPPFLAGS:-}"
export LDFLAGS="${MINGW_LDFLAGS:-}"
export PKG_CONFIG_PATH="$SCRIPT_DIR/3rdparty/dist/lib/pkgconfig"
export PKG_CONFIG_LIBDIR="$PKG_CONFIG_PATH"
fi

# Windows NSIS installs makensis.exe here but does not add it to MSYS PATH — match typical fuse dev setups.
for _nsis in "/c/Program Files/NSIS" "/c/Program Files (x86)/NSIS"; do
if [[ -d "$_nsis" ]] && [[ -x "$_nsis/makensis.exe" || -x "$_nsis/makensis" ]]; then
Expand All @@ -32,24 +53,42 @@ for _nsis in "/c/Program Files/NSIS" "/c/Program Files (x86)/NSIS"; do
fi
done

if [[ "$HOST_OS" == "Darwin" ]]; then
export MINGW_RUNTIME_DIR="${MINGW_RUNTIME_DIR:-$($CC -print-sysroot)/${MINGW_HOST}/bin}"
fi

# Code generators assume Unix line endings on option/menu data (avoid CRLF breakage under Windows).
for f in ui/options.dat menu_data.dat settings.dat keysyms.dat \
z80/opcodes_base.dat z80/opcodes_cb.dat z80/opcodes_ddfd.dat \
z80/opcodes_ddfdcb.dat z80/opcodes_ed.dat; do
if [[ -f "$f" ]]; then
sed -i 's/\r$//' "$f" 2>/dev/null || true
if [[ "$HOST_OS" == "Darwin" ]]; then
perl -pi -e 's/\r$//' "$f"
else
sed -i 's/\r$//' "$f" 2>/dev/null || true
fi
fi
done

echo -e "${GREEN}Directory: $SCRIPT_DIR${NC}"

echo -e "\n${GREEN}Checking tools...${NC}"
for tool in gcc make pkg-config perl; do
TOOLS=( gcc make pkg-config perl )
if [[ "$HOST_OS" == "Darwin" ]]; then
TOOLS=( "$CC" make pkg-config perl )
fi
for tool in "${TOOLS[@]}"; do
if ! command -v "$tool" &> /dev/null; then
echo -e "${RED}Missing: $tool${NC}"
case "$tool" in
perl) echo " pacman -S mingw-w64-x86_64-perl" ;;
*) echo " pacman -S mingw-w64-x86_64-$tool" ;;
*)
if [[ "$HOST_OS" == "Darwin" ]]; then
echo " Install the MinGW-w64 build tool containing: $tool"
else
echo " pacman -S mingw-w64-x86_64-$tool"
fi
;;
esac
exit 1
fi
Expand All @@ -71,13 +110,22 @@ export PKG_CONFIG_PATH="$DIST_PREFIX/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
# Link the static archive explicitly (avoids picking /usr/local libspectrum.dll.a via libtool).
PC="$DIST_PREFIX/lib/pkgconfig/libspectrum.pc"
if [[ -f "$PC" ]]; then
sed -i 's|^Libs:.*|Libs: ${libdir}/libspectrum.a|' "$PC" 2>/dev/null || true
if [[ "$HOST_OS" == "Darwin" ]]; then
perl -pi -e 's|^Libs:.*|Libs: \${libdir}/libspectrum.a|' "$PC"
else
sed -i 's|^Libs:.*|Libs: ${libdir}/libspectrum.a|' "$PC" 2>/dev/null || true
fi
fi

# Static libspectrum from 3rdparty: strip dllimport so MinGW links the .a correctly.
if [[ -f "$DIST_PREFIX/include/libspectrum.h" ]]; then
sed -i 's/#define LIBSPECTRUM_API __declspec( dllimport )/#define LIBSPECTRUM_API/g' \
"$DIST_PREFIX/include/libspectrum.h" 2>/dev/null || true
if [[ "$HOST_OS" == "Darwin" ]]; then
perl -pi -e 's/#define LIBSPECTRUM_API __declspec\( dllimport \)/#define LIBSPECTRUM_API/g' \
"$DIST_PREFIX/include/libspectrum.h"
else
sed -i 's/#define LIBSPECTRUM_API __declspec( dllimport )/#define LIBSPECTRUM_API/g' \
"$DIST_PREFIX/include/libspectrum.h" 2>/dev/null || true
fi
fi
# Prefer the static archive: libspectrum.dll.a can make -lspectrum import from a DLL.
if [[ -f "$DIST_PREFIX/lib/libspectrum.a" && -f "$DIST_PREFIX/lib/libspectrum.dll.a" ]]; then
Expand All @@ -86,7 +134,11 @@ if [[ -f "$DIST_PREFIX/lib/libspectrum.a" && -f "$DIST_PREFIX/lib/libspectrum.dl
fi

echo -e "\n${GREEN}Generating configure if needed...${NC}"
if [[ ! -f configure ]]; then
if [[ "$HOST_OS" == "Darwin" ]]; then
# Building libspectrum refreshes the shared libtool support files in this
# source tree. Regenerate Fuse's configure files with that same version.
./autogen.sh
elif [[ ! -f configure ]]; then
./autogen.sh
else
echo " configure present"
Expand All @@ -95,7 +147,18 @@ fi
echo -e "\n${GREEN}Configuring FuseX...${NC}"

# Sockets enabled (default): Spectranet, gdbserver remote, etc. require Winsock on Windows.
CONFIGURE_OPTS=( --with-win32 --without-zlib --without-png --prefix=/usr/local )
CONFIGURE_PREFIX="/usr/local"
if [[ "$HOST_OS" == "Darwin" ]]; then
# Avoid an unrelated native /usr/local/include/libspectrum.h taking
# precedence over the Windows library built above.
CONFIGURE_PREFIX="$DIST_PREFIX"
fi
CONFIGURE_OPTS=( --with-win32 --without-zlib --without-png --prefix="$CONFIGURE_PREFIX" )
if [[ "$HOST_OS" == "Darwin" ]]; then
CONFIGURE_OPTS=( --host="$MINGW_HOST" "${CONFIGURE_OPTS[@]}" )
# Never allow pkg-config to fall back to native macOS libraries.
export PKG_CONFIG_LIBDIR="$DIST_PREFIX/lib/pkgconfig"
fi
if pkg-config --exists libxml-2.0 2>/dev/null; then
echo " with libxml2 (pkg-config)"
else
Expand All @@ -105,10 +168,18 @@ fi

./configure "${CONFIGURE_OPTS[@]}"

if [[ "${WIN32_CLEAN:-0}" == "1" ]]; then
echo -e "\n${GREEN}Cleaning the configured Windows build...${NC}"
make clean
fi

echo -e "\n${GREEN}Building and creating Windows distribution (zip, 7z, installer if NSIS is available)...${NC}"
# Same as upstream fuse build_win32.sh: one target builds zip + 7z + setup.exe (see data/win32/distribution.mk).
if command -v makensis &>/dev/null || command -v makensis.exe &>/dev/null; then
make dist-win32 -j"$(nproc 2>/dev/null || echo 4)"
make "${WIN32_DIST_TARGET:-dist-win32}" -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)"
elif [[ "${REQUIRE_NSIS:-0}" == "1" ]]; then
echo -e "${RED}NSIS is required, but makensis was not found.${NC}"
exit 1
else
echo -e "${YELLOW}makensis not on PATH — building zip/7z only. Add NSIS to PATH or install to:${NC}"
echo " C:\\Program Files\\NSIS or C:\\Program Files (x86)\\NSIS"
Expand All @@ -133,7 +204,7 @@ if [[ -z "$SETUP_EXE" ]]; then
SETUP_EXE="$( ls "$SCRIPT_DIR"/fusex-*-win32-setup.exe 2>/dev/null | sort -V | tail -1 )"
fi
APPCAST_SRC="$SCRIPT_DIR/build/appcast-windows/appcast.xml"
if [[ -n "$SETUP_EXE" ]]; then
if [[ -n "$SETUP_EXE" && "${SKIP_APPCAST:-0}" != "1" ]]; then
echo -e "\n${GREEN}Generating WinSparkle appcast...${NC}"
bash "$SCRIPT_DIR/data/win32/generate-appcast.sh" "$SETUP_EXE"
APPCAST_PUSH_DIR="$SCRIPT_DIR/../speccytools.github.io/updates"
Expand All @@ -143,6 +214,6 @@ if [[ -n "$SETUP_EXE" ]]; then
cp -f "$APPCAST_SRC" "$APPCAST_DEST/appcast.xml"
echo -e "${GREEN}Copied appcast to ${APPCAST_DEST}/appcast.xml${NC}"
fi
else
elif [[ -z "$SETUP_EXE" ]]; then
echo -e "\n${YELLOW}Skipping appcast generation (no setup.exe).${NC}"
fi
3 changes: 3 additions & 0 deletions data/win32/distribution.mk
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ dist-win32-dir: 3rdparty-dist
elif test -z "$$MINGW_BIN" && test -d "/mingw32/bin"; then \
MINGW_BIN="/mingw32/bin"; \
fi; \
if test "$$MACOS_MINGW_CROSS" = "1" && test -n "$$MINGW_RUNTIME_DIR"; then \
MINGW_BIN="$$MINGW_RUNTIME_DIR"; \
fi; \
if test -n "$$MINGW_BIN"; then \
echo "Copying MinGW runtime DLLs from $$MINGW_BIN ..."; \
for dll in libwinpthread-1.dll libstdc++-6.dll libgcc_s_seh-1.dll libgcc_s_dw2-1.dll; do \
Expand Down
20 changes: 20 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

# Build the complete FuseX macOS and Windows release from a Mac.

set -euo pipefail

readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if [[ "$(uname -s)" != "Darwin" ]]; then
echo "Error: deploy.sh must be run on macOS." >&2
exit 1
fi

echo "==> Starting macOS deployment"
bash "$SCRIPT_DIR/deploy_mac.sh"

echo "==> Starting Windows deployment"
bash "$SCRIPT_DIR/deploy_win.sh"

echo "==> Complete FuseX deployment finished"
Loading
Loading