# ---------------------------------------------------------------------- # host-tests.mk — общие правила модульных тестов, исполняемых под ucsim_z80. # # Сама обвязка (crt0_ucsim.s, tcheck.*, run_ucsim.py) лежит в testkit/ и ни # к какому подпроекту не привязана: тестировать так можно и libc, и логику # приложений — всё, что на plain C и не трогает железо. # # Подключается из каталога с наборами t_*.c: # # TESTKIT := $(abspath ../../../../testkit) # ENGINE_DIR := $(abspath ..) # где лежат модули под тестом # OBJS_geom := build/eng_pop_geom.rel # что доложить в этот набор # include $(TESTKIT)/host-tests.mk # # Набор t_<имя>.c подхватывается wildcard'ом, регистрировать не надо. # ---------------------------------------------------------------------- ifndef TESTKIT $(error перед include надо задать TESTKIT — путь к каталогу testkit/) endif PROJ_ROOT ?= $(abspath $(TESTKIT)/..) SDCC := $(PROJ_ROOT)/third_party/sdcc/bin/sdcc SDASZ80 := $(PROJ_ROOT)/third_party/sdcc/bin/sdasz80 UCSIM := $(PROJ_ROOT)/third_party/sdcc/bin/ucsim_z80 RUNNER := $(TESTKIT)/run_ucsim.py BUILD := build # --code-loc: стартовый код занимает 13 байт по 0x0000, код с 0x0200. # --data-loc 0x8000: данные заведомо выше кода. CFLAGS := -mz80 --no-std-crt0 --std-c99 --opt-code-size -I$(TESTKIT) \ $(if $(ENGINE_DIR),-I$(ENGINE_DIR)) LDFLAGS := -mz80 --no-std-crt0 --code-loc 0x0200 --data-loc 0x8000 SUITES := $(patsubst t_%.c,%,$(notdir $(wildcard t_*.c))) COMMON := $(BUILD)/crt0_ucsim.rel $(BUILD)/tcheck.rel .PHONY: all clean $(addprefix t_,$(SUITES)) # Иначе make считает .rel/.ihx промежуточными и удаляет их после прогона — # следующий `make` пересобирал бы всё заново. .SECONDARY: # OBJS_<набор> подставляется в правило по имени цели — нужен второй проход # раскрытия, иначе модуль не попадёт в зависимости и не соберётся. .SECONDEXPANSION: # Ярлык каталога в отчёте — с родителем: «tests-host» само по себе # неоднозначно, когда таких каталогов несколько. LABEL := $(notdir $(patsubst %/,%,$(dir $(CURDIR))))/$(notdir $(CURDIR)) all: $(addprefix run-,$(SUITES)) @echo "$(LABEL): все наборы прошли ($(words $(SUITES)))" # Прогон одного набора. Раннер сам разбирает tc_result и возвращает код. run-%: $(BUILD)/%.ihx @python3 $(RUNNER) $(UCSIM) $(BUILD)/$*.ihx $(BUILD)/$*.noi # Удобный псевдоним: `make t_geom` вместо `make run-geom`. t_%: run-% ; $(BUILD)/%.ihx: $(BUILD)/%.rel $(COMMON) $$(OBJS_$$*) @$(SDCC) $(LDFLAGS) -o $@ $(COMMON) $(BUILD)/$*.rel $(OBJS_$*) $(BUILD)/%.rel: t_%.c $(TESTKIT)/tcheck.h | $(BUILD) @$(SDCC) $(CFLAGS) -c -o $@ $< # Модули под тестом собираются ТЕМ ЖЕ компилятором и с той же семантикой, # что и продукт, — включая модули с inline-asm, которые хостовой сборкой # не проверить в принципе. $(BUILD)/eng_%.rel: $(ENGINE_DIR)/%.c | $(BUILD) @$(SDCC) $(CFLAGS) -c -o $@ $< $(BUILD)/tcheck.rel: $(TESTKIT)/tcheck.c $(TESTKIT)/tcheck.h | $(BUILD) @$(SDCC) $(CFLAGS) -c -o $@ $< $(BUILD)/crt0_ucsim.rel: $(TESTKIT)/crt0_ucsim.s | $(BUILD) @$(SDASZ80) -plosgff $@ $< $(BUILD): @mkdir -p $(BUILD) clean: @rm -rf $(BUILD)