mirror of
https://github.com/libretro/Libretro-Supermodel.git
synced 2026-11-07 11:15:58 -10:00
Both are arm64 and both are the GLES build with Apple's SDK in front of it. The renderer already resolves every entry point through glsym on the other GLES platforms, so nothing here links against a GL framework - OpenGLES is deprecated on these systems in any case - and Legacy3D is dropped the way it is for macOS and Android, with an explicit RENDERER=legacy rejected rather than silently accepted. No PPC JIT. Writing and then executing the same page needs an entitlement a libretro core cannot ask for on stock iOS or tvOS, so Model 3 runs on the interpreter. That is worth saying plainly, and it is still better than leaving the platform unbuilt. The dylib names are the ones the ios-arm64 and tvos-arm64 templates look for, and their after_script checks the platform recorded in the Mach-O, which is what -isysroot and the version-min flag put there. A missing SDK is an error at that point rather than an empty -isysroot and a confusing failure later - the same lesson as the bundled headers in the commit before this one. Checked here with make -n and a stub xcrun: glsym_es3.c is compiled and glsym_gl.c is not, no Legacy3D object reaches the link line, the Unix FileSystemPath is the one selected, the targets come out as supermodel_libretro_ios.dylib and supermodel_libretro_tvos.dylib, and HAVE_PPC_JIT is absent from both. Neither SDK exists outside the Apple runner, so both jobs are allow_failure until a pipeline has had them.
782 lines
31 KiB
Makefile
782 lines
31 KiB
Makefile
# Supermodel Libretro Core - Unified Makefile
|
|
# Follows libretro/skeletor pattern with all platforms consolidated
|
|
|
|
STATIC_LINKING := 0
|
|
DEBUG ?= 0
|
|
PSS_STYLE ?= 1
|
|
EXTERNAL_ZLIB ?= 0
|
|
HAVE_GRIFFIN ?= 1
|
|
|
|
# Core definitions
|
|
CORE_DIR := .
|
|
TARGET_NAME := supermodel
|
|
|
|
# ============================================================
|
|
# Platform Auto-Detection
|
|
# ============================================================
|
|
ifeq ($(platform),)
|
|
platform = unix
|
|
ifeq ($(shell uname -a),)
|
|
platform = win
|
|
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
|
platform = win
|
|
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
|
platform = osx
|
|
else ifneq ($(findstring win,$(shell uname -a)),)
|
|
platform = win
|
|
else ifeq ($(shell uname -m),aarch64)
|
|
platform = linux-aarch64
|
|
endif
|
|
endif
|
|
|
|
# The libretro buildbot passes platform=win64 to the MinGW cross build, and
|
|
# other spellings are in circulation too. Normalize them all to "win" so the
|
|
# Windows branches below actually match -- otherwise no branch matches at all,
|
|
# TARGET stays empty and "make" silently does nothing.
|
|
WIN_PLATFORM := $(filter $(platform),win win32 win64 windows wincross64)
|
|
ifneq (,$(WIN_PLATFORM))
|
|
platform := win
|
|
endif
|
|
|
|
# System platform (for native builds)
|
|
system_platform = unix
|
|
ifeq ($(shell uname -a),)
|
|
system_platform = win
|
|
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
|
system_platform = osx
|
|
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
|
system_platform = win
|
|
endif
|
|
|
|
# ============================================================
|
|
# Source Files (extracted from Makefile.common)
|
|
# ============================================================
|
|
LIBRETRO_COMM_DIR := $(CORE_DIR)/Src/OSD/libretro/libretro-common
|
|
DEPS_DIR := $(CORE_DIR)/deps
|
|
|
|
INCFLAGS := -I$(CORE_DIR) \
|
|
-I$(DEPS_DIR)/ugui \
|
|
-I$(LIBRETRO_COMM_DIR)/include \
|
|
-I$(CORE_DIR)/Src/OSD/libretro/include \
|
|
-I$(CORE_DIR)/Src/OSD/libretro \
|
|
-I$(CORE_DIR)/Src \
|
|
-I$(CORE_DIR)/Src/CPU/68K/Musashi \
|
|
-I$(CORE_DIR)/Src/CPU/68K/Musashi/generated
|
|
|
|
COREDEFINES := -D__LIBRETRO__ -DSUPERMODEL_OSD_LIBRETRO -DNET_BOARD
|
|
COREDEFINES += -DINLINE=inline
|
|
COREDEFINES += -DPSS_STYLE=$(PSS_STYLE)
|
|
|
|
# C Source Files (28 files)
|
|
SOURCES_C := $(CORE_DIR)/Src/Pkgs/unzip.c \
|
|
$(CORE_DIR)/Src/Pkgs/ioapi.c \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/m68kcpu.c \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kops.c \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopac.c \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopdm.c \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopnz.c \
|
|
$(DEPS_DIR)/ugui/ugui.c \
|
|
$(CORE_DIR)/Src/ugui_tools.c \
|
|
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
|
|
$(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.c \
|
|
$(LIBRETRO_COMM_DIR)/file/file_path.c \
|
|
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
|
|
$(LIBRETRO_COMM_DIR)/file/retro_dirent.c \
|
|
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c \
|
|
$(LIBRETRO_COMM_DIR)/lists/dir_list.c \
|
|
$(LIBRETRO_COMM_DIR)/lists/string_list.c \
|
|
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
|
|
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
|
|
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
|
|
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
|
|
$(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \
|
|
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
|
|
$(LIBRETRO_COMM_DIR)/memmap/memalign.c \
|
|
$(LIBRETRO_COMM_DIR)/time/rtime.c \
|
|
$(LIBRETRO_COMM_DIR)/hash/rhash.c
|
|
|
|
# Add libretro-common glsym for non-Android
|
|
ifeq (,$(findstring android,$(platform)))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_gl.c \
|
|
$(LIBRETRO_COMM_DIR)/glsym/rglgen.c
|
|
endif
|
|
|
|
# C++ Source Files (80 files - verified to exist)
|
|
SOURCES_CXX := $(CORE_DIR)/Src/CPU/PowerPC/PPCDisasm.cpp \
|
|
$(CORE_DIR)/Src/BlockFile.cpp \
|
|
$(CORE_DIR)/Src/Model3/93C46.cpp \
|
|
$(CORE_DIR)/Src/Util/BitRegister.cpp \
|
|
$(CORE_DIR)/Src/Model3/JTAG.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/imgui/imgui.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/imgui/imgui_draw.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/imgui/imgui_tables.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/imgui/imgui_widgets.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/imgui/imgui_impl_opengl3.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Legacy3D/Error.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Shader.cpp \
|
|
$(CORE_DIR)/Src/Graphics/GLSLVersion.cpp \
|
|
$(CORE_DIR)/Src/Model3/Real3D.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Legacy3D/Legacy3D.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Legacy3D/Models.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Legacy3D/TextureRefs.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/New3D.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/Mat4.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/Model.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/PolyHeader.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/TextureBank.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/VBO.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/Vec.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/R3DShader.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/R3DFloat.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/R3DScrollFog.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/R3DFrameBuffers.cpp \
|
|
$(CORE_DIR)/Src/Graphics/New3D/GLSLShader.cpp \
|
|
$(CORE_DIR)/Src/Graphics/FBO.cpp \
|
|
$(CORE_DIR)/Src/Graphics/SuperAA.cpp \
|
|
$(CORE_DIR)/Src/Graphics/Render2D.cpp \
|
|
$(CORE_DIR)/Src/Model3/TileGen.cpp \
|
|
$(CORE_DIR)/Src/Model3/Model3.cpp \
|
|
$(CORE_DIR)/Src/CPU/PowerPC/ppc.cpp \
|
|
$(if $(filter android aarch64 rpi64 linux-aarch64 osx,$(platform)),$(CORE_DIR)/Src/CPU/PowerPC/Jit/JitArm64.cpp,) \
|
|
$(CORE_DIR)/Src/Model3/SoundBoard.cpp \
|
|
$(CORE_DIR)/Src/Sound/SCSP.cpp \
|
|
$(CORE_DIR)/Src/Sound/SCSPDSP.cpp \
|
|
$(CORE_DIR)/Src/CPU/68K/68K.cpp \
|
|
$(CORE_DIR)/Src/Model3/DSB.cpp \
|
|
$(CORE_DIR)/Src/CPU/Z80/Z80.cpp \
|
|
$(CORE_DIR)/Src/Model3/IRQ.cpp \
|
|
$(CORE_DIR)/Src/Model3/53C810.cpp \
|
|
$(CORE_DIR)/Src/Model3/PCI.cpp \
|
|
$(CORE_DIR)/Src/Model3/RTC72421.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/DriveBoard.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/WheelBoard.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/JoystickBoard.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/SkiBoard.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/BillBoard.cpp \
|
|
$(CORE_DIR)/Src/Model3/DriveBoard/Z80CTC.cpp \
|
|
$(CORE_DIR)/Src/Model3/MPC10x.cpp \
|
|
$(CORE_DIR)/Src/Inputs/Input.cpp \
|
|
$(CORE_DIR)/Src/Inputs/Inputs.cpp \
|
|
$(CORE_DIR)/Src/Inputs/InputSource.cpp \
|
|
$(CORE_DIR)/Src/Inputs/InputSystem.cpp \
|
|
$(CORE_DIR)/Src/Inputs/InputTypes.cpp \
|
|
$(CORE_DIR)/Src/Inputs/MultiInputSource.cpp \
|
|
$(CORE_DIR)/Src/OSD/Outputs.cpp \
|
|
$(CORE_DIR)/Src/Sound/MPEG/MpegAudio.cpp \
|
|
$(CORE_DIR)/Src/Model3/Crypto.cpp \
|
|
$(CORE_DIR)/Src/OSD/Logger.cpp \
|
|
$(CORE_DIR)/Src/Util/Format.cpp \
|
|
$(CORE_DIR)/Src/Util/NewConfig.cpp \
|
|
$(CORE_DIR)/Src/Util/ByteSwap.cpp \
|
|
$(CORE_DIR)/Src/Util/ConfigBuilders.cpp \
|
|
$(CORE_DIR)/Src/GameLoader.cpp \
|
|
$(CORE_DIR)/Src/Pkgs/tinyxml2.cpp \
|
|
$(CORE_DIR)/Src/ROMSet.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/libretroAudio.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/libretroThread.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/libretroCrosshair.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/libretroGui.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/LibretroBlockFileMemory.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/CLibretroInputSystem.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/CLibretroOutputSystem.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/LibretroNetBoard.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/LibretroWrapper.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/vfs_ioapi.cpp \
|
|
$(CORE_DIR)/Src/OSD/libretro/libretro.cpp
|
|
|
|
# Platform-specific OSD FileSystemPath implementation
|
|
ifeq ($(platform),win)
|
|
SOURCES_CXX += $(CORE_DIR)/Src/OSD/Windows/FileSystemPath.cpp
|
|
else ifeq ($(platform),osx)
|
|
SOURCES_CXX += $(CORE_DIR)/Src/OSD/OSX/FileSystemPath.cpp
|
|
else
|
|
# osx, unix, android, rpi64, aarch64 all use Unix FileSystemPath
|
|
SOURCES_CXX += $(CORE_DIR)/Src/OSD/Unix/FileSystemPath.cpp
|
|
endif
|
|
|
|
# Renderer selection: new3d (default) or legacy.
|
|
# make platform=rpi64 RENDERER=legacy
|
|
# Legacy3D is the old desktop-GL renderer. It is being ported to run inside the
|
|
# GLES3 context (GLES2-style code: client vertex arrays, #version 100 shaders),
|
|
# so on GLES platforms it is only compiled in when explicitly asked for.
|
|
RENDERER ?= new3d
|
|
|
|
LEGACY3D_SOURCES := %/Legacy3D/Error.cpp %/Legacy3D/Legacy3D.cpp %/Legacy3D/Models.cpp %/Legacy3D/TextureRefs.cpp
|
|
|
|
# These platforms deliberately omit the fixed-function Legacy3D sources.
|
|
# Reject an explicit legacy build instead of accepting the selector and later
|
|
# failing with missing renderer objects or symbols.
|
|
ifneq ($(filter osx android ios-arm64 tvos-arm64,$(platform)),)
|
|
ifeq ($(RENDERER),legacy)
|
|
$(error RENDERER=legacy is not supported for platform=$(platform))
|
|
endif
|
|
endif
|
|
|
|
ifeq ($(RENDERER),legacy)
|
|
RENDERER_DEFINES := -DUSE_LEGACY3D
|
|
DROP_LEGACY3D :=
|
|
else
|
|
RENDERER_DEFINES :=
|
|
DROP_LEGACY3D := 1
|
|
endif
|
|
|
|
# Platform-specific source filtering (MUST be before OBJECTS computation!)
|
|
# macOS and Android don't support Legacy3D (old fixed-pipeline OpenGL)
|
|
ifeq ($(platform),osx)
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
ifeq ($(platform),android)
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
|
|
# rpi64 and aarch64 use GLES3 (RetroArch on RPi5 provides only GLES context via EGL)
|
|
ifeq ($(platform),rpi64)
|
|
SOURCES_C := $(filter-out %/glsym/glsym_gl.c,$(SOURCES_C))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.c
|
|
ifdef DROP_LEGACY3D
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
endif
|
|
ifeq ($(platform),aarch64)
|
|
SOURCES_C := $(filter-out %/glsym/glsym_gl.c,$(SOURCES_C))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.c
|
|
ifdef DROP_LEGACY3D
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
endif
|
|
ifeq ($(platform),linux-aarch64)
|
|
SOURCES_C := $(filter-out %/glsym/glsym_gl.c,$(SOURCES_C))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.c
|
|
ifdef DROP_LEGACY3D
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
endif
|
|
# iOS and tvOS are GLES too, and there is no desktop GL on either to fall back
|
|
# on, so Legacy3D goes whatever RENDERER says - the block further up rejects an
|
|
# explicit legacy build for them the same way it does for osx and android.
|
|
ifneq ($(filter $(platform),ios-arm64 tvos-arm64),)
|
|
SOURCES_C := $(filter-out %/glsym/glsym_gl.c,$(SOURCES_C))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.c
|
|
SOURCES_CXX := $(filter-out $(LEGACY3D_SOURCES),$(SOURCES_CXX))
|
|
endif
|
|
|
|
# Renderer capabilities exposed to the Libretro option layer. Keep these as
|
|
# feature defines rather than platform tests so future ports only need to
|
|
# enable the capability here.
|
|
ifneq ($(filter $(CORE_DIR)/Src/Graphics/Legacy3D/Legacy3D.cpp,$(SOURCES_CXX)),)
|
|
RENDERER_DEFINES += -DHAVE_LEGACY3D
|
|
endif
|
|
|
|
ifneq ($(filter $(platform),osx android rpi64 aarch64 linux-aarch64 ios-arm64 tvos-arm64),$(platform))
|
|
RENDERER_DEFINES += -DHAVE_QUAD_RENDERING
|
|
endif
|
|
|
|
ifneq ($(filter $(platform),android rpi64 aarch64 linux-aarch64 ios-arm64 tvos-arm64),$(platform))
|
|
RENDERER_DEFINES += -DHAVE_CRT_COLOURS
|
|
RENDERER_DEFINES += -DHAVE_SUPERSAMPLING
|
|
endif
|
|
|
|
# GIT version
|
|
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
|
|
ifneq ($(GIT_VERSION)," unknown")
|
|
COREDEFINES += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
|
endif
|
|
|
|
# Platform-specific defines (to be assembled with COREDEFINES into final DEFINES)
|
|
PLATFORM_DEFINES :=
|
|
|
|
# ============================================================
|
|
# Platform-Specific Configuration
|
|
# ============================================================
|
|
|
|
# ============ UNIX/LINUX (Default) ============
|
|
ifeq ($(platform),unix)
|
|
TARGET := $(TARGET_NAME)_libretro.so
|
|
LDFLAGS += -shared -fPIC
|
|
CFLAGS += -fPIC
|
|
CXXFLAGS += -fPIC
|
|
LIBS += -ldl -lm -lz
|
|
ifeq ($(strip $(CROSS_COMPILE)),)
|
|
INCFLAGS += -I/usr/include
|
|
endif
|
|
endif
|
|
|
|
# ============ Linux ARM64 (native — CI runner, RPi4/5, ARM64 SBCs) ============
|
|
# Auto-selected when platform is unset and uname -m is aarch64.
|
|
# Uses the native compiler; enables GLES3 + JIT (required for RetroArch on RPi).
|
|
# For cross-compiling from x86 to RPi, use platform=rpi64 instead.
|
|
ifeq ($(platform),linux-aarch64)
|
|
TARGET := $(TARGET_NAME)_libretro.so
|
|
fpic := -fPIC
|
|
SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,-no-undefined
|
|
LDFLAGS += $(SHARED)
|
|
CFLAGS += -fPIC
|
|
CXXFLAGS += -fPIC
|
|
LIBS += -ldl -lm -lz
|
|
|
|
PLATFORM_DEFINES += -DARM -D__aarch64__ -DLSB_FIRST -DGL_GLEXT_PROTOTYPES -DHAVE_PPC_JIT
|
|
PLATFORM_DEFINES += -DGLES -Dgles -DHAVE_OPENGLES=1 -DHAVE_OPENGLES3=1 -DCORE_GLES -D__glext_h_ -D__GLEXT_H_
|
|
|
|
CXXFLAGS += -std=c++17
|
|
endif
|
|
|
|
# ============ iOS / tvOS (arm64) ============
|
|
# Both are the GLES build with Apple's SDK in front of it: the renderer resolves
|
|
# every entry point through glsym, so nothing links against a GL framework here
|
|
# any more than it does on the other GLES platforms, and OpenGLES is deprecated
|
|
# on these systems anyway.
|
|
#
|
|
# No PPC JIT. Writing and then executing the same page needs an entitlement that
|
|
# a libretro core cannot ask for on stock iOS or tvOS, so the recompiler is out
|
|
# and Model 3 runs on the interpreter. That is the same bargain every emulator
|
|
# on these systems makes, and it is the reason to be honest about what the
|
|
# artifact is rather than to leave the platform unbuilt.
|
|
#
|
|
# The dylib names are what the libretro ios-arm64 and tvos-arm64 templates look
|
|
# for, and their after_script checks the platform recorded in the Mach-O, which
|
|
# is what -isysroot and the version-min flag put there.
|
|
ifneq ($(filter $(platform),ios-arm64 tvos-arm64),)
|
|
ifeq ($(platform),ios-arm64)
|
|
TARGET := $(TARGET_NAME)_libretro_ios.dylib
|
|
APPLE_SDK := $(shell xcrun -sdk iphoneos -show-sdk-path)
|
|
APPLE_MIN := -miphoneos-version-min=13.0
|
|
PLATFORM_DEFINES += -DIOS
|
|
else
|
|
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
|
|
APPLE_SDK := $(shell xcrun -sdk appletvos -show-sdk-path)
|
|
APPLE_MIN := -mappletvos-version-min=13.0
|
|
PLATFORM_DEFINES += -DTVOS
|
|
endif
|
|
|
|
# Same lesson as the bundled headers above: a tool that is not there should
|
|
# stop the build where it is missing, not hand the compiler an empty
|
|
# -isysroot and let it fail later on a header it cannot find.
|
|
ifeq ($(APPLE_SDK),)
|
|
$(error xcrun found no SDK for $(platform) - is Xcode installed and selected?)
|
|
endif
|
|
|
|
CC := clang
|
|
CXX := clang++
|
|
|
|
ARCHFLAGS := -arch arm64 -isysroot $(APPLE_SDK) $(APPLE_MIN)
|
|
CFLAGS += -fPIC $(ARCHFLAGS)
|
|
CXXFLAGS += -fPIC $(ARCHFLAGS) -std=c++17
|
|
LDFLAGS += -dynamiclib -fPIC $(ARCHFLAGS)
|
|
|
|
# dlopen lives in libc on these systems, so there is no -ldl to link.
|
|
LIBS += -lm -lz
|
|
|
|
PLATFORM_DEFINES += -DARM -D__aarch64__ -DLSB_FIRST -DGL_GLEXT_PROTOTYPES
|
|
PLATFORM_DEFINES += -DGLES -Dgles -DHAVE_OPENGLES=1 -DHAVE_OPENGLES3=1 -DCORE_GLES -D__glext_h_ -D__GLEXT_H_
|
|
PLATFORM_DEFINES += -DGL_SILENCE_DEPRECATION
|
|
endif
|
|
|
|
# ============ macOS / osxcross ============
|
|
ifeq ($(platform),osx)
|
|
TARGET := $(TARGET_NAME)_libretro.dylib
|
|
# __gcov_dump is an optional profiling hook. Keep only that symbol weakly
|
|
# importable so missing core dependencies still fail at link time.
|
|
LDFLAGS += -dynamiclib -fPIC -Wl,-U,___gcov_dump
|
|
CFLAGS += -fPIC
|
|
CXXFLAGS += -fPIC
|
|
LIBS += -lm -framework OpenGL -framework CoreFoundation
|
|
PLATFORM_DEFINES += -DGL_SILENCE_DEPRECATION
|
|
|
|
ifeq ($(system_platform),osx)
|
|
# Native macOS build (CI macOS runner or local Mac developer build).
|
|
# Build for the host arch so the CI x64 job → x86_64, arm64 job → arm64.
|
|
NATIVE_ARCH := $(shell uname -m)
|
|
ARCHFLAGS := -arch $(NATIVE_ARCH) -mmacosx-version-min=10.15
|
|
CFLAGS += $(ARCHFLAGS)
|
|
CXXFLAGS += $(ARCHFLAGS)
|
|
LDFLAGS += $(ARCHFLAGS)
|
|
|
|
# Apple Silicon requires MAP_JIT plus per-thread W^X switching. Keep
|
|
# Intel and universal cross-builds on the interpreter.
|
|
ifeq ($(NATIVE_ARCH),arm64)
|
|
PLATFORM_DEFINES += -DHAVE_PPC_JIT
|
|
endif
|
|
else
|
|
# Cross-compile from Linux via osxcross (universal x86_64 + arm64 dylib).
|
|
OSXCROSS_ROOT ?= /opt/osxcross
|
|
OSXCROSS_PATH := $(OSXCROSS_ROOT)/target/bin
|
|
|
|
ifeq ($(wildcard $(OSXCROSS_PATH)/o64-clang++),)
|
|
$(error osxcross not found at $(OSXCROSS_ROOT). Install: cd /tmp && git clone https://github.com/tpoechtrager/osxcross.git && cd osxcross && wget -nc https://github.com/rtrussell/osxcross-build/releases/download/12.0/MacOSX12.0.sdk.tar.xz -O tarballs/MacOSX12.0.sdk.tar.xz && ./build.sh)
|
|
endif
|
|
|
|
export PATH := $(OSXCROSS_PATH):$(PATH)
|
|
export LD_LIBRARY_PATH := $(OSXCROSS_ROOT)/target/lib:$(LD_LIBRARY_PATH)
|
|
override CC := o64-clang
|
|
override CXX := o64-clang++
|
|
override LD := o64-clang++
|
|
|
|
ARCHFLAGS := -arch x86_64 -arch arm64
|
|
CFLAGS += $(ARCHFLAGS)
|
|
CXXFLAGS += $(ARCHFLAGS)
|
|
LDFLAGS += $(ARCHFLAGS)
|
|
|
|
MACOSX_SDK ?= /opt/osxcross/target/SDK/MacOSX12.0.sdk
|
|
CFLAGS += -isysroot $(MACOSX_SDK)
|
|
CXXFLAGS += -isysroot $(MACOSX_SDK)
|
|
LDFLAGS += -isysroot $(MACOSX_SDK)
|
|
|
|
LDFLAGS += -static-libstdc++
|
|
endif
|
|
endif
|
|
|
|
# ============ ANDROID ============
|
|
ifeq ($(platform),android)
|
|
TARGET := $(TARGET_NAME)_libretro_android.so
|
|
fpic := -fPIC
|
|
SHARED := -shared
|
|
PLATFORM_DEFINES += -DANDROID -D__LIBRETRO__ -DPSS_STYLE=1 -D_FILE_OFFSET_BITS=64
|
|
PLATFORM_DEFINES += -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE
|
|
PLATFORM_DEFINES += -DEGL_EGLEXT_PROTOTYPES
|
|
LIBS += -lGLESv3 -llog -lz
|
|
|
|
# Prepend Android shim headers to resolve <GL/glew.h> to our shim
|
|
INCFLAGS := -I$(CORE_DIR)/Src/OSD/Android/include $(INCFLAGS)
|
|
|
|
# --- NDK Detection ---
|
|
# Check common locations if NDK_ROOT is not already set
|
|
ifeq ($(NDK_ROOT),)
|
|
NDK_ROOT := $(shell ls -d ~/Android/Sdk/ndk/28.2.13676358 2>/dev/null)
|
|
endif
|
|
|
|
# Performance Flags from Mupen64Plus
|
|
HAVE_NEON := 0
|
|
ifeq ($(arch),arm)
|
|
HAVE_NEON := 1
|
|
endif
|
|
ifeq ($(arch),arm64)
|
|
HAVE_NEON := 1
|
|
endif
|
|
|
|
# LTO Control - Disable for Android due to PIC relocation issues with NDK clang
|
|
HAVE_LTCG := 0
|
|
|
|
# If NDK is found, use its Clang toolchain
|
|
ifneq ($(NDK_ROOT),)
|
|
# Default to aarch64 (64-bit ARM) if no 'arch' is specified
|
|
ifeq ($(arch),arm)
|
|
ARCH_TRIPLE := arm-linux-androideabi
|
|
CLANG_TRIPLE := armv7a-linux-androideabi24
|
|
PLATFORM_DEFINES += -march=armv7-a -mfloat-abi=softfp -mfpu=neon
|
|
else ifeq ($(arch),x86)
|
|
ARCH_TRIPLE := i686-linux-android
|
|
CLANG_TRIPLE := i686-linux-android24
|
|
else ifeq ($(arch),x86_64)
|
|
ARCH_TRIPLE := x86_64-linux-android
|
|
CLANG_TRIPLE := x86_64-linux-android24
|
|
else
|
|
# Default to arm64 (aarch64)
|
|
ARCH_TRIPLE := aarch64-linux-android
|
|
CLANG_TRIPLE := aarch64-linux-android24
|
|
PLATFORM_DEFINES += -DHAVE_PPC_JIT
|
|
endif
|
|
|
|
TOOLCHAIN := $(NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin
|
|
CC := $(TOOLCHAIN)/$(CLANG_TRIPLE)-clang
|
|
CXX := $(TOOLCHAIN)/$(CLANG_TRIPLE)-clang++
|
|
LD := $(CXX)
|
|
|
|
# Android Clang usually needs some extra flags
|
|
CFLAGS += -ffunction-sections -fdata-sections
|
|
CXXFLAGS += -ffunction-sections -fdata-sections
|
|
LDFLAGS += $(SHARED) -Wl,-soname,$(TARGET) -Wl,--no-undefined
|
|
|
|
# Link C++ library statically to avoid dlopen issues on device
|
|
LDFLAGS += -static-libstdc++
|
|
else
|
|
# Fallback to generic names if NDK not found
|
|
CC = arm-linux-androideabi-gcc
|
|
CXX = arm-linux-androideabi-g++
|
|
LD := $(CXX)
|
|
endif
|
|
|
|
ifeq ($(HAVE_NEON),1)
|
|
PLATFORM_DEFINES += -DHAVE_NEON -D__ARM_NEON__ -ftree-vectorize
|
|
endif
|
|
|
|
OBJOUT = -o
|
|
LINKOUT = -o
|
|
LIBM := -lm
|
|
WARNING_DEFINES := -Wno-write-strings
|
|
|
|
# Ensure CXXFLAGS is appended
|
|
CXXFLAGS += -std=c++17
|
|
|
|
ifeq ($(DEBUG),1)
|
|
CFLAGS += -O0 -g -DDEBUG
|
|
CXXFLAGS += -O0 -g -DDEBUG
|
|
else
|
|
CFLAGS += -O3 -DNDEBUG
|
|
CXXFLAGS += -O3 -DNDEBUG
|
|
|
|
# General Performance Optimizations
|
|
CFLAGS += -ffast-math -funsafe-math-optimizations -fomit-frame-pointer
|
|
CXXFLAGS += -ffast-math -funsafe-math-optimizations -fomit-frame-pointer
|
|
|
|
# Visibility Optimizations
|
|
CFLAGS += -fvisibility=hidden
|
|
CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
|
|
|
# LTO (Link Time Optimization)
|
|
ifeq ($(HAVE_LTCG),1)
|
|
CFLAGS += -flto
|
|
CXXFLAGS += -flto
|
|
LDFLAGS += -flto
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
# ============ WINDOWS / MinGW ============
|
|
ifeq ($(platform),win)
|
|
TARGET := $(TARGET_NAME)_libretro.dll
|
|
LDFLAGS += -shared
|
|
CFLAGS += -D_WIN32 -DWIN32
|
|
CXXFLAGS += -D_WIN32 -DWIN32
|
|
|
|
ifeq ($(system_platform),win)
|
|
# Native Windows build with MinGW
|
|
ifeq ($(origin CC),default)
|
|
CC := gcc
|
|
endif
|
|
ifeq ($(origin CXX),default)
|
|
CXX := g++
|
|
endif
|
|
else
|
|
# Cross-compile to Windows (from Linux). Only fall back to the plain
|
|
# mingw-w64 names when no toolchain was handed to us -- the buildbot's
|
|
# MXE container exports its own (x86_64-w64-mingw32.static-gcc), and
|
|
# overriding that would point us at compilers that do not exist there.
|
|
ifeq ($(WIN_PLATFORM),win32)
|
|
MINGW_PREFIX ?= i686-w64-mingw32
|
|
else
|
|
MINGW_PREFIX ?= x86_64-w64-mingw32
|
|
endif
|
|
ifeq ($(origin CC),default)
|
|
CC := $(MINGW_PREFIX)-gcc
|
|
endif
|
|
ifeq ($(origin CXX),default)
|
|
CXX := $(MINGW_PREFIX)-g++
|
|
endif
|
|
ifeq ($(origin AR),default)
|
|
AR := $(MINGW_PREFIX)-ar
|
|
endif
|
|
endif
|
|
|
|
# Static-link MinGW runtimes and zlib so the DLL is self-contained — no
|
|
# libgcc_s_seh-1.dll / libstdc++-6.dll / zlib1.dll required on the user's system.
|
|
LDFLAGS += -static-libgcc -static-libstdc++
|
|
LIBS += -lm -Wl,-Bstatic -lz -Wl,-Bdynamic -lopengl32 -lglu32 -lgdi32
|
|
endif
|
|
|
|
# ============ Raspberry Pi 64-bit ============
|
|
ifeq ($(platform),rpi64)
|
|
CC = aarch64-linux-gnu-gcc
|
|
CXX = aarch64-linux-gnu-g++
|
|
LD = aarch64-linux-gnu-g++
|
|
|
|
TARGET := $(TARGET_NAME)_libretro_aarch64.so
|
|
fpic := -fPIC
|
|
SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,-no-undefined
|
|
|
|
# 1. ARCHITECTURE & FEATURE FLAGS
|
|
PLATFORM_DEFINES += -DARM -D__aarch64__ -DLSB_FIRST -DGL_GLEXT_PROTOTYPES -DHAVE_PPC_JIT
|
|
PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -funsafe-math-optimizations
|
|
# Prevent system header redeclaration
|
|
PLATFORM_DEFINES += -DGLES -Dgles -DHAVE_OPENGLES=1 -DHAVE_OPENGLES3=1 -DCORE_GLES -D__glext_h_ -D__GLEXT_H_
|
|
|
|
# 2. CPU TUNING
|
|
# platform=rpi64 always matches above, so the specific board must be
|
|
# selected via board=rpi5 / board=rpi4 (e.g. make platform=rpi64 board=rpi5)
|
|
ifeq ($(board), rpi5)
|
|
PLATFORM_DEFINES += -mcpu=cortex-a76
|
|
else ifeq ($(board), rpi4)
|
|
PLATFORM_DEFINES += -mcpu=cortex-a72
|
|
else
|
|
PLATFORM_DEFINES += -mcpu=cortex-a53
|
|
endif
|
|
|
|
# 3. LIBRARY & PATHS
|
|
LDFLAGS += $(SHARED) -L/usr/lib/aarch64-linux-gnu
|
|
LIBS := -lGLESv2 -lz -lm
|
|
|
|
# 4. CXXFLAGS
|
|
CXXFLAGS += -std=c++17
|
|
endif
|
|
|
|
# ============ aarch64 (Generic ARM64) ============
|
|
ifeq ($(platform),aarch64)
|
|
CC = aarch64-linux-gnu-gcc
|
|
CXX = aarch64-linux-gnu-g++
|
|
LD = aarch64-linux-gnu-g++
|
|
|
|
TARGET := $(TARGET_NAME)_libretro.so
|
|
fpic := -fPIC
|
|
SHARED := -shared -Wl,--version-script=$(CORE_DIR)/link.T -Wl,-no-undefined
|
|
|
|
# 1. ARCHITECTURE & FEATURE FLAGS
|
|
PLATFORM_DEFINES += -DARM -D__aarch64__ -DLSB_FIRST -DGL_GLEXT_PROTOTYPES -DHAVE_PPC_JIT
|
|
PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -funsafe-math-optimizations
|
|
# Prevent system header redeclaration
|
|
PLATFORM_DEFINES += -DGLES -Dgles -DHAVE_OPENGLES=1 -DHAVE_OPENGLES3=1 -DCORE_GLES -D__glext_h_ -D__GLEXT_H_
|
|
|
|
# 2. LIBRARY & PATHS
|
|
LDFLAGS += $(SHARED) -L/usr/lib/aarch64-linux-gnu
|
|
LIBS := -lGLESv2 -lz -lm
|
|
|
|
# 3. CXXFLAGS
|
|
CXXFLAGS += -std=c++17
|
|
endif
|
|
|
|
# ============ webOS ============
|
|
ifneq (,$(or $(findstring webos,$(CROSS_COMPILE)),$(findstring starfish,$(CROSS_COMPILE))))
|
|
SOURCES_C := $(filter-out %/glsym/glsym_gl.c,$(SOURCES_C))
|
|
SOURCES_C += $(LIBRETRO_COMM_DIR)/glsym/glsym_es3.c
|
|
|
|
# 1. ARCHITECTURE & FEATURE FLAGS
|
|
ifneq (,$(findstring aarch64,$(CROSS_COMPILE)))
|
|
PLATFORM_DEFINES += -DARM -D__aarch64__ -DLSB_FIRST -DGL_GLEXT_PROTOTYPES -DHAVE_PPC_JIT
|
|
endif
|
|
PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -funsafe-math-optimizations
|
|
|
|
# Prevent system header redeclaration
|
|
PLATFORM_DEFINES += -DGLES -Dgles -DHAVE_OPENGLES=1 -DHAVE_OPENGLES3=1 -DCORE_GLES -D__glext_h_ -D__GLEXT_H_
|
|
|
|
# 2. LIBRARY & PATHS
|
|
LIBS := -lGLESv2 -lz -lm
|
|
endif
|
|
|
|
OBJECTS := $(SOURCES_C:.c=.o) $(SOURCES_CXX:.cpp=.o)
|
|
DEPFILES := $(OBJECTS:.o=.d)
|
|
|
|
# ============ COMMON COMPILER FLAGS ============
|
|
|
|
# C compiler defaults
|
|
CC ?= gcc
|
|
CXX ?= g++
|
|
AR ?= ar
|
|
|
|
# Assemble final DEFINES from COREDEFINES and PLATFORM_DEFINES (mirrors old build system)
|
|
DEFINES := $(COREDEFINES) $(PLATFORM_DEFINES) $(RENDERER_DEFINES)
|
|
OBJOUT ?= -o
|
|
LINKOUT ?= -o
|
|
LIBM ?= -lm
|
|
WARNING_DEFINES ?= -Wno-write-strings
|
|
|
|
# Base optimization and warning flags
|
|
CFLAGS := $(CFLAGS) -Wall -Wextra -O3 -ffast-math -DHAVE_ZLIB $(fpic)
|
|
CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -std=c++17 -O3 -ffast-math -DHAVE_ZLIB $(fpic)
|
|
|
|
# Include path flags and final defines assembly
|
|
CFLAGS += $(INCFLAGS) $(DEFINES)
|
|
CXXFLAGS += $(INCFLAGS) $(DEFINES)
|
|
|
|
# Debug settings
|
|
ifeq ($(DEBUG),1)
|
|
CFLAGS := $(filter-out -O3,$(CFLAGS)) -g -O0 -DDEBUG
|
|
CXXFLAGS := $(filter-out -O3,$(CXXFLAGS)) -g -O0 -DDEBUG
|
|
LDFLAGS += -g
|
|
endif
|
|
|
|
# External zlib
|
|
ifeq ($(EXTERNAL_ZLIB),1)
|
|
INCFLAGS += $(shell pkg-config --cflags zlib)
|
|
LIBS += $(shell pkg-config --libs zlib)
|
|
else
|
|
LIBS += -lz
|
|
endif
|
|
|
|
# ============================================================
|
|
# Build Rules
|
|
# ============================================================
|
|
|
|
.DEFAULT_GOAL := all
|
|
|
|
BUNDLED_GAMES_XML_H := $(CORE_DIR)/Src/OSD/libretro/BundledGamesXml.h
|
|
BUNDLED_SUPERMODEL_H := $(CORE_DIR)/Src/OSD/libretro/BundledSupermodelIni.h
|
|
|
|
$(CORE_DIR)/Src/OSD/libretro/LibretroWrapper.o: \
|
|
$(BUNDLED_GAMES_XML_H) \
|
|
$(BUNDLED_SUPERMODEL_H)
|
|
|
|
.PHONY: all clean info
|
|
$(info PLATFORM_DEFINES ARE: $(PLATFORM_DEFINES))
|
|
all: $(BUNDLED_GAMES_XML_H) $(BUNDLED_SUPERMODEL_H) $(TARGET)
|
|
|
|
$(BUNDLED_GAMES_XML_H): $(CORE_DIR)/Config/Games.xml
|
|
xxd -i $< | sed 's/unsigned char.*\[\]/const unsigned char bundled_games_xml[]/' \
|
|
| sed 's/unsigned int.*_len/const unsigned int bundled_games_xml_len/' > $@
|
|
|
|
# Track included headers so incremental builds rebuild every object whose ABI
|
|
# may have changed. This is especially important for shared core option types.
|
|
-include $(DEPFILES)
|
|
|
|
$(BUNDLED_SUPERMODEL_H): $(CORE_DIR)/Config/Supermodel.ini
|
|
xxd -i $< | sed 's/unsigned char.*\[\]/const unsigned char bundled_supermodel_ini[]/' \
|
|
| sed 's/unsigned int.*_len/const unsigned int bundled_supermodel_ini_len/' > $@
|
|
|
|
$(TARGET): $(OBJECTS)
|
|
@echo "Linking $(TARGET)..."
|
|
$(CXX) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
|
@echo "Build complete: $@"
|
|
|
|
# Special handling for ppc.o: strip -ffast-math to avoid FENV_ACCESS pragma conflicts
|
|
# ppc_ops.c contains #pragma STDC FENV_ACCESS ON which requires precise FP semantics
|
|
# For Android DEBUG builds, also ensure -fPIC is applied to prevent relocation errors
|
|
$(CORE_DIR)/Src/CPU/PowerPC/ppc.o: CXXFLAGS := $(filter-out -ffast-math -funsafe-math-optimizations,$(CXXFLAGS))
|
|
$(CORE_DIR)/Src/CPU/PowerPC/ppc.o: CXXFLAGS += -Wno-unused-parameter
|
|
|
|
# Both 3D renderers explicitly sanitize NaN/Inf fog values used by Star Wars
|
|
# Trilogy. Fast-math assumes these values cannot exist and removes the checks.
|
|
IEEE_FP_RENDERER_OBJECTS := $(CORE_DIR)/Src/Graphics/New3D/New3D.o \
|
|
$(CORE_DIR)/Src/Graphics/Legacy3D/Legacy3D.o
|
|
$(IEEE_FP_RENDERER_OBJECTS): CXXFLAGS := $(filter-out -ffast-math -funsafe-math-optimizations,$(CXXFLAGS))
|
|
|
|
ifeq ($(platform),android)
|
|
ifeq ($(DEBUG),1)
|
|
$(CORE_DIR)/Src/CPU/PowerPC/ppc.o: CXXFLAGS += -fPIC
|
|
endif
|
|
endif
|
|
|
|
# These vendored/generated sources intentionally expose platform-dependent
|
|
# parameters and legacy implementation details that are unused by this core.
|
|
# Keep their known warning noise local instead of weakening warnings globally.
|
|
MUSASHI_OBJECTS := $(CORE_DIR)/Src/CPU/68K/Musashi/m68kcpu.o \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kops.o \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopac.o \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopdm.o \
|
|
$(CORE_DIR)/Src/CPU/68K/Musashi/generated/m68kopnz.o
|
|
LIBRETRO_COMMON_WARNING_OBJECTS := $(LIBRETRO_COMM_DIR)/file/file_path.o \
|
|
$(LIBRETRO_COMM_DIR)/file/retro_dirent.o \
|
|
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.o \
|
|
$(LIBRETRO_COMM_DIR)/string/stdstring.o
|
|
|
|
$(MUSASHI_OBJECTS): CFLAGS += -Wno-unused-parameter
|
|
$(DEPS_DIR)/ugui/ugui.o: CFLAGS += -Wno-sign-compare -Wno-bitwise-op-parentheses -Wno-unused-but-set-variable
|
|
$(LIBRETRO_COMMON_WARNING_OBJECTS): CFLAGS += -Wno-unused-parameter -Wno-sign-compare
|
|
|
|
%.o: %.c
|
|
$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<
|
|
|
|
%.o: %.cpp
|
|
$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $<
|
|
|
|
clean:
|
|
@echo "Cleaning..."
|
|
@rm -f $(OBJECTS) $(DEPFILES) $(TARGET)
|
|
@echo "Clean complete"
|
|
|
|
info:
|
|
@echo "Platform: $(platform)"
|
|
@echo "Target: $(TARGET)"
|
|
@echo "CC: $(CC)"
|
|
@echo "CXX: $(CXX)"
|
|
@echo "CFLAGS: $(CFLAGS)"
|
|
@echo "CXXFLAGS: $(CXXFLAGS)"
|
|
@echo "LDFLAGS: $(LDFLAGS)"
|
|
@echo "LIBS: $(LIBS)"
|