@@ -351,6 +351,91 @@ clean:
351351 $(Q ) rm -f $(TARGET )
352352 $(Q ) rm -f * .d
353353 $(Q ) rm -f default.metallib gfx/common/metal/* .air
354+ $(Q ) rm -rf $(BUNDLE )
355+
356+ # ---------------------------------------------------------------------------
357+ # make bundle — assemble RetroArch.app from the build outputs (macOS only).
358+ #
359+ # Mirrors what pkg/apple/RetroArch_Metal.xcodeproj produces, minus code
360+ # signing, entitlements, asset archives, and framework-wrapped cores. The
361+ # resulting .app is a plain, ad-hoc bundle suitable for local testing and
362+ # for distribution outside the App Store.
363+ #
364+ # Invoked as `make bundle`. Not part of `all:`; plain `make` builds only
365+ # the retroarch binary and default.metallib exactly as before.
366+ #
367+ # The deployment target in Info.plist (LSMinimumSystemVersion) is derived
368+ # from the -mmacosx-version-min=X.Y flag the binary was linked with (set
369+ # earlier in this Makefile via $(MINVERFLAGS) based on the target arch).
370+ # Build floors per Makefile.common:130-164:
371+ # arm64 -> 10.15 (Apple Silicon)
372+ # x86_64+Metal -> 10.13
373+ # x86_64 -> 10.7
374+ # i386 -> 10.6
375+ # powerpc -> 10.5
376+ # To target a lower OS version than the default for the current arch,
377+ # cross-compile with ARCH=<arch> (e.g. `ARCH=ppc make && make bundle`)
378+ # or override BUNDLE_MIN_OS directly.
379+ #
380+ # User-overridable variables:
381+ # BUNDLE bundle directory name (default: RetroArch.app)
382+ # BUNDLE_EXECUTABLE binary name inside Contents/MacOS (default: RetroArch)
383+ # BUNDLE_IDENTIFIER CFBundleIdentifier (default: com.libretro.dist.RetroArch)
384+ # BUNDLE_VERSION CFBundleShortVersionString (default: from version.all)
385+ # BUNDLE_BUILD CFBundleVersion (default: 44)
386+ # BUNDLE_MIN_OS LSMinimumSystemVersion (default: derived from MINVERFLAGS)
387+ #
388+ # Example: BUNDLE=RetroArchDev.app BUNDLE_IDENTIFIER=com.example.dev make bundle
389+ # ---------------------------------------------------------------------------
390+
391+ ifneq ($(findstring Darwin,$(OS ) ) ,)
392+
393+ # version.all is a C/Make/shell polyglot, but all lines start with '#' so
394+ # '-include version.all' is a no-op from Make's perspective. Parse the
395+ # #define out via shell instead.
396+ PACKAGE_VERSION := $(shell grep 'define PACKAGE_VERSION' version.all | cut -d'"' -f2)
397+
398+ BUNDLE ?= RetroArch.app
399+ BUNDLE_EXECUTABLE ?= RetroArch
400+ BUNDLE_IDENTIFIER ?= com.libretro.dist.RetroArch
401+ BUNDLE_VERSION ?= $(PACKAGE_VERSION )
402+ BUNDLE_BUILD ?= 44
403+ # Extract X.Y from '-mmacosx-version-min=X.Y' inside $(MINVERFLAGS).
404+ # If nothing matches (e.g. building with a custom toolchain), fall back to 10.13.
405+ BUNDLE_MIN_OS ?= $(or $(patsubst -mmacosx-version-min=% ,% ,$(filter -mmacosx-version-min=% ,$(MINVERFLAGS ) ) ) ,10.13)
406+ INFO_PLIST_SRC := pkg/apple/OSX/Info_Metal.plist
407+
408+ bundle : $(TARGET ) $(METALLIB )
409+ @echo " Assembling $( BUNDLE) (min macOS $( BUNDLE_MIN_OS) )"
410+ $(Q ) rm -rf $(BUNDLE )
411+ $(Q ) mkdir -p $(BUNDLE ) /Contents/MacOS
412+ $(Q ) mkdir -p $(BUNDLE ) /Contents/Resources/filters/audio
413+ $(Q ) mkdir -p $(BUNDLE ) /Contents/Resources/filters/video
414+ $(Q ) cp $(TARGET ) $(BUNDLE ) /Contents/MacOS/$(BUNDLE_EXECUTABLE )
415+ $(Q ) chmod +x $(BUNDLE ) /Contents/MacOS/$(BUNDLE_EXECUTABLE )
416+ $(Q ) if [ -f default.metallib ]; then \
417+ cp default.metallib $(BUNDLE ) /Contents/Resources/default.metallib; \
418+ elif [ -f pkg/apple/OSX/Resources/default.metallib ]; then \
419+ cp pkg/apple/OSX/Resources/default.metallib $(BUNDLE ) /Contents/Resources/default.metallib; \
420+ fi
421+ $(Q ) cp libretro-common/audio/dsp_filters/* .dsp \
422+ $(BUNDLE ) /Contents/Resources/filters/audio/ 2> /dev/null || true
423+ $(Q ) cp gfx/video_filters/* .filt \
424+ $(BUNDLE ) /Contents/Resources/filters/video/ 2> /dev/null || true
425+ $(Q ) printf ' APPL????' > $(BUNDLE ) /Contents/PkgInfo
426+ $(Q ) sed \
427+ -e ' s|$$(EXECUTABLE_NAME)|$(BUNDLE_EXECUTABLE)|g' \
428+ -e ' s|$${PRODUCT_NAME}|$(BUNDLE_EXECUTABLE)|g' \
429+ -e ' s|$$(PRODUCT_BUNDLE_IDENTIFIER)|$(BUNDLE_IDENTIFIER)|g' \
430+ -e ' s|$$(MARKETING_VERSION)|$(BUNDLE_VERSION)|g' \
431+ -e ' s|$$(CURRENT_PROJECT_VERSION)|$(BUNDLE_BUILD)|g' \
432+ -e ' s|$$(MACOSX_DEPLOYMENT_TARGET)|$(BUNDLE_MIN_OS)|g' \
433+ $(INFO_PLIST_SRC ) > $(BUNDLE ) /Contents/Info.plist
434+ @echo " Done. Run with: open $( BUNDLE) "
435+
436+ .PHONY : bundle
437+
438+ endif
354439
355440.PHONY : all install uninstall clean
356441
0 commit comments