BIN_DIR=bin BUILD_DIR=build SRC_DIR=src KERNEL := sen.elf # It is highly recommended to use a custom built cross toolchain to build a kernel. # We are only using "cc" as a placeholder here. It may work by using # the host system's toolchain, but this is not guaranteed. ifeq ($(origin CC), default) CC := cc endif # Likewise, "ld" here is just a placeholder and your mileage may vary if using the # host's "ld". ifeq ($(origin LD), default) LD := ld endif CFLAGS ?= -O2 -g -Wall -Wextra -pipe -fno-pie -no-pie LDFLAGS ?= # Internal C flags that should not be changed by the user. INTERNALCFLAGS := \ -I$(SRC_DIR) \ -std=gnu11 \ -ffreestanding \ -fno-stack-protector \ -no-pie \ -mabi=sysv \ -mno-80387 \ -mno-mmx \ -mno-3dnow \ -mno-sse \ -mno-sse2 \ -mno-red-zone \ -mcmodel=kernel \ -MMD # Internal linker flags that should not be changed by the user. INTERNALLDFLAGS := \ -T$(SRC_DIR)/linker.ld \ -nostdlib \ -zmax-page-size=0x1000 \ -static rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) CFILES := $(shell find ./$(SRC_DIR) -type f -name '*.c') OBJ := $(subst $(SRC_DIR),$(BUILD_DIR),$(CFILES:.c=.o)) HEADER_DEPS := $(OBJ:.o=.d)) .PHONY: all all: $(KERNEL) $(KERNEL): $(OBJ) | $(BIN_DIR) $(LD) $(OBJ) $(LDFLAGS) $(INTERNALLDFLAGS) -o $(BIN_DIR)/$@ -include $(HEADER_DEPS) $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) @mkdir -p $(@D) $(CC) $(CFLAGS) $(INTERNALCFLAGS) -c $< -o $@ # create directories if they don't exist $(BIN_DIR): mkdir -p $@ $(BUILD_DIR): mkdir -p $@ # Remove object files and the final executable. .PHONY: clean clean: rm -rf $(BIN_DIR)/$(KERNEL) $(OBJ) $(HEADER_DEPS)