# Makefile for the bootstrap compiler. # # Copyright © 2021-2025 Samuel Lidén Borell # # SPDX-License-Identifier: EUPL-1.2+ srcdir ?= . builddir ?= . VPATH ?= $(srcdir) MKDIR ?= mkdir MKDIR_P ?= $(MKDIR) -p RM ?= rm RM_F ?= $(RM) -f HOST_CC ?= $(CC) CFLAGS ?= -g HOST_CFLAGS ?= $(CFLAGS) HOST_LDFLAGS ?= $(LDFLAGS) BASE_WARNINGS = -Wall -Wextra -pedantic \ -Walloca \ -Wbad-function-cast \ -Wcast-align \ -Wconversion \ -Wdate-time \ -Wmissing-declarations \ -Wmissing-prototypes \ -Wmissing-noreturn \ -Wnested-externs \ -Wnull-dereference \ -Wold-style-definition \ -Wshadow \ -Wshift-negative-value \ -Wshift-overflow \ -Wstrict-aliasing \ -Wstrict-overflow=5 \ -Wstrict-prototypes \ -Wswitch-enum \ -Wundef \ -Wunused \ -Wvla \ -Wwrite-strings WARNINGS += $(BASE_WARNINGS) BASELINE_CFLAGS = -std=c89 $(WARNINGS) OBJECTS = \ $(builddir)/ast.o \ $(builddir)/main.o \ $(builddir)/parsedecl.o \ $(builddir)/parseexpr.o \ $(builddir)/parsestmt.o \ $(builddir)/out.o \ $(builddir)/outcommon.o \ $(builddir)/outdecl.o \ $(builddir)/outexpr.o \ $(builddir)/outstmt.o \ $(builddir)/tree.o \ $(builddir)/token.o \ $(builddir)/util.o C_SOURCES = \ $(srcdir)/ast.c \ $(srcdir)/main.c \ $(srcdir)/parsedecl.c \ $(srcdir)/parseexpr.c \ $(srcdir)/parsestmt.c \ $(srcdir)/out.c \ $(srcdir)/outcommon.c \ $(srcdir)/outdecl.c \ $(srcdir)/outexpr.c \ $(srcdir)/outstmt.c \ $(srcdir)/tree.c \ $(srcdir)/token.c \ $(srcdir)/util.c C_HEADERS = \ $(srcdir)/out.h \ $(srcdir)/compiler.h \ $(srcdir)/token.h # TODO should use separate compilation for these too # (but should it use HOST_CC or not? should it be possible to override?) STAGE2_C_SOURCES = \ $(srcdir)/rtl/fail.c \ $(builddir)/stage2.out.c STAGE2_INCLUDE = \ -I$(srcdir)/rtlincl # perhaps it could pass multiple paths here, to include the backend library # (or, in the future, whatever vendored libraries that the compiler needs) STAGE1_ARGS = $(builddir)/stage2.out.c $(srcdir)/../compiler COMPILER_SOURCES = \ $(srcdir)/../compiler/main.slul all: $(builddir)/stage2 $(OBJECTS): $(srcdir)/compiler.h parsedecl.o parseexpr.o parsestmt.o token.o: $(srcdir)/token.h .SUFFIXES: .c .o .c.o: $(HOST_CC) $(HOST_CFLAGS) $(BASELINE_CFLAGS) -c $< -o $@ $(builddir)/stage1: $(OBJECTS) $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(OBJECTS) -o $@ $(builddir)/stage1-boundschecked: $(C_SOURCES) $(C_HEADERS) tcc -b -bt24 $(C_SOURCES) -o $@ $(builddir)/stage2.out.c: $(builddir)/stage1 $(COMPILER_SOURCES) $(builddir)/stage1 $(STAGE1_ARGS) $(builddir)/stage2: $(STAGE2_C_SOURCES) $(CC) $(CFLAGS) $(LDFLAGS) $(CC_FLAGS) \ $(STAGE2_INCLUDE) \ $(STAGE2_C_SOURCES) \ -o $(builddir)/stage2 .PHONY: all check check-all check-valgrind check-boundschecked clean outdirs check: $(builddir)/stage1 $(builddir)/stage1 $(STAGE1_ARGS) check-all: check check-valgrind check-boundschecked clang-analyze check-valgrind: $(builddir)/stage1 valgrind --leak-check=yes -q $(builddir)/stage1 $(STAGE1_ARGS) check-boundschecked: $(builddir)/stage1-boundschecked TCC_BOUNDS_WARN_POINTER_ADD=1 $(builddir)/stage1-boundschecked $(STAGE1_ARGS) clang-analyze: clang --analyze $(C_SOURCES) # Gives a lot of warnings (possibly false positives) and output gets mixed # up (unless a single file is processed). So not included in check-all. gcc-analyzer: gcc -fanalyzer $(C_SOURCES) clean: -$(RM_F) \ $(builddir)/stage1 \ $(builddir)/stage1-boundschecked \ $(builddir)/stage2.out.c \ $(builddir)/stage2 \ $(OBJECTS) outdirs: $(MKDIR_P) $(builddir)