summaryrefslogtreecommitdiff
path: root/makefile
blob: 6b2f69724af8518573275fbd38856b12d6683071 (plain) (blame)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# arguments are not strictly necessary to build

CC_EXTRA_ARGS = -Wall -Wextra -O3 -ggdb

.PHONY: default
default: build/disk.iso

# command and arguments that you should be careful about changing

NASM = nasm
CC = toolchain/usr/bin/x86_64-elf-c++
AR = toolchain/usr/bin/x86_64-elf-ar
LD = toolchain/usr/bin/x86_64-elf-ld

KERNEL_INCLUDES = \
  dependencies/limine \
  dependencies/mintsuki-headers \
  kernel/include

USER_INCLUDES = \
  dependencies/mintsuki-headers \
  euler/include \
  $(wildcard libraries/*/include)

NASM_ARGS = -f elf64

CC_ARGS_COMMON = -std=c++20 -static -mno-sse -Iinclude ${CC_EXTRA_ARGS}
CC_ARGS_KERNEL = \
  ${CC_ARGS_COMMON} -ffreestanding -fno-exceptions \
  -fno-rtti -mcmodel=kernel ${KERNEL_INCLUDES:%=-I%}
CC_ARGS_USER = ${CC_ARGS_COMMON} ${USER_INCLUDES:%=-I%}

LD_ARGS = -z noexecstack

LIBDIR = toolchain/usr/x86_64-elf/lib

SOURCES_FIND = -type f -regex '.*\.\(asm\|cpp\)'

# kernel section

build/kernel/%.asm.o: kernel/%.asm
	@mkdir -p ${@D}
	${NASM} ${NASM_ARGS} $^ -o $@

build/kernel/%.cpp.o: kernel/%.cpp
	@mkdir -p ${@D}
	${CC} -c ${CC_ARGS_KERNEL} $^ -o $@

KERNEL_SOURCES = $(shell find kernel/source ${SOURCES_FIND})
build/kernel.elf: ${KERNEL_SOURCES:%=build/%.o}
	${LD} ${LD_ARGS} -T kernel/link.ld $^ -o $@

# euler section

build/euler/%.asm.o: euler/%.asm
	@mkdir -p ${@D}
	${NASM} ${NASM_ARGS} $^ -o $@

build/euler/%.cpp.o: euler/%.cpp
	@mkdir -p ${@D}
	${CC} -c ${CC_ARGS_USER} -ffreestanding $^ -o $@

EULER_SOURCES = $(shell find euler/source ${SOURCES_FIND})
${LIBDIR}/crt0.o ${LIBDIR}/libc.a ${LIBDIR}/libg.a ${LIBDIR}/libm.a build/euler.a&: ${EULER_SOURCES:%=build/%.o}
	${AR} rcs build/euler.a $^
	cp build/euler.a ${LIBDIR}/libc.a
	${NASM} ${NASM_ARGS} /dev/null -o ${LIBDIR}/crt0.o
	${AR} rcs ${LIBDIR}/libg.a ${LIBDIR}/crt0.o
	${AR} rcs ${LIBDIR}/libm.a ${LIBDIR}/crt0.o

# libraries and applications section

ALL_LIBRARIES = daguerre pake
ALL_APPLICATIONS = clock goldman hello init

  clock_LIBRARIES = daguerre pake
goldman_LIBRARIES = daguerre
  hello_LIBRARIES = daguerre pake
   init_LIBRARIES =

build/%.cpp.o: %.cpp
	@mkdir -p ${@D}
	${CC} -c ${CC_ARGS_USER} $^ -o $@

# ${1} = library name
define LIBRARY_TEMPLATE =
${1}_SOURCES = $$(shell find libraries/${1}/source $${SOURCES_FIND})
$${LIBDIR}/lib${1}.a build/libraries/lib${1}.a&: $${${1}_SOURCES:%=build/%.o}
	$${AR} rcs build/libraries/lib${1}.a $$^
	cp build/libraries/lib${1}.a $${LIBDIR}/lib${1}.a
endef

# ${1} = application name
define APPLICATION_TEMPLATE =
${1}_SOURCES = $$(shell find applications/${1}/source $${SOURCES_FIND})
build/applications/${1}.elf: $${${1}_SOURCES:%=build/%.o} $${${1}_LIBRARIES:%=$${LIBDIR}/lib%.a} $${LIBDIR}/libc.a
	$${CC} ${CC_ARGS_USER} $${${1}_SOURCES:%=build/%.o} $$(patsubst %,-l%,$${${1}_LIBRARIES}) -o $$@
endef

$(foreach library,${ALL_LIBRARIES},$(eval $(call LIBRARY_TEMPLATE,${library})))
$(foreach application,${ALL_APPLICATIONS},$(eval $(call APPLICATION_TEMPLATE,${application})))

# initfs and disk section

build/initfs.tgz: ${ALL_APPLICATIONS:%=build/applications/%.elf}
	rm -rf build/initfs
	cp -r skeleton build/initfs
	$(foreach application,${ALL_APPLICATIONS},cp build/applications/${application}.elf build/initfs/bin/${application}; )
	cd build/initfs && tar czf ../initfs.tgz .

build/disk.iso: build/kernel.elf build/initfs.tgz
	rm -rf build/iso
	mkdir build/iso
	cp dependencies/limine/bin/limine-bios.sys dependencies/limine/bin/limine-bios-cd.bin \
	  build/kernel.elf build/initfs.tgz build/iso/
	echo 'TIMEOUT=0' > build/iso/limine.cfg
	echo ':Hilbert OS' >> build/iso/limine.cfg
	echo 'PROTOCOL=limine' >> build/iso/limine.cfg
	echo 'KERNEL_PATH=boot:///kernel.elf' >> build/iso/limine.cfg
	echo 'MODULE_PATH=$$boot:///initfs.tgz' >> build/iso/limine.cfg
	echo 'MODULE_CMDLINE=initfs' >> build/iso/limine.cfg
	xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4 \
	  -boot-info-table --protective-msdos-label build/iso -o $@

# phony targets

.PHONY: run
run: build/disk.iso
	gdb -x qemu.gdb

.PHONY: clean
clean:
	rm -rf build ${LIBDIR}/crt0.o ${LIBDIR}/libc.a ${LIBDIR}/libg.a ${LIBDIR}/libm.a $(foreach library,${ALL_LIBRARIES},${LIBDIR}/lib${library}.a)