diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f82863..790af08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,17 @@ # Released under the GPLv3 cmake_minimum_required(VERSION 3.20) + +# macOS: set deployment target and universal architectures BEFORE project() +# so they propagate to all targets, including FetchContent dependencies (SDL3, etc.) +if(APPLE) + set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum macOS version" FORCE) + # Build universal binary (Apple Silicon + Intel) unless the user explicitly set architectures + if(NOT DEFINED CMAKE_OSX_ARCHITECTURES OR CMAKE_OSX_ARCHITECTURES STREQUAL "") + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "macOS architectures" FORCE) + endif() +endif() + project(ObsidianDragon VERSION 1.1.1 LANGUAGES C CXX diff --git a/build.sh b/build.sh index c891517..498aa27 100755 --- a/build.sh +++ b/build.sh @@ -197,7 +197,14 @@ bundle_linux_daemon() { # ═══════════════════════════════════════════════════════════════════════════════ build_dev() { header "Dev Build ($(uname -s) / $BUILD_TYPE)" - local bd="$SCRIPT_DIR/build/linux" + + # Use platform-appropriate build directory + if [[ "$(uname -s)" == "Darwin" ]]; then + local bd="$SCRIPT_DIR/build/mac" + export MACOSX_DEPLOYMENT_TARGET="11.0" + else + local bd="$SCRIPT_DIR/build/linux" + fi if $CLEAN; then info "Cleaning $bd ..."; rm -rf "$bd" @@ -732,7 +739,9 @@ build_release_mac() { fi info "macOS cross-compiler: $OSXCROSS_CXX (arch: $MAC_ARCH)" else - MAC_ARCH=$(uname -m) + # Native macOS: build universal binary (arm64 + x86_64) + MAC_ARCH="universal" + export MACOSX_DEPLOYMENT_TARGET="11.0" fi header "Release: macOS ($MAC_ARCH$(${IS_CROSS} && echo ' — cross-compile'))" @@ -811,12 +820,31 @@ TOOLCHAIN -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ ${COMPILER_RT:+-DOSXCROSS_COMPILER_RT="$COMPILER_RT"} else - info "Configuring (native) ..." + # Build libsodium as universal if needed + local need_sodium=false + if [[ ! -f "$SCRIPT_DIR/libs/libsodium/lib/libsodium.a" ]] && \ + [[ ! -f "$SCRIPT_DIR/libs/libsodium-mac/lib/libsodium.a" ]]; then + need_sodium=true + elif [[ -f "$SCRIPT_DIR/libs/libsodium/lib/libsodium.a" ]]; then + # Rebuild if existing lib is not universal (single-arch won't link) + if ! lipo -info "$SCRIPT_DIR/libs/libsodium/lib/libsodium.a" 2>/dev/null | grep -q "arm64.*x86_64\|x86_64.*arm64"; then + info "Existing libsodium is not universal — rebuilding ..." + rm -rf "$SCRIPT_DIR/libs/libsodium" + need_sodium=true + fi + fi + if $need_sodium; then + info "Building libsodium (universal) ..." + "$SCRIPT_DIR/scripts/fetch-libsodium.sh" + fi + + info "Configuring (native universal arm64+x86_64) ..." cmake "$SCRIPT_DIR" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_FLAGS_RELEASE="-O3 -DNDEBUG" \ -DDRAGONX_USE_SYSTEM_SDL3=OFF \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 + -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ + -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" fi info "Building with $JOBS jobs ..." @@ -836,6 +864,11 @@ TOOLCHAIN else info "Stripping ..." strip bin/ObsidianDragon + # Verify universal binary + if command -v lipo &>/dev/null; then + info "Architecture info:" + lipo -info bin/ObsidianDragon + fi fi info "Binary: $(du -h bin/ObsidianDragon | cut -f1)" diff --git a/scripts/fetch-libsodium.sh b/scripts/fetch-libsodium.sh index 7839116..f5fbcd5 100755 --- a/scripts/fetch-libsodium.sh +++ b/scripts/fetch-libsodium.sh @@ -50,12 +50,20 @@ if [[ ! -f "$TARBALL" ]]; then curl -fSL -o "$TARBALL" "$SODIUM_URL" fi -# Verify checksum -echo "$SODIUM_SHA256 $TARBALL" | sha256sum -c - || { - echo "[fetch-libsodium] ERROR: SHA256 mismatch! Removing corrupted download." - rm -f "$TARBALL" - exit 1 -} +# Verify checksum (sha256sum on Linux, shasum on macOS) +if command -v sha256sum &>/dev/null; then + echo "$SODIUM_SHA256 $TARBALL" | sha256sum -c - || { + echo "[fetch-libsodium] ERROR: SHA256 mismatch! Removing corrupted download." + rm -f "$TARBALL" + exit 1 + } +elif command -v shasum &>/dev/null; then + echo "$SODIUM_SHA256 $TARBALL" | shasum -a 256 -c - || { + echo "[fetch-libsodium] ERROR: SHA256 mismatch! Removing corrupted download." + rm -f "$TARBALL" + exit 1 + } +fi # ── Extract ───────────────────────────────────────────────────────────────── if [[ ! -d "$SRC_DIR" ]]; then @@ -115,6 +123,69 @@ case "$TARGET" in ;; esac +# ── Native macOS: build universal binary (arm64 + x86_64) ─────────────────── +IS_MACOS_NATIVE=false +if [[ "$TARGET" == "native" && "$(uname -s)" == "Darwin" ]]; then + IS_MACOS_NATIVE=true +fi + +if $IS_MACOS_NATIVE; then + echo "[fetch-libsodium] Building universal (arm64 + x86_64) for macOS..." + export MACOSX_DEPLOYMENT_TARGET="11.0" + + INSTALL_ARM64="$PROJECT_DIR/libs/libsodium-arm64" + INSTALL_X86_64="$PROJECT_DIR/libs/libsodium-x86_64" + + for ARCH in arm64 x86_64; do + echo "[fetch-libsodium] Building for $ARCH..." + cd "$SRC_DIR" + make clean 2>/dev/null || true + make distclean 2>/dev/null || true + + if [[ "$ARCH" == "arm64" ]]; then + ARCH_INSTALL="$INSTALL_ARM64" + HOST_TRIPLE="aarch64-apple-darwin" + else + ARCH_INSTALL="$INSTALL_X86_64" + HOST_TRIPLE="x86_64-apple-darwin" + fi + + ARCH_CFLAGS="-arch $ARCH -mmacosx-version-min=11.0" + + ./configure \ + --prefix="$ARCH_INSTALL" \ + --disable-shared \ + --enable-static \ + --with-pic \ + --host="$HOST_TRIPLE" \ + CFLAGS="$ARCH_CFLAGS" \ + LDFLAGS="-arch $ARCH" \ + > /dev/null + + make -j"$(sysctl -n hw.ncpu 2>/dev/null || echo 4)" > /dev/null 2>&1 + make install > /dev/null + done + + # Merge with lipo + echo "[fetch-libsodium] Creating universal binary with lipo..." + mkdir -p "$INSTALL_DIR/lib" "$INSTALL_DIR/include" + lipo -create \ + "$INSTALL_ARM64/lib/libsodium.a" \ + "$INSTALL_X86_64/lib/libsodium.a" \ + -output "$INSTALL_DIR/lib/libsodium.a" + cp -R "$INSTALL_ARM64/include/"* "$INSTALL_DIR/include/" + + # Clean up per-arch builds + rm -rf "$INSTALL_ARM64" "$INSTALL_X86_64" + cd "$PROJECT_DIR" + rm -rf "$SRC_DIR" + rm -f "$TARBALL" + + echo "[fetch-libsodium] Done (universal): $INSTALL_DIR/lib/libsodium.a" + lipo -info "$INSTALL_DIR/lib/libsodium.a" + exit 0 +fi + echo "[fetch-libsodium] Configuring for target: $TARGET ..." ./configure "${CONFIGURE_ARGS[@]}" > /dev/null