joeylib2/make/hosted.mk
2026-10-13 14:01:46 -05:00

140 lines
6.1 KiB
Makefile

# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# The hosted ports' shared build rules (src/hosted): JoeyLib's library for
# the hosted core and one backend, libxmp-lite, and programRules, the rules
# for one program, which make/programs.mk instantiates for every program.
# Included by make/sdl3.mk (a native program), make/web.mk (the same
# SDL3 backend compiled to WebAssembly), make/psp.mk (the same again, for
# the PSP), make/win32.mk, make/win16.mk and make/be.mk (Haiku), after each
# has included common.mk and set:
# HOSTED_CC the compiler
# HOSTED_AR the archiver
# HOSTED_BACKEND the backend folder under src/hosted
# HOSTED_DEFINES the platform and backend macros
# HOSTED_SDK_CFLAGS the backend's library headers (the backend only)
# HOSTED_LINK what a program links after the library and libxmp-lite
# PROGRAM_EXT the program file's extension
# and, when the backend is C++ (src/hosted/<backend>/*.cpp, the Be API's),
# HOSTED_CXX its C++ compiler
# and may set HOSTED_PROGRAM_DEPS, files every program is rebuilt after (the
# web page's shell), and, when a program needs its DATA at link time (the web
# port packs it into the program), HOSTED_LINK_DATA: the link flags for one
# program's DATA folder, $(1) the program's id. When the program file is
# packed from what is linked (the PSP's EBOOT.PBP, from an ELF), the port
# sets HOSTED_LINK_OUT, the file one program is linked to, and HOSTED_PACK,
# the command that packs it into the program file ($(1) the id in both).
#
# The stage is the chunky generic one, as on the BLANK port: the core, every
# generic (the sprite interpreter stub among them -- no machine code is
# generated), the hosted core and the backend.
HOSTED_DIR := $(SRC_DIR)/hosted
BACKEND_DIR := $(HOSTED_DIR)/$(HOSTED_BACKEND)
# LIBXMP_STATIC: libxmp-lite is linked in, never a DLL (xmp.h marks its
# functions dllimport on Windows without it).
CFLAGS := $(COMMON_CFLAGS) $(HOSTED_DEFINES) -DLIBXMP_STATIC -I$(HOSTED_DIR) -I$(LIBXMP_DIR)/include -MMD -MP
# libxmp-lite (MIT, libxmp.org): the MOD player the hosted mixer runs, the
# same sources and flags as the DOS port's -- and its win32.c, libxmp's own
# snprintf for a C library without a safe one (Open Watcom's, the win16
# port's), which compiles to nothing for the others.
LIBXMP_SRC := $(wildcard $(LIBXMP_DIR)/src/*.c) $(wildcard $(LIBXMP_DIR)/src/loaders/*.c)
LIBXMP_OBJDIR := $(BUILD)/obj/libxmp-lite
LIBXMP_OBJS := $(patsubst $(LIBXMP_DIR)/src/%.c,$(LIBXMP_OBJDIR)/%.o,$(LIBXMP_SRC))
LIBXMP_AR := $(LIBDIR)/libxmplite.a
LIBXMP_CFLAGS := -DJOEY_LIBXMP_LITE -DLIBXMP_CORE_PLAYER -DHAVE_FNMATCH=0 -I$(LIBXMP_DIR)/include -I$(LIBXMP_DIR)/include/libxmp-lite -I$(LIBXMP_DIR)/src -Wno-error -w
HOSTED_C_SRCS := $(wildcard $(HOSTED_DIR)/*.c)
BACKEND_C_SRCS := $(wildcard $(BACKEND_DIR)/*.c)
BACKEND_CXX_SRCS := $(wildcard $(BACKEND_DIR)/*.cpp)
LIB_OBJS := \
$(patsubst $(SRC_CORE)/%.c,$(BUILD)/obj/core/%.o,$(CORE_C_SRCS)) \
$(patsubst $(SRC_DIR)/generic/%.c,$(BUILD)/obj/generic/%.o,$(GENERIC_C_SRCS) $(SRC_DIR)/generic/spriteEmitStub.c) \
$(patsubst $(HOSTED_DIR)/%.c,$(BUILD)/obj/hosted/%.o,$(HOSTED_C_SRCS)) \
$(patsubst $(BACKEND_DIR)/%.c,$(BUILD)/obj/backend/%.o,$(BACKEND_C_SRCS)) \
$(patsubst $(BACKEND_DIR)/%.cpp,$(BUILD)/obj/backend/%.o,$(BACKEND_CXX_SRCS))
LIB := $(LIBDIR)/libjoey.a
$(BUILD)/obj/core/%.o: $(SRC_CORE)/%.c
@mkdir -p $(dir $@)
$(HOSTED_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/generic/%.o: $(SRC_DIR)/generic/%.c
@mkdir -p $(dir $@)
$(HOSTED_CC) $(CFLAGS) -c $< -o $@
$(BUILD)/obj/hosted/%.o: $(HOSTED_DIR)/%.c
@mkdir -p $(dir $@)
$(HOSTED_CC) $(CFLAGS) -c $< -o $@
# Only the backend sees its library's headers.
$(BUILD)/obj/backend/%.o: $(BACKEND_DIR)/%.c
@mkdir -p $(dir $@)
$(HOSTED_CC) $(CFLAGS) $(HOSTED_SDK_CFLAGS) -c $< -o $@
$(BUILD)/obj/backend/%.o: $(BACKEND_DIR)/%.cpp
@mkdir -p $(dir $@)
$(HOSTED_CXX) $(CFLAGS) $(HOSTED_SDK_CFLAGS) -c $< -o $@
# Archived from scratch, so the members follow LIB_OBJS rather than the order
# earlier builds added them in.
$(LIB): $(LIB_OBJS)
@mkdir -p $(dir $@)
rm -f $@
$(HOSTED_AR) rcs $@ $^
$(LIBXMP_OBJDIR)/%.o: $(LIBXMP_DIR)/src/%.c
@mkdir -p $(dir $@)
$(HOSTED_CC) $(CFLAGS) $(LIBXMP_CFLAGS) -c $< -o $@
$(LIBXMP_AR): $(LIBXMP_OBJS)
@mkdir -p $(dir $@)
rm -f $@
$(HOSTED_AR) rcs $@ $^
# Pull in per-object header-dependency files generated by -MMD/-MP.
-include $(LIB_OBJS:.o=.d)
# ---- programs -----------------------------------------------------------------
PROGRAM_FOLDERS := yes
# The file one program, $(1) its id, is linked to: the program file itself
# unless the port packs it afterwards.
hostedLinkOut = $(or $(call HOSTED_LINK_OUT,$(1)),$(call programBin,$(1)))
# One program, $(1) its id: compiled and linked in one step with the library,
# libxmp-lite and the backend's libraries (and the maths library the mixer's
# tables use), its DATA too where the port packs it in, then packed where the
# port packs it. -MMD leaves the dependency file beside what is linked, for
# header edits.
define programRules
$(call programBin,$(1)): $(call programVar,$(1),SRCS) $(LIB) $(LIBXMP_AR) $(HOSTED_PROGRAM_DEPS) $(if $(HOSTED_LINK_DATA),$(call programVar,$(1),DATA))
@mkdir -p $$(dir $$@) $(dir $(call hostedLinkOut,$(1)))
$(HOSTED_CC) $(CFLAGS) $(call programVar,$(1),CFLAGS) $(call programVar,$(1),SRCS) $(LIB) $(LIBXMP_AR) $(HOSTED_LINK) $(if $(HOSTED_LINK_DATA),$(call HOSTED_LINK_DATA,$(1))) -lm -o $(call hostedLinkOut,$(1)) $(call programVar,$(1),LDFLAGS)
$(call HOSTED_PACK,$(1))
-include $(basename $(call hostedLinkOut,$(1))).d
endef
# ---- JoeyLib's own build: its examples ------------------------------------------
ifndef JOEY_PROJECT
include $(REPO_DIR)/make/examples.mk
include $(REPO_DIR)/make/programs.mk
.DEFAULT_GOAL := all
.PHONY: all $(PLATFORM) clean-$(PLATFORM) clean
all $(PLATFORM): $(LIB) $(LIBXMP_AR) programs
clean-$(PLATFORM):
rm -rf $(BUILD)
# `clean` as an alias for `clean-<port>`, so a bare
# `make -f make/<port>.mk clean` cleans instead of failing.
clean: clean-$(PLATFORM)
endif