-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
103 lines (85 loc) · 2.82 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Directory names
src_dir := src
out_dir := out
# C compiler
CC := i386-elf-gcc
CFLAGS := -Wall -Wextra -O2 -ffreestanding -I"$(src_dir)/include" -fstack-protector-strong
LDFLAGS := -nostdlib -lgcc
# Targets that don't need dependency files (.d) (e.g. clean)
# This allows us to only include them when they're actually needed
# so we are not building unnecessary stuff
no-dep-targets = clean
# Helper macros
# Recursively create the directory for the current target
# Usage: $(mkdirp)
mkdirp = @dir=$(dir $@); [ -d "$$dir" ] || mkdir -p "$$dir"
# Build the complete OS image by default
.PHONY: all
all: $(out_dir)/Image
.PHONY: iso
iso: $(out_dir)/Image.iso
# That's easy, we just need to delete the output directory
.PHONY: clean
clean:
rm -rf $(out_dir)
# Run the image in qemu
.PHONY: run
run: $(out_dir)/Image
qemu-system-i386 -kernel $(out_dir)/Image
# Run the image in qemu
.PHONY: runiso
runiso: $(out_dir)/Image.iso
qemu-system-i386 -drive format=raw,file=$(out_dir)/Image.iso
$(out_dir)/Image.iso: $(out_dir)/Image $(src_dir)/grub.cfg
$(mkdirp)
mkdir -p $(out_dir)/iso/boot/grub/
cp $(out_dir)/Image $(out_dir)/iso/boot/
cp $(src_dir)/grub.cfg $(out_dir)/iso/boot/grub/
grub-mkrescue -o $@ $(out_dir)/iso
# These directories will be searched for a Makefile
MODULES := boot kernel lib drivers
# Set up variables for included Makefiles
libs :=
# Include sub-Makefiles
-include $(patsubst %, $(src_dir)/%/Makefile,$(MODULES))
# Prepend the output directory to all object file paths
objs := $(addprefix $(out_dir)/,$(objs))
# Build a .c file to an object
# Also generates a corresponding .d file for faster building
%.o: %.c
$(out_dir)/%.o: $(src_dir)/%.c $(out_dir)/%.d
$(mkdirp)
$(CC) -MT "$@" -MMD -MP -MF "$(out_dir)/$*.Td" $(CFLAGS) -o "$@" -c "$<"
mv -f "$(out_dir)/$*.Td" "$(out_dir)/$*.d"
# Build a .S file to an object
# Also generates a corresponding .d file for faster building
%.o: %.S
$(out_dir)/%.o: $(src_dir)/%.S $(out_dir)/%.d
$(mkdirp)
$(CC) -MT "$@" -MMD -MP -MF "$(out_dir)/$*.Td" $(CFLAGS) -o "$@" -c "$<"
mv -f "$(out_dir)/$*.Td" "$(out_dir)/$*.d"
# Link the final kernel image
$(out_dir)/Image: $(src_dir)/linker.ld $(objs)
$(mkdirp)
$(CC) $(CFLAGS) $(LDFLAGS) -T $(src_dir)/linker.ld -o $@ $(libs) $(objs)
#
$(out_dir)/%.d: ;
# Mark the dependency files as precious, so they won't get deleted when
# make is interrupted (we are using intermediary files (.Td))
.PRECIOUS: $(out_dir)/%.d
# Include .d files only if needed
# This is rather complicated as make does not have proper a
# proper logical or function
no-deps :=
# Include if no targets given
ifneq ($(MAKECMDGOALS),)
# Don't include if only no-dep targets are given
ifeq ($(filter-out $(no-dep-targets),$(MAKECMDGOALS)),)
no-deps := 1
endif
endif
# Only include if no-deps is not set
ifeq ($(no-deps),)
# For every .o file include a .d file
-include $(objs:.o,.d)
endif