# Native installer plus a standalone PC setup host. PYTHON := python3 LOADER := third_party/ps5-webkit-remote-loader INSTALLER_COMMON := $(LOADER)/installer/common include $(INSTALLER_COMMON)/common.mk SDK := /opt/ps5-payload-sdk CC := $(SDK)/bin/prospero-clang STRIP := $(SDK)/bin/prospero-strip TARGET := $(SDK)/target CFLAGS := -Os -Wall -ffunction-sections -fdata-sections -Iinclude -I$(INSTALLER_COMMON) -I$(TARGET)/include LDFLAGS := -Wl,--gc-sections LIBS := $(TARGET)/lib/libmicrohttpd.a -L$(TARGET)/lib -lpthread \ -lSceNetCtl -lSceUserService -lSceSystemService -lSceAppInstUtil SRCS := src/main.c src/http_server.c $(INSTALLER_COMMON_SRCS) ELF := installer.elf # One version per make invocation, including dirty-tree builds. ifndef BUILD_VERSION BUILD_VERSION := $(shell $(PYTHON) tools/gen_version.py --print) endif export BUILD_VERSION ifndef BUILD_TITLE BUILD_TITLE := $(shell $(PYTHON) tools/gen_version.py --title) endif BUILDER := $(PYTHON) $(LOADER)/tools/build_standalone.py CHAINS := poops relapse # One standalone page per chain, carrying elfldr-check.js, the chain's exploit, # then autoload.js. The chain sources are unmodified # submodule payloads; each exploit prefetches elfldr/kexp itself. # Autoloader appearance is embedded through the upstream builder's hooks. # Each variable accepts a whitespace-separated list of file paths. PAGE_CSS ?= frontend/autoloader/style.css PAGE_JS ?= frontend/autoloader/app.js PAGE_CONFIG := build/page-config.js ELFLDR_TAG := v0.26-bb1e117 ELFLDR_VIRTUAL := shared/elfldr-ps5-$(ELFLDR_TAG).elf PAGE_FLAGS := --elfldr $(ELFLDR_VIRTUAL)=build/deps/elfldr.elf \ $(foreach file,$(PAGE_CSS),--css "$(file)") \ --js "$(PAGE_CONFIG)" \ $(foreach file,$(PAGE_JS),--js "$(file)") APP_PAGE := build/autoloader/index.html HOST_PAGE := build/host/index.html STAGE := frontend/dist REGISTRY := include/file_registry.h include/file_registry.c ICONS := assets/icon0.png assets/icon.ico INSTALLER_LOGO := frontend/installer-page/logo.svg HOST_PAYLOAD ?= $(ELF) PAYLOAD_TAG ?= $(shell git -C third_party/ps5-unified-autoloader describe --tags --always 2>/dev/null || echo v0.1.5-915a65e) AUTOLOAD_PAYLOAD_VIRTUAL ?= ps5-unified-autoloader-$(PAYLOAD_TAG).elf HOST_PAYLOAD_VIRTUAL ?= $(if $(filter-out installer.elf,$(notdir $(HOST_PAYLOAD))),$(notdir $(HOST_PAYLOAD)),webkit-autoloader-installer_v$(BUILD_VERSION).elf) # Optional cache-repair hardware test builds; use make clean all when changing. SIMULATE ?= 0 ifneq ($(SIMULATE),0) CFLAGS += -DINSTALLER_SIMULATE_CACHE_CORRUPTION=$(SIMULATE) endif all: $(ELF) version: $(PYTHON) tools/gen_version.py print-version: @echo $(BUILD_VERSION) test: node tools/test_elfldr_check.js node tools/test_autoload_payload.js node tools/test_installer.js node tools/test_selection_flow.js # Run on Linux or in the SDK container; PS5 services are stubbed. test-native: $(PYTHON) $(LOADER)/tools/installer_common_test.py icons: $(ICONS) $(INSTALLER_LOGO) assets/icon0.png: assets/icon.svg tools/gen_icons.py $(PYTHON) tools/gen_icons.py assets/icon.ico: assets/icon0.png @test -f $@ || $(PYTHON) tools/gen_icons.py $(INSTALLER_LOGO): assets/icon.svg cp $< $@ payload-deps: ./tools/download_deps.sh # One page per chain: ELF loader check first, then exploit and autoload. Both # are cached, so the choice of chain never has to invalidate anything. page: payload-deps @mkdir -p build/autoloader $(PYTHON) tools/gen_version.py --page-config $(PAGE_CONFIG) @for chain in $(CHAINS); do \ echo "$(BUILDER) payloads/$$chain.js -> build/autoloader/$$chain.html"; \ $(BUILDER) $(CURDIR)/payloads/elfldr-check.js payloads/$$chain.js $(CURDIR)/payloads/autoload.js::$(AUTOLOAD_PAYLOAD_VIRTUAL) \ --title "$(BUILD_TITLE)" $(PAGE_FLAGS) \ --embed $(AUTOLOAD_PAYLOAD_VIRTUAL)=build/deps/autoload.elf \ -o $(CURDIR)/build/autoloader/$$chain.html || exit 1; \ done registry: version page $(INSTALLER_LOGO) rm -rf $(STAGE) @mkdir -p $(STAGE)/app/$(BUILD_VERSION) cp frontend/installer-page/index.html $(INSTALLER_LOGO) $(STAGE)/ cp frontend/pointer/index.html $(STAGE)/app/index.html @for chain in $(CHAINS); do \ cp build/autoloader/$$chain.html $(STAGE)/app/$(BUILD_VERSION)/$$chain.html || exit 1; \ done @echo "$(BUILD_VERSION)" > $(STAGE)/VERSION $(PYTHON) tools/gen_file_registry.py $(STAGE) $(word 1,$(REGISTRY)) $(word 2,$(REGISTRY)) $(ELF): registry icons $(SRCS) $(wildcard include/*.h) $(INSTALLER_COMMON_HEADERS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SRCS) include/file_registry.c $(LIBS) $(STRIP) $@ # The setup host embeds the installer ELF. It packages both chains (Relapse as # default index.html, Poops as poops.html) so firmwares where Relapse is # unsupported (9.05, 11.40) are automatically routed to Poops. HOST_RELAPSE := build/host/relapse.html HOST_POOPS := build/host/poops.html host: $(HOST_PAYLOAD) payload-deps assets/icon.ico @mkdir -p build/host $(PYTHON) tools/gen_version.py --page-config $(PAGE_CONFIG) $(BUILDER) $(CURDIR)/payloads/elfldr-check.js payloads/relapse.js $(CURDIR)/payloads/autoload.js::$(HOST_PAYLOAD_VIRTUAL) \ --title "$(BUILD_TITLE)" $(PAGE_FLAGS) \ --embed $(HOST_PAYLOAD_VIRTUAL)=$(HOST_PAYLOAD) -o $(CURDIR)/$(HOST_RELAPSE) $(BUILDER) $(CURDIR)/payloads/elfldr-check.js payloads/poops.js $(CURDIR)/payloads/autoload.js::$(HOST_PAYLOAD_VIRTUAL) \ --title "$(BUILD_TITLE)" $(PAGE_FLAGS) \ --embed $(HOST_PAYLOAD_VIRTUAL)=$(HOST_PAYLOAD) -o $(CURDIR)/$(HOST_POOPS) $(PYTHON) $(LOADER)/tools/build_host.py \ --page index.html=$(HOST_RELAPSE) \ --page poops.html=$(HOST_POOPS) \ --version $(BUILD_VERSION) --name "PS5 WEBKIT AUTOLOADER" --output webkit-autoloader-host.py dev: page $(PYTHON) -m http.server 8123 --bind 127.0.0.1 --directory build/autoloader clean: rm -rf $(STAGE) build/autoloader build/host rm -f $(ELF) $(REGISTRY) include/wkali_version.h webkit-autoloader-host.py rm -f $(PAGE_CONFIG) .PHONY: all version print-version test test-native icons payload-deps page registry host dev clean