Skip to content

Refine the build system #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand All @@ -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"
Expand Down Expand Up @@ -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 $@
Expand Down
30 changes: 9 additions & 21 deletions mk/arm.mk
Original file line number Diff line number Diff line change
@@ -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$\
"
28 changes: 26 additions & 2 deletions mk/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ else
PRINTF = env printf
endif

HOST_ARCH = $(shell arch 2>/dev/null)

# Control the build verbosity
ifeq ("$(VERBOSE)","1")
Q :=
Expand All @@ -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
27 changes: 10 additions & 17 deletions mk/riscv.mk
Original file line number Diff line number Diff line change
@@ -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$\
"