LuckyWorld/scripts/mac_build.sh

220 lines
8.0 KiB
Bash
Raw Normal View History

#!/bin/bash
# Get the user's home directory
USER_HOME="$HOME"
# Set up Unreal Engine paths
UE_ROOT="/Users/Shared/Epic Games/UE_5.5"
UE_EDITOR="$UE_ROOT/Engine/Binaries/Mac/UnrealEditor.app/Contents/MacOS/UnrealEditor"
UE_UAT="$UE_ROOT/Engine/Build/BatchFiles/RunUAT.command"
# Set up project paths
PROJECT_ROOT="$(pwd)"
2025-04-10 07:17:18 -05:00
PROJECT_FILE="$PROJECT_ROOT/LuckyWorld.uproject"
ARCHIVE_DIR="$PROJECT_ROOT/Builds"
# Check for entitlements file
if [ -f "$PROJECT_ROOT/LuckyWorld.entitlements" ]; then
ENTITLEMENTS_FILE="$PROJECT_ROOT/LuckyWorld.entitlements"
else
echo "Warning: No entitlements file found. This might affect notarization."
ENTITLEMENTS_FILE=""
fi
# For debugging: print paths and config
echo "Project root: $PROJECT_ROOT"
echo "Project file: $PROJECT_FILE"
echo "Archive directory: $ARCHIVE_DIR"
echo "Entitlements file: $ENTITLEMENTS_FILE"
# Clean up previous build artifacts
2025-04-10 07:17:18 -05:00
rm -rf DerivedDataCache Intermediate Binaries Saved
# Generate project files
2025-04-10 07:17:18 -05:00
"$UE_ROOT/Engine/Build/BatchFiles/Mac/GenerateProjectFiles.sh" -project="$PROJECT_FILE" -game -engine
# Run the build command
"$UE_UAT" -ScriptsForProject="$PROJECT_FILE" Turnkey \
-command=VerifySdk \
-platform=Mac \
-UpdateIfNeeded \
-EditorIO \
-EditorIOPort=59484 \
-project="$PROJECT_FILE" \
BuildCookRun \
-nop4 \
-utf8output \
-cook \
-project="$PROJECT_FILE" \
2025-04-10 07:17:18 -05:00
-target=LuckyWorld \
-unrealexe="$UE_EDITOR" \
-platform=Mac \
-installed \
-stage \
-archive \
-package \
-build \
-iterativecooking \
-pak \
-iostore \
-compressed \
-prereqs \
-archivedirectory="$ARCHIVE_DIR" \
-CrashReporter \
-clientconfig=Shipping \
# -nocompile \
# -nocompileuat \
# -nocompileeditor \
# -skipbuildeditor \
# enable these if you want to test build without pak and iostore (you're just testing the build)
# -skipiostore \
# -skippak \ (disable -pak and -iostore)
echo ""
echo "🦾 Build completed. Application path:"
APP_PATH=$(find "$ARCHIVE_DIR" -name "*.app" -type d | head -n 1)
echo "$APP_PATH"
# Check if the build actually succeeded by verifying the app exists
if [ -z "$APP_PATH" ] || [ ! -d "$APP_PATH" ]; then
echo "❌ ERROR: Build failed or did not produce an app bundle!"
echo "Check the logs above for build errors."
echo "Common issues:"
echo " - 'Targets with a unique build environment cannot be built with an installed engine'"
echo " Fix: Use bOverrideBuildEnvironment = true instead of BuildEnvironment = TargetBuildEnvironment.Unique"
exit 1
fi
if [ -n "$APP_PATH" ]; then
echo ""
echo "🔍 Binary files that will need signing:"
DYLIB_COUNT=$(find "$APP_PATH" -name "*.dylib" | wc -l)
SO_COUNT=$(find "$APP_PATH" -name "*.so" | wc -l)
FRAMEWORKS=$(find "$APP_PATH" -path "*.framework/*" -type f -perm +111 | wc -l)
EXECUTABLES=$(find "$APP_PATH" -type f -perm +111 -not -path "*.framework/*" -not -name "*.dylib" -not -name "*.so" | wc -l)
echo "- $DYLIB_COUNT .dylib libraries"
echo "- $SO_COUNT .so libraries"
echo "- $FRAMEWORKS framework executables"
echo "- $EXECUTABLES other executables"
echo "Total binary files: $((DYLIB_COUNT + SO_COUNT + FRAMEWORKS + EXECUTABLES))"
echo ""
echo "🔍 Checking for PhysX and other special libraries (often need special handling):"
find "$APP_PATH" -name "*PhysX*" -o -name "*APEX*"
fi
# Update bundle ID in project settings
echo ""
echo "🔧 Checking for bundle ID in UE config..."
CONFIG_FILE="$PROJECT_ROOT/Config/DefaultGame.ini"
if [ -f "$CONFIG_FILE" ]; then
if grep -q "\[/Script/MacTargetPlatform\.MacTargetSettings\]" "$CONFIG_FILE" && grep -q "BundleIdentifier=com.luckyrobots.luckyworld" "$CONFIG_FILE"; then
echo "Bundle ID already correctly set in project config ✅"
else
echo "⚠️ Warning: Bundle ID may not be correctly set in DefaultGame.ini"
echo "Please ensure [/Script/MacTargetPlatform.MacTargetSettings] section exists with BundleIdentifier=com.luckyrobots.luckyworld"
fi
else
echo "⚠️ Config file not found at $CONFIG_FILE"
fi
# Post-build process - set bundle ID
echo ""
echo "🔍 Checking bundle ID in built app..."
echo "Note: Bundle ID should be automatically set by Unreal Engine based on DefaultGame.ini and"
echo "LuckyWorld.Build.cs settings, but UE sometimes fails to apply it correctly."
echo "Therefore, we keep this check and fix as a safety measure."
if [ -n "$APP_PATH" ]; then
INFO_PLIST="$APP_PATH/Contents/Info.plist"
if [ -f "$INFO_PLIST" ]; then
CURRENT_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$INFO_PLIST")
echo "Current bundle ID: $CURRENT_BUNDLE_ID"
if [ "$CURRENT_BUNDLE_ID" != "com.luckyrobots.luckyworld" ]; then
echo "Bundle ID mismatch - fixing it!"
echo "Setting bundle identifier to com.luckyrobots.luckyworld"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.luckyrobots.luckyworld" "$INFO_PLIST"
echo "Updated bundle ID: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$INFO_PLIST")"
else
echo "✅ Bundle ID is already correct: com.luckyrobots.luckyworld"
fi
else
echo "⚠️ Info.plist not found at $INFO_PLIST"
fi
fi
# If this is a manual build (not in CI), attempt to sign the app locally
if [ -z "$CI" ] && [ -n "$APP_PATH" ]; then
echo ""
echo "🔐 Attempting local code signing and stapling..."
# Check if we have a valid Apple Developer identity
IDENTITY=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -1 | sed -E 's/.*\) ([A-F0-9]+) "(.*)"/\2/')
if [ -n "$IDENTITY" ]; then
echo "Found signing identity: $IDENTITY"
# Sign the app
echo "Signing application..."
if [ -f "$PROJECT_ROOT/LuckyWorld.entitlements" ]; then
echo "Using entitlements file: $PROJECT_ROOT/LuckyWorld.entitlements"
codesign --force --options runtime --entitlements "$PROJECT_ROOT/LuckyWorld.entitlements" --sign "$IDENTITY" --deep "$APP_PATH"
else
codesign --force --options runtime --sign "$IDENTITY" --deep "$APP_PATH"
fi
# Verify signature
echo "Verifying signature..."
codesign -vvv --deep "$APP_PATH"
# Staple the app if notarization is successful
echo "Checking if notarization is needed..."
if xcrun altool --notarization-info $(uuidgen) -u "YOUR_APPLE_ID" 2>&1 | grep -q "success"; then
echo "App is notarized, stapling the ticket..."
xcrun stapler staple "$APP_PATH"
xcrun stapler validate "$APP_PATH"
# Remove quarantine attribute if present
if [ -n "$(xattr -l "$APP_PATH" | grep quarantine)" ]; then
echo "Removing quarantine attribute..."
xattr -d com.apple.quarantine "$APP_PATH"
fi
else
echo "App is not notarized yet. Upload to Apple's notary service for full verification."
fi
else
echo "⚠️ No Developer ID Application certificate found for signing."
echo "Run 'security find-identity -v -p codesigning' to view available certificates."
fi
else
echo "Skipping local signing (running in CI or app not found)"
fi
# Find and check nested app bundles (like CrashReportClient.app)
NESTED_APPS=$(find "$APP_PATH" -name "*.app" -type d | grep -v "^$APP_PATH$")
if [ -n "$NESTED_APPS" ]; then
echo "Checking nested app bundles:"
echo "$NESTED_APPS" | while read -r NESTED_APP; do
if [ -f "$NESTED_APP/Contents/Info.plist" ]; then
NESTED_NAME=$(basename "$NESTED_APP" .app)
NESTED_BUNDLE_ID="com.luckyrobots.luckyworld.$NESTED_NAME"
CURRENT_NESTED_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")
if [ "$CURRENT_NESTED_ID" != "$NESTED_BUNDLE_ID" ]; then
echo "Setting nested bundle ID to $NESTED_BUNDLE_ID for $NESTED_APP"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $NESTED_BUNDLE_ID" "$NESTED_APP/Contents/Info.plist"
echo "Updated nested app bundle ID: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")"
else
echo "Nested app bundle ID already correct: $CURRENT_NESTED_ID"
fi
fi
done
fi
echo ""
echo "✅ Build and post-processing completed!"
echo "App location: $APP_PATH"