diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df0a4a77..6d7a612d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,48 +27,33 @@ jobs: sudo apt -y --allow-downgrades install g++-10-multilib linux-libc-dev binutils-arm-none-eabi p7zip-full pkg-config libpugixml-dev ppa-purge sudo ppa-purge -y ppa:ubuntu-toolchain-r/test || true sudo dpkg --add-architecture i386 - sudo mkdir -pm755 /etc/apt/keyrings - sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key - sudo add-apt-repository ppa:cybermax-dexter/sdl2-backport - sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/$(lsb_release -cs)/winehq-$(lsb_release -cs).sources sudo apt update - sudo apt -y --allow-downgrades install --install-recommends winehq-stable + sudo apt -y --allow-downgrades install libc6:i386 - name: Checkout repo uses: actions/checkout@v4 - name: Set up repo run: | - mkdir -p ~/download - cd ~/download - wget https://github.com/pret/pmd-sky/raw/workflows/assets/mwccarm.zip - wget https://github.com/pret/pmd-sky/raw/workflows/assets/NitroSDK-4_2-071210-jp.7z - unzip mwccarm.zip - mv mwccarm $GITHUB_WORKSPACE/tools - 7z x NitroSDK-4_2-071210-jp.7z - mv tools/bin $GITHUB_WORKSPACE/tools - mv include/nitro/specfiles/ARM7-TS.lcf.template $GITHUB_WORKSPACE/sub/ - mv include/nitro/specfiles/ARM9-TS.lcf.template $GITHUB_WORKSPACE/ - mv include/nitro/specfiles/mwldarm.response.template $GITHUB_WORKSPACE/ - working-directory: ~ + make install_toolchain install_wibo install_metroskrew - name: Build North America env: GAME_LANGUAGE: NORTH_AMERICA GAME_REVISION: 0 - run: make -j${nproc} + run: make -j${nproc} USE_WIBO=1 USE_METROSKREW=1 - name: Build Europe env: GAME_LANGUAGE: EUROPE GAME_REVISION: 0 - run: make -j${nproc} + run: make -j${nproc} USE_WIBO=1 USE_METROSKREW=1 - name: Build Japan env: GAME_LANGUAGE: JAPAN GAME_REVISION: 0 - run: make -j${nproc} + run: make -j${nproc} USE_WIBO=1 USE_METROSKREW=1 - name: Webhook if: ${{ github.event_name == 'push' && env.CALCROM_WEBHOOK_URL != '' }} diff --git a/.gitignore b/.gitignore index 2ea2503c..f354f18f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,12 @@ tools/bin/** *.lcf.template *.response.template +# wibo +tools/wibo/** + +# metroskrew +tools/metroskrew/** + # Build folder build/** sub/build/** diff --git a/INSTALL.md b/INSTALL.md index fe5dd65a..de7859c9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -104,6 +104,45 @@ There are targets for building and testing changes to individual components with At the end of building each of these, there is a checksum verification step. This makes sure that the final product is byte-for-byte equivalent to the retail ROM. To disable this, append `COMPARE=0` to your command. +### Building with wibo and Metroskrew instead of wine + +**[wibo](https://github.com/decompals/wibo)** is a minimal and fast Win32 loader for decompilation work specifically. You can use it instead of wine on Linux (and x86 macOS, though untested). + +```shell +make install_wibo # download wibo into tools/wibo/ +make USE_WIBO=1 # build +``` + +To use wibo already on your `PATH`, pass `WIBO=wibo`: + +```shell +make USE_WIBO=1 WIBO=wibo +``` + +Likewise, to use your own build, replace that with `WIBO=`. + +If the Nitro SDK tools (`makerom`, `makelcf`, `makebanner`) cause issues under wibo, you can use wine for those while keeping wibo on the Metrowerks binaries: + +```shell +make USE_WIBO=1 NITROWINE=wine +``` + +**[Metroskrew](https://github.com/mid-kid/metroskrew)** is a port of the Metrowerks ARM compiler to Linux by relinking, which means that you can run the compilers directly as native Linux binaries using it. + +You will still need either Wine or Wibo for the SDK tools (which are separate from the compiler). + +In addition, Metroskrew's binaries are 32-bit x86, so you will need 32-bit glibc installed. That's: + +* libc6-i386 on Debian/Ubuntu +* lib32-glibc on Arch (multilib) +* glibc.i686 on Fedora + +```shell +make install_metroskrew # download Metroskrew into tools/metroskrew/ +#make install_wibo # download wibo into tools/wibo/, from earlier +make USE_WIBO=1 USE_METROSKREW=1 # build +``` + ### Windows If you get an error in saving configuration settings when specifying the license file, you need to add a system environment variable called `LM_LICENSE_FILE` and point it to the `license.dat` file. Alternatively, run `mwccarm.exe` from an Administrator command prompt, PowerShell, or WSL session. diff --git a/Makefile b/Makefile index 567a9a7d..16f94dac 100644 --- a/Makefile +++ b/Makefile @@ -56,14 +56,14 @@ $(BUILD_DIR)/component.files: main ; $(HEADER_TEMPLATE): ; $(ROM): $(ROMSPEC) tools filesystem main sub $(BANNER) - $(WINE) $(MAKEROM) $(MAKEROM_FLAGS) -DBUILD_DIR=$(BUILD_DIR) -M$(NITROFS_FILES_FILE) -DTITLE_NAME="$(TITLE_NAME)" -DBNR="$(BANNER)" -DHEADER_TEMPLATE="$(HEADER_TEMPLATE)" $< $@ + $(NITROWINE) $(MAKEROM) $(MAKEROM_FLAGS) -DBUILD_DIR=$(BUILD_DIR) -M$(NITROFS_FILES_FILE) -DTITLE_NAME="$(TITLE_NAME)" -DBNR="$(BANNER)" -DHEADER_TEMPLATE="$(HEADER_TEMPLATE)" $< $@ $(FIXROM) $@ --secure-crc $(SECURE_CRC) --game-code $(GAME_CODE) ifeq ($(COMPARE),1) $(SHA1SUM) -c $(buildname)/rom.sha1 endif $(BANNER): $(BANNER_SPEC) $(ICON_PNG:%.png=%.nbfp) $(ICON_PNG:%.png=%.nbfc) - $(WINE) $(MAKEBNR) $< $@ + $(NITROWINE) $(MAKEBNR) $< $@ us: ; @$(MAKE) GAME_LANGUAGE=NORTH_AMERICA eu: ; @$(MAKE) GAME_LANGUAGE=EUROPE @@ -88,4 +88,25 @@ install_toolchain: mv toolchain_tmp/nitro_sdk/include/nitro/specfiles/mwldarm.response.template . rm -r toolchain_tmp -.PHONY: compare install_toolchain +WIBO_VERSION := 1.2.0 +WIBO_ARCH := $(if $(filter aarch64 arm64,$(shell uname -m)),,$(if $(filter Darwin,$(shell uname -s)),macos,x86_64)) + +install_wibo: +ifeq ($(WIBO_ARCH),) + $(error No prebuilt wibo binaries are available for $(shell uname -s)/$(shell uname -m), build it from https://github.com/decompals/wibo and install it manually) +endif + rm -rf tools/wibo + mkdir -p tools/wibo + wget -O tools/wibo/wibo https://github.com/decompals/wibo/releases/download/$(WIBO_VERSION)/wibo-$(WIBO_ARCH) + chmod +x tools/wibo/wibo + tools/wibo/wibo --version + +METROSKREW_VER ?= 0.1.3 +METROSKREW_URL := https://github.com/mid-kid/metroskrew/releases/download/$(METROSKREW_VER)/metroskrew-linux.tar.xz + +install_metroskrew: + rm -rf tools/metroskrew + mkdir -p tools/metroskrew + wget -O- $(METROSKREW_URL) | tar -xJ -C tools/metroskrew --strip-components=1 + +.PHONY: compare install_toolchain install_wibo install_metroskrew diff --git a/common.mk b/common.mk index 79b2dff0..10e6f205 100644 --- a/common.mk +++ b/common.mk @@ -31,9 +31,19 @@ include $(WORK_DIR)/platform.mk include $(WORK_DIR)/binutils.mk # NitroSDK tools -MWCC = $(TOOLSDIR)/mwccarm/$(MWCCVER)/mwccarm.exe -MWAS = $(TOOLSDIR)/mwccarm/$(MWCCVER)/mwasmarm.exe -MWLD = $(BACK_REL)/$(TOOLSDIR)/mwccarm/$(MWCCVER)/mwldarm.exe +MWAS_EXE = $(TOOLSDIR)/mwccarm/$(MWCCVER)/mwasmarm.exe +ifneq ($(USE_METROSKREW),0) + SKREWRAP := $(abspath $(TOOLSDIR)/metroskrew/bin/skrewrap) + SKREW_SDK = $(TOOLSDIR)/metroskrew/share/metroskrew/sdk/ds/$(MWCCVER) + skrew_ver = $(patsubst $(1)-%.exe,%,$(shell cat $(SKREW_SDK)/$(1).exe.txt)) + MWCC = $(SKREWRAP) mwccarm -wrap:ver $(call skrew_ver,mwccarm) + MWAS = $(SKREWRAP) mwasmarm -wrap:ver $(call skrew_ver,mwasmarm) + MWLD = $(SKREWRAP) mwldarm -wrap:ver $(call skrew_ver,mwldarm) +else + MWCC = $(WINE) $(TOOLSDIR)/mwccarm/$(MWCCVER)/mwccarm.exe + MWAS = $(WINE) $(TOOLSDIR)/mwccarm/$(MWCCVER)/mwasmarm.exe + MWLD = $(WINE) $(BACK_REL)/$(TOOLSDIR)/mwccarm/$(MWCCVER)/mwldarm.exe +endif MAKEROM := $(TOOLSDIR)/bin/makerom.exe MAKELCF := $(TOOLSDIR)/bin/makelcf.exe MAKEBNR := $(TOOLSDIR)/bin/makebanner.exe @@ -146,11 +156,11 @@ LIBRARY_INCLUDE_FLAGS := -I$(WORK_DIR)/lib/msl/include/MSL_C $(foreach dname,$(L SRC_INCLUDE_FLAGS := -i ./include -i ./include/library -i $(WORK_DIR)/files $(LIBRARY_INCLUDE_FLAGS) SDK_INCLUDE_FLAGS := $(LIBRARY_INCLUDE_FLAGS) -MW_COMPILE_SRC = $(WINE) $(MWCC) $(OPTFLAGS) $(MWCFLAGS) $(SRC_INCLUDE_FLAGS) -i $(PRECOMPILE_OBJ_DIR) -prefix $(PRECOMPILE_OBJ_BASENAME) -MW_COMPILE_LIB = $(WINE) $(MWCC) $(OPTFLAGS_SDK) $(MWCFLAGS_LIB) $(SRC_INCLUDE_FLAGS) -i $(PRECOMPILE_OBJ_DIR) -prefix $(PRECOMPILE_OBJ_BASENAME) -MW_COMPILE_SRC_PRECOMPILE = $(WINE) $(MWCC) $(MWCFLAGS) $(SRC_INCLUDE_FLAGS) +MW_COMPILE_SRC = $(MWCC) $(OPTFLAGS) $(MWCFLAGS) $(SRC_INCLUDE_FLAGS) -i $(PRECOMPILE_OBJ_DIR) -prefix $(PRECOMPILE_OBJ_BASENAME) +MW_COMPILE_LIB = $(MWCC) $(OPTFLAGS_SDK) $(MWCFLAGS_LIB) $(SRC_INCLUDE_FLAGS) -i $(PRECOMPILE_OBJ_DIR) -prefix $(PRECOMPILE_OBJ_BASENAME) +MW_COMPILE_SRC_PRECOMPILE = $(MWCC) $(MWCFLAGS) $(SRC_INCLUDE_FLAGS) -MW_ASSEMBLE = $(WINE) $(MWAS) $(MWASFLAGS) +MW_ASSEMBLE = $(MWAS) $(MWASFLAGS) export MWCIncludes := lib/include @@ -171,8 +181,8 @@ DUMMY := $(shell mkdir -p $(ALL_BUILDDIRS) $(PRECOMPILE_OBJ_DIR)) .PRECIOUS: $(SBIN) .NOTPARALLEL: -.PHONY: $(MWAS) -$(MWAS): +.PHONY: $(MWAS_EXE) +$(MWAS_EXE): $(ASPATCH) -q $@ ifeq ($(NODEP),) @@ -224,7 +234,7 @@ $(BUILD_DIR)/lib/%.o: lib/%.c $(BUILD_DIR)/lib/%.d $(NITRO_PRECOMPILE_OBJ) $(BUILD_DIR)/%.o: %.s $(BUILD_DIR)/%.o: %.s $(BUILD_DIR)/%.d - $(WINE) $(MWAS) $(MWASFLAGS) -I$(dir $<) $(DEPFLAGS) -o $@ $< + $(MWAS) $(MWASFLAGS) -I$(dir $<) $(DEPFLAGS) -o $@ $< @$(call fixdep,$(BUILD_DIR)/$*.d) include $(wildcard $(DEPFILES)) @@ -237,12 +247,12 @@ $(BUILD_DIR)/%.o: %.c $(BUILD_C) $@ $< $(BUILD_DIR)/%.o: %.s - $(WINE) $(MWAS) $(MWASFLAGS) -o $@ $< + $(MWAS) $(MWASFLAGS) -o $@ $< endif $(NATIVE_TOOLS): tools -tools: $(TOOLDIRS) $(MWAS) +tools: $(TOOLDIRS) $(MWAS_EXE) $(TOOLDIRS): @$(MAKE) -C $@ @@ -251,7 +261,7 @@ clean-tools: $(foreach tool,$(TOOLDIRS),$(MAKE) -C $(tool) clean;) $(LCF): $(LSF) $(LCF_TEMPLATE) - $(WINE) $(MAKELCF) $(MAKELCF_FLAGS) $^ $@ + $(NITROWINE) $(MAKELCF) $(MAKELCF_FLAGS) $^ $@ ifeq ($(PROC),arm946e) $(SED) -i '1i KEEP_SECTION\n{\n\t.exceptix\n}' $@ else @@ -262,13 +272,13 @@ RESPONSE_TEMPLATE := $(PROJECT_ROOT)/mwldarm.response.template RESPONSE_TEMPLATE_NT := $(PROJECT_ROOT_NT)/mwldarm.response.template $(RESPONSE): $(LSF) $(RESPONSE_TEMPLATE) - $(WINE) $(MAKELCF) $(MAKELCF_FLAGS) $< $(RESPONSE_TEMPLATE_NT) $@ + $(NITROWINE) $(MAKELCF) $(MAKELCF_FLAGS) $< $(RESPONSE_TEMPLATE_NT) $@ # Locate crt0.o CRT0_OBJ := lib/asm/crt0.o $(NEF): $(LCF) $(RESPONSE) $(ALL_OBJS) - cd $(BUILD_DIR) && LM_LICENSE_FILE=$(BACK_REL)/$(LM_LICENSE_FILE) $(WINE) $(MWLD) $(MWLDFLAGS) $(LIBS) -o $(BACK_REL)/$(NEF) $(LCF:$(BUILD_DIR)/%=%) @$(RESPONSE:$(BUILD_DIR)/%=%) $(CRT0_OBJ) + cd $(BUILD_DIR) && LM_LICENSE_FILE=$(BACK_REL)/$(LM_LICENSE_FILE) $(MWLD) $(MWLDFLAGS) $(LIBS) -o $(BACK_REL)/$(NEF) $(LCF:$(BUILD_DIR)/%=%) @$(RESPONSE:$(BUILD_DIR)/%=%) $(CRT0_OBJ) .INTERMEDIATE: $(BUILD_DIR)/obj.list diff --git a/lib/syscall/Makefile b/lib/syscall/Makefile index 2d1a0dd8..bbe64ccf 100644 --- a/lib/syscall/Makefile +++ b/lib/syscall/Makefile @@ -20,7 +20,7 @@ all: $(LIB) ASM_SRCS := asm/_secure_$(GAME_CODE).s $(LIB): $(ALL_OBJS) - cd $(BUILD_DIR) && LM_LICENSE_FILE=$(BACK_REL)/$(LM_LICENSE_FILE) $(WINE) $(MWLD) $(MWLDFLAGS) -o $(BACK_REL)/$(LIB) $(ALL_OBJS:$(BUILD_DIR)/%=%) + cd $(BUILD_DIR) && LM_LICENSE_FILE=$(BACK_REL)/$(LM_LICENSE_FILE) $(MWLD) $(MWLDFLAGS) -o $(BACK_REL)/$(LIB) $(ALL_OBJS:$(BUILD_DIR)/%=%) install: all $(shell mkdir -p $(INSTALL_LIBDIR)) diff --git a/main.lsf b/main.lsf index 8dd27efe..cd35d5fd 100644 --- a/main.lsf +++ b/main.lsf @@ -445,7 +445,7 @@ Static main Object lib/NitroSDK/asm/os_valarm.o Object lib/NitroSDK/src/os/os_system.o object lib/NitroSDK/asm/os_reset.o - object lib/NitroSDK/src/os/os_ownerinfo.o + object lib/NitroSDK/src/os/os_ownerInfo.o Object lib/NitroSDK/src/os/os_vramExclusive.o Object lib/NitroSDK/src/os/os_entropy.o Object lib/NitroSDK/src/os/os_terminate_proc.o diff --git a/platform.mk b/platform.mk index 5493e631..152ca331 100644 --- a/platform.mk +++ b/platform.mk @@ -44,3 +44,34 @@ ifeq ($(NOWINE),1) else WINPATH := winepath endif + +# Win32 runner selection, using wibo when USE_WIBO=1 and regular wine otherwise. +# +# make install_wibo # download wibo in tools/wibo/ +# make USE_WIBO=1 # build +# +# WIBO overrides which binary is used; it defaults to tools/wibo/* when present and otherwise to `wibo` on PATH. +# +# Nitro SDK tools are run using NITROWINE. It can be set separately like so: +# +# make USE_WIBO=1 NITROWINE=wine +# +# if you find that WIBO doesn't work as well with those tools as compared to the Metrowerks compilers. + +USE_WIBO ?= 0 + +ifneq ($(USE_WIBO),0) + TOOLS_WIBO := $(TOOLSDIR)/wibo/wibo + WIBO ?= $(if $(wildcard $(TOOLS_WIBO)),$(TOOLS_WIBO),wibo) + # Make the path absolute as long as it's not just "wibo" (from PATH) + WIBO_CMD := $(if $(findstring /,$(WIBO)),$(abspath $(WIBO)),$(WIBO)) + WINE := $(WIBO_CMD) + WINPATH := $(WIBO_CMD) path # use `wibo path` under wibo instead of winepath +endif + +NITROWINE ?= $(WINE) + +# USE_METROSKREW overrides WINE for the Metrowerks compilers only, +# skipping wine entirely, using the metroskrew native re-link. + +USE_METROSKREW ?= 0