|
| 1 | +# Nuke built-in rules and variables. |
| 2 | +override MAKEFLAGS += -rR |
| 3 | + |
| 4 | +CC = /usr/local/cross-compiler/bin/x86_64-elf-gcc |
| 5 | +LD = /usr/local/cross-compiler/bin/x86_64-elf-ld |
| 6 | +# This is the name that our final kernel executable will have. |
| 7 | +# Change as needed. |
| 8 | +override KERNEL := kernel.elf |
| 9 | + |
| 10 | +# Convenience macro to reliably declare user overridable variables. |
| 11 | +define DEFAULT_VAR = |
| 12 | + ifeq ($(origin $1),default) |
| 13 | + override $(1) := $(2) |
| 14 | + endif |
| 15 | + ifeq ($(origin $1),undefined) |
| 16 | + override $(1) := $(2) |
| 17 | + endif |
| 18 | +endef |
| 19 | + |
| 20 | +# It is highly recommended to use a custom built cross toolchain to build a kernel. |
| 21 | +# We are only using "cc" as a placeholder here. It may work by using |
| 22 | +# the host system's toolchain, but this is not guaranteed. |
| 23 | +$(eval $(call $(CC))) |
| 24 | + |
| 25 | +# Same thing for "ld" (the linker). |
| 26 | +$(eval $(call $(LD))) |
| 27 | + |
| 28 | +# User controllable C flags. |
| 29 | +$(eval $(call $(CC),CFLAGS,-g -O2 -pipe -Wall -Wextra)) |
| 30 | + |
| 31 | +# User controllable C preprocessor flags. We set none by default. |
| 32 | +$(eval $(call $(CC),CPPFLAGS,)) |
| 33 | + |
| 34 | +# User controllable nasm flags. |
| 35 | +$(eval $(call DEFAULT_VAR,NASMFLAGS,-F dwarf -g)) |
| 36 | + |
| 37 | +# User controllable linker flags. We set none by default. |
| 38 | +$(eval $(call $(LD),LDFLAGS,)) |
| 39 | + |
| 40 | +# Internal C flags that should not be changed by the user. |
| 41 | +override CFLAGS += \ |
| 42 | + -std=gnu11 \ |
| 43 | + -ffreestanding \ |
| 44 | + -fno-stack-protector \ |
| 45 | + -fno-stack-check \ |
| 46 | + -fno-lto \ |
| 47 | + -fno-pie \ |
| 48 | + -fno-pic \ |
| 49 | + -m64 \ |
| 50 | + -march=x86-64 \ |
| 51 | + -mabi=sysv \ |
| 52 | + -mno-80387 \ |
| 53 | + -mno-mmx \ |
| 54 | + -mno-sse \ |
| 55 | + -mno-sse2 \ |
| 56 | + -mno-red-zone \ |
| 57 | + -mcmodel=kernel |
| 58 | + |
| 59 | +# Internal C preprocessor flags that should not be changed by the user. |
| 60 | +override CPPFLAGS := \ |
| 61 | + -I. \ |
| 62 | + $(CPPFLAGS) \ |
| 63 | + -MMD \ |
| 64 | + -MP |
| 65 | + |
| 66 | +# Internal linker flags that should not be changed by the user. |
| 67 | +override LDFLAGS += \ |
| 68 | + -nostdlib \ |
| 69 | + -static \ |
| 70 | + \ |
| 71 | + -z max-page-size=0x1000 \ |
| 72 | + -T linker.ld |
| 73 | + |
| 74 | +# Check if the linker supports -no-pie and enable it if it does. |
| 75 | + |
| 76 | +# Internal nasm flags that should not be changed by the user. |
| 77 | +override NASMFLAGS += \ |
| 78 | + -f elf64 |
| 79 | + |
| 80 | +# Use "find" to glob all *.c, *.S, and *.asm files in the tree and obtain the |
| 81 | +# object and header dependency file names. |
| 82 | +override CFILES := $(shell find -L . -type f -name '*.c') |
| 83 | +override ASFILES := $(shell find -L . -type f -name '*.S') |
| 84 | +override NASMFILES := $(shell find -L . -type f -name '*.asm') |
| 85 | +override OBJ := $(CFILES:.c=.o) $(ASFILES:.S=.o) $(NASMFILES:.asm=.o) |
| 86 | +override HEADER_DEPS := $(CFILES:.c=.d) $(ASFILES:.S=.d) |
| 87 | + |
| 88 | +# Default target. |
| 89 | +.PHONY: all |
| 90 | +all: $(KERNEL) |
| 91 | + |
| 92 | +limine.h: |
| 93 | + curl -Lo $@ https://github.com/limine-bootloader/limine/raw/trunk/limine.h |
| 94 | + |
| 95 | +# Link rules for the final kernel executable. |
| 96 | +$(KERNEL): $(OBJ) |
| 97 | + sudo $(LD) $(OBJ) $(LDFLAGS) -o $@ |
| 98 | + |
| 99 | +# Include header dependencies. |
| 100 | +-include $(HEADER_DEPS) |
| 101 | + |
| 102 | +# Compilation rules for *.c files. |
| 103 | +%.o: %.c limine.h |
| 104 | + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ |
| 105 | + |
| 106 | +# Compilation rules for *.S files. |
| 107 | +%.o: %.S limine.h |
| 108 | + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ |
| 109 | + |
| 110 | +# Compilation rules for *.asm (nasm) files. |
| 111 | +%.o: %.asm |
| 112 | + nasm $(NASMFLAGS) $< -o $@ |
| 113 | + |
| 114 | +.PHONY: debug |
| 115 | +debug: $(KERNEL) |
| 116 | + |
| 117 | +%.o: %.c limine.h |
| 118 | + $(CC) $(CFLAGS) -g $(INTERNALCFLAGS) -c $< -o $@ |
| 119 | + |
| 120 | +# Remove object files and the final executable. |
| 121 | +.PHONY: clean |
| 122 | +clean: |
| 123 | + rm -rf $(KERNEL) $(OBJ) $(HEADER_DEPS) |
| 124 | + |
| 125 | +.PHONY: distclean |
| 126 | +distclean: clean |
| 127 | + rm -f limine.h |
0 commit comments