PROJ := EMPTY := SPACE := $(EMPTY) $(EMPTY) SLASH := / V := @ GCCPREFIX := riscv64-unknown-elf- ifndef QEMU QEMU := qemu-system-riscv64 endif # eliminate default suffix rules .SUFFIXES: .c .S .h # delete target files if there is an error (or make is interrupted) .DELETE_ON_ERROR: # define compiler and flags HOSTCC := gcc HOSTCFLAGS := -Wall -O2 GDB := $(GCCPREFIX)gdb CC := $(GCCPREFIX)gcc CFLAGS := -mcmodel=medany -std=gnu99 -Wno-unused -Werror -g CFLAGS += -fno-builtin -Wall -O2 -nostdinc $(DEFS) CFLAGS += -fno-stack-protector -ffunction-sections -fdata-sections CTYPE := c S LD := $(GCCPREFIX)ld LDFLAGS := -m elf64lriscv LDFLAGS += -nostdlib --gc-sections OBJCOPY := $(GCCPREFIX)objcopy OBJDUMP := $(GCCPREFIX)objdump COPY := cp MKDIR := mkdir -p MV := mv RM := rm -f AWK := awk SED := sed SH := sh TR := tr TOUCH := touch -c FIND = find CLANG_FORMAT = clang-format AVOCADO = avocado TEST_RESULTS_DIR = test_results AVOCADO_RUN_EXTRA_PARAMS = AVOCADO_RUN_PARAMS = --job-results-dir $(TEST_RESULTS_DIR) \ $(AVOCADO_RUN_EXTRA_PARAMS) TEST_REFERENCES = tests OBJDIR := obj BINDIR := bin ALLOBJS := ALLDEPS := TARGETS := # include some predefined function include tools/function.mk listf_cc = $(call listf,$(1),$(CTYPE)) # for cc add_files_cc = $(call add_files,$(1),$(CC),$(CFLAGS) $(3),$(2),$(4)) create_target_cc = $(call create_target,$(1),$(2),$(3),$(CC),$(CFLAGS)) # for hostcc add_files_host = $(call add_files,$(1),$(HOSTCC),$(HOSTCFLAGS),$(2),$(3)) create_target_host = $(call create_target,$(1),$(2),$(3),$(HOSTCC),$(HOSTCFLAGS)) cgtype = $(patsubst %.$(2),%.$(3),$(1)) objfile = $(call toobj,$(1)) asmfile = $(call cgtype,$(call toobj,$(1)),o,asm) outfile = $(call cgtype,$(call toobj,$(1)),o,out) symfile = $(call cgtype,$(call toobj,$(1)),o,sym) # for match pattern match = $(shell echo $(2) | $(AWK) '{for(i=1;i<=NF;i++){if(match("$(1)","^"$$(i)"$$")){exit 1;}}}'; echo $$?) # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # include kernel/user INCLUDE += libs/ CFLAGS += $(addprefix -I,$(INCLUDE)) LIBDIR += libs $(call add_files_cc,$(call listf_cc,$(LIBDIR)),libs,) # ------------------------------------------------------------------- # kernel KINCLUDE += kern/debug/ \ kern/driver/ \ kern/trap/ \ kern/mm/ \ kern/arch/ KSRCDIR += kern/init \ kern/libs \ kern/debug \ kern/driver \ kern/trap \ kern/mm KCFLAGS += $(addprefix -I,$(KINCLUDE)) $(call add_files_cc,$(call listf_cc,$(KSRCDIR)),kernel,$(KCFLAGS)) KOBJS = $(call read_packet,kernel libs) # create kernel target kernel = $(call totarget,kernel) $(kernel): tools/kernel.ld $(kernel): $(KOBJS) $(V)$(LD) $(LDFLAGS) -T tools/kernel.ld -o $@ $(KOBJS) $(V)$(OBJDUMP) -S $@ > $(call asmfile,kernel) $(V)$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,kernel) $(call create_target,kernel) # ------------------------------------------------------------------- # create ucore.bin UCOREIMG := $(call totarget,ucore.bin) $(UCOREIMG): $(kernel) $(OBJCOPY) $(kernel) --strip-all -O binary $@ $(call create_target,ucore.bin) # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $(call finish_all) IGNORE_ALLDEPS = clean \ dist-clean \ grade \ touch \ print-.+ \ handin ifeq ($(call match,$(MAKECMDGOALS),$(IGNORE_ALLDEPS)),0) -include $(ALLDEPS) endif # files for grade script TARGETS: $(TARGETS) .DEFAULT_GOAL := TARGETS QEMU_OPTS := -machine virt \ -nographic \ -bios default \ -kernel $(UCOREIMG) .PHONY: qemu qemu: $(UCOREIMG) $(SWAPIMG) $(SFSIMG) $(V)$(QEMU) $(QEMU_OPTS) .PHONY: qemu-gdb qemu-gdb: $(UCOREIMG) $(SWAPIMG) $(SFSIMG) $(V)$(QEMU) $(QEMU_OPTS) -S -gdb tcp::3117 GRADE_GDB_IN := .gdb.in GRADE_QEMU_OUT := .qemu.out .PHONY: clean clean: $(V)$(RM) $(GRADE_GDB_IN) $(GRADE_QEMU_OUT) cscope* tags -$(RM) -r $(OBJDIR) $(BINDIR) FIND_FORMAT_CMD = $(FIND) $(THIS_DIR) -type f -name "*.[ch]" \ -execdir $(CLANG_FORMAT) $(CLANG_FORMAT_PARAMS) "{}" "+" .PHONY: format_check format_check: CLANG_FORMAT_PARAMS=-Werror --dry-run format_check: $(FIND_FORMAT_CMD) .PHONY: format format: CLANG_FORMAT_PARAMS=-i format: $(FIND_FORMAT_CMD) .PHONY: check check: $(UCOREIMG) $(SWAPIMG) $(SFSIMG) $(AVOCADO) run $(AVOCADO_RUN_PARAMS) $(TEST_REFERENCES)