diff --git a/Makefile b/Makefile index 63b9b985..8624fba7 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,6 @@ CFLAGS := -O -g \ BUILD_SESSION := .session.mk -include mk/common.mk -include mk/arm.mk -include mk/riscv.mk -include $(BUILD_SESSION) STAGE0 := shecc @@ -28,6 +25,7 @@ STAGE2 := shecc-stage2.elf OUT ?= out ARCHS = arm riscv ARCH ?= $(firstword $(ARCHS)) +HOST_ARCH = $(shell arch 2>/dev/null) SRCDIR := $(shell find src -type d) LIBDIR := $(shell find lib -type d) @@ -43,17 +41,15 @@ all: config bootstrap ifeq (,$(filter $(ARCH),$(ARCHS))) $(error Support ARM and RISC-V only. Select the target with "ARCH=arm" or "ARCH=riscv") endif - -ifneq ("$(wildcard $(PWD)/config)","") -TARGET_EXEC := $($(shell head -1 config | sed 's/.*: \([^ ]*\).*/\1/')_EXEC) -endif -export TARGET_EXEC +include mk/$(ARCH).mk +include mk/common.mk config: $(Q)ln -s $(PWD)/$(SRCDIR)/$(ARCH)-codegen.c $(SRCDIR)/codegen.c - $(call $(ARCH)-specific-defs) > $@ + $(Q)$(PRINTF) $(ARCH_DEFS) > $@ $(VECHO) "Target machine code switch to %s\n" $(ARCH) $(Q)$(MAKE) $(BUILD_SESSION) --silent + $(Q)$(CONFIG_CHECK_CMD) $(OUT)/tests/%.elf: tests/%.c $(OUT)/$(STAGE0) $(VECHO) " SHECC\t$@\n" @@ -109,6 +105,7 @@ $(OUT)/$(STAGE0): $(OUT)/libc.inc $(OBJS) $(Q)$(CC) $(OBJS) -o $@ $(OUT)/$(STAGE1): $(OUT)/$(STAGE0) + $(Q)$(STAGE1_CHECK_CMD) $(VECHO) " SHECC\t$@\n" $(Q)$(OUT)/$(STAGE0) --dump-ir -o $@ $(SRCDIR)/main.c > $(OUT)/shecc-stage1.log $(Q)chmod a+x $@ diff --git a/mk/arm.mk b/mk/arm.mk index abd1439a..57bbebd4 100644 --- a/mk/arm.mk +++ b/mk/arm.mk @@ -1,21 +1,9 @@ -ifeq ($(HOST_ARCH),armv7l) # detect ARMv7-A only and assume Linux-compatible - ARM_EXEC := -else - ARM_EXEC = qemu-arm - ARM_EXEC := $(shell which $(ARM_EXEC)) - ifndef ARM_EXEC - $(warning "no qemu-arm found. Please check package installation") - ARM_EXEC = echo WARN: unable to run - endif -endif - -export ARM_EXEC - -arm-specific-defs = \ - $(Q)$(PRINTF) \ - "/* target: ARM */\n$\ - \#pragma once\n$\ - \#define ARCH_PREDEFINED \"__arm__\" /* defined by GNU C and RealView */\n$\ - \#define ELF_MACHINE 0x28 /* up to ARMv7/Aarch32 */\n$\ - \#define ELF_FLAGS 0x5000200\n$\ - " +ARCH_NAME = armv7l +ARCH_RUNNER = qemu-arm +ARCH_DEFS = \ + "/* target: ARM */\n$\ + \#pragma once\n$\ + \#define ARCH_PREDEFINED \"__arm__\" /* defined by GNU C and RealView */\n$\ + \#define ELF_MACHINE 0x28 /* up to ARMv7/Aarch32 */\n$\ + \#define ELF_FLAGS 0x5000200\n$\ + " diff --git a/mk/common.mk b/mk/common.mk index e54382bc..95380cba 100644 --- a/mk/common.mk +++ b/mk/common.mk @@ -5,8 +5,6 @@ else PRINTF = env printf endif -HOST_ARCH = $(shell arch 2>/dev/null) - # Control the build verbosity ifeq ("$(VERBOSE)","1") Q := @@ -23,3 +21,29 @@ PASS_COLOR = \e[32;01m NO_COLOR = \e[0m pass = $(PRINTF) "$(PASS_COLOR)$1 Passed$(NO_COLOR)\n" + +# Check the prerequisites +PREREQ_LIST := dot jq +TARGET_EXEC ?= +ifneq ($(HOST_ARCH),$(ARCH_NAME)) + # Add qemu to the list if the host and target architectures differ + PREREQ_LIST += $(ARCH_RUNNER) + ifeq ($(filter $(ARCH_RUNNER),$(notdir $(shell which $(ARCH_RUNNER)))),) + STAGE1_WARN_MSG := "Warning: failed to build the stage 1 and $\ + stage 2 compilers due to missing $(ARCH_RUNNER)\n" + STAGE1_CHECK_CMD := $(VECHO) $(STAGE1_WARN_MSG) && exit 1 + endif + + # Generate the path to the architecture-specific qemu + TARGET_EXEC = $(shell which $(ARCH_RUNNER)) +endif +export TARGET_EXEC + +PREREQ_EXEC := $(shell which $(PREREQ_LIST)) +PREREQ_MISSING := $(filter-out $(notdir $(PREREQ_EXEC)),$(PREREQ_LIST)) + +ifdef PREREQ_MISSING + CONFIG_WARN_MSG := "Warning: missing packages: $(PREREQ_MISSING)\n$\ + Warning: Please check package installation\n" + CONFIG_CHECK_CMD := $(VECHO) $(CONFIG_WARN_MSG) +endif diff --git a/mk/riscv.mk b/mk/riscv.mk index ee8f25fd..89e33341 100644 --- a/mk/riscv.mk +++ b/mk/riscv.mk @@ -1,17 +1,10 @@ -RISCV_EXEC = qemu-riscv32 -RISCV_EXEC := $(shell which $(RISCV_EXEC)) -ifndef RISCV_EXEC -$(warning "no qemu-riscv32 found. Please check package installation") -RISCV_EXEC = echo WARN: unable to run -endif - -export RISCV_EXEC - -riscv-specific-defs = \ - $(Q)$(PRINTF) \ - "/* target: RISCV */\n$\ - \#pragma once\n$\ - \#define ARCH_PREDEFINED \"__riscv\" /* Older versions of the GCC toolchain defined __riscv__ */\n$\ - \#define ELF_MACHINE 0xf3\n$\ - \#define ELF_FLAGS 0\n$\ - " +# Enforce the use qemu of by setting the ARCH_NAME variable to empty +ARCH_NAME = +ARCH_RUNNER = qemu-riscv32 +ARCH_DEFS = \ + "/* target: RISCV */\n$\ + \#pragma once\n$\ + \#define ARCH_PREDEFINED \"__riscv\" /* Older versions of the GCC toolchain defined __riscv__ */\n$\ + \#define ELF_MACHINE 0xf3\n$\ + \#define ELF_FLAGS 0\n$\ + "