-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
339 lines (280 loc) · 10.2 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
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#
# This makefile system follows the structuring conventions
# recommended by Peter Miller in his excellent paper:
#
# Recursive Make Considered Harmful
# http://aegis.sourceforge.net/auug97.pdf
#
OBJDIR := obj
COMMIT := ""
# Run 'make V=1' to turn on verbose commands, or 'make V=0' to turn them off.
ifeq ($(V),1)
override V =
endif
ifeq ($(V),0)
override V = @
endif
-include conf/lab.mk
-include conf/env.mk
LABSETUP ?= ./
TOP = .
# Cross-compiler jos toolchain
#
# This Makefile will automatically use the cross-compiler toolchain
# installed as 'i386-jos-elf-*', if one exists. If the host tools ('gcc',
# 'objdump', and so forth) compile for a 32-bit x86 ELF target, that will
# be detected as well. If you have the right compiler toolchain installed
# using a different name, set CROSS_COMPILE explicitly in conf/env.mk
# try to infer the correct CROSS_COMPILE
ifndef CROSS_COMPILE
CROSS_COMPILE := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
then echo 'i386-jos-elf-'; \
elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
then echo ''; \
else echo "***" 1>&2; \
echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \
echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
echo "*** prefix other than 'i386-jos-elf-', set your CROSS_COMPILE" 1>&2; \
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
echo "*** To turn off this error, run 'gmake CROSS_COMPILE= ...'." 1>&2; \
echo "***" 1>&2; exit 1; fi)
endif
# try to generate a unique GDB port
GDBPORT := $(shell expr `id -u` % 5000 + 25000)
CC := $(CROSS_COMPILE)gcc -pipe
AS := $(CROSS_COMPILE)gcc
AR := $(CROSS_COMPILE)ar
LD := $(CROSS_COMPILE)gcc
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
NM := $(CROSS_COMPILE)nm
# binutils-gold has problems with parsing -Ttext right
ifneq ($(shell which $(LD).bfd 2>/dev/null),)
LD := $(LD).bfd
endif
# Native commands
NCC := gcc $(CC_VER) -pipe
NATIVE_CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -I$(TOP) -MD -Wall
TAR := gtar
PERL := perl
# Compiler flags
# -fno-builtin is required to avoid refs to undefined functions in the kernel.
# -O1 and -fno-builtin to make backtraces work more nicely.
CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -O1 -fno-inline -fno-builtin -I$(TOP) -MD
CFLAGS += -fno-omit-frame-pointer
CFLAGS += -Wall -Wno-format -Wno-unused -Werror
CFLAGS += -Iinclude
# Add -fno-stack-protector if the option exists.
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
GCC_LIB := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
# Lists that the */Makefile makefile fragments will add to
OBJDIRS :=
# Make sure that 'all' is the first target
all:
# Eliminate default suffix rules
.SUFFIXES:
# Delete target files if there is an error (or make is interrupted)
.DELETE_ON_ERROR:
# make it so that no intermediate .o files are ever deleted
.PRECIOUS: %.o $(OBJDIR)/boot/%.o $(OBJDIR)/kernel/%.o \
$(OBJDIR)/lib/%.o $(OBJDIR)/fs/%.o $(OBJDIR)/net/%.o \
$(OBJDIR)/user/%.o
BOOT_CFLAGS := $(CFLAGS) -DJOS_KERNEL -fno-pie -m32
BOOT_LDFLAGS := -N -nostdlib -T boot/boot.ld -m32 -static -fno-pie -Wl,-melf_i386
KERNEL_CFLAGS := $(CFLAGS) -DJOS_KERNEL -gdwarf-2 -mcmodel=large -fno-pie
KERNEL_CFLAGS += -DKERNEL_LMA=0x100000
KERNEL_CFLAGS += -DKERNEL_VMA=0xFFFF800000000000
KERNEL_CFLAGS += -DLAB3_SYSCALL=0x1
#KERNEL_CFLAGS += -DBONUS_LAB3=0x1
# KERNEL_CFLAGS += -DUSE_BIG_KERNEL_LOCK=0x1
KERNEL_CFLAGS += -DBONUS_LAB6=0x1
KERNEL_CFLAGS += -mno-sse
KERNEL_LDFLAGS := -Tkernel/kernel.ld -nostdlib -n -fno-pie
KERNEL_LDFLAGS += -Wl,--defsym,KERNEL_LMA=0x100000
KERNEL_LDFLAGS += -Wl,--defsym,KERNEL_VMA=0xFFFF800000000000
KERNEL_LDFLAGS += -static
USER_CFLAGS := $(CFLAGS) -DJOS_USER -gdwarf-2 -fPIC
USER_LDFLAGS := -Tuser/user.ld -nostdlib -n
USER_CFLAGS += -DLAB3_SYSCALL=0x1
USER_CFLAGS += -DBONUS_LAB6=0x1
# Update .vars.X if variable X has changed since the last make run.
#
# Rules that use variable X should depend on $(OBJDIR)/.vars.X. If
# the variable's value has changed, this will update the vars file and
# force a rebuild of the rule that depends on it.
$(OBJDIR)/.vars.%: FORCE
$(V)echo "$($*)" | cmp -s $@ || echo "$($*)" > $@
.PRECIOUS: $(OBJDIR)/.vars.%
.PHONY: FORCE
# Include Makefiles for subdirectories
include boot/Makefile
include kernel/Makefile
include user/Makefile
include lib/Makefile
CPUS ?= 1
QEMUOPTS += -machine q35
QEMUOPTS += -device ich9-ahci,id=ahci
QEMUOPTS += -drive id=disk0,format=raw,file=$(OBJDIR)/kernel/kernel.img,if=none
QEMUOPTS += -device ide-drive,drive=disk0,bus=ahci.0
QEMUOPTS += -drive id=disk1,format=raw,file=$(OBJDIR)/kernel/swap.img,if=none
QEMUOPTS += -device ide-drive,drive=disk1,bus=ahci.1
QEMUOPTS += -serial mon:stdio -gdb tcp::$(GDBPORT)
QEMUOPTS += $(shell if $(QEMU) -nographic -help | grep -q '^-D '; then echo '-D qemu.log'; fi)
QEMUOPTS += -no-reboot -D /dev/stdout
QEMUOPTS += -smp $(CPUS)
QEMUOPTS += $(QEMUEXTRA)
IMAGES += $(OBJDIR)/kernel/kernel.img
IMAGES += $(OBJDIR)/kernel/swap.img
.gdbrc: .gdbrc.tmpl
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
gdb: .gdbrc
gdb -x .gdbrc obj/kernel/kernel
pre-qemu: .gdbrc
qemu: $(IMAGES) pre-qemu
@$(QEMU) $(QEMUOPTS)
qemu-nox: $(IMAGES) pre-qemu
@echo "***"
@echo "*** Use Ctrl-a x to exit qemu"
@echo "***"
@$(QEMU) -nographic $(QEMUOPTS)
qemu-gdb: $(IMAGES) pre-qemu
@sed "s/localhost:1234/localhost:$(GDBPORT)/" < .gdbrc.tmpl > .gdbrc
@echo "***"
@echo "*** Now run 'make gdb'." 1>&2
@echo "***"
@$(QEMU) $(QEMUOPTS) -S
qemu-nox-gdb: $(IMAGES) pre-qemu
@sed "s/localhost:1234/localhost:$(GDBPORT)/" < .gdbrc.tmpl > .gdbrc
@echo "***"
@echo "*** Now run 'make gdb'." 1>&2
@echo "***"
@$(QEMU) -nographic $(QEMUOPTS) -S
print-qemu:
@echo $(QEMU)
print-gdbport:
@echo $(GDBPORT)
# For deleting the build
clean:
rm -rf $(OBJDIR) .gdbrc jos.in qemu.log
realclean: clean
rm -rf lab$(LAB).tar.gz \
jos.out $(wildcard jos.out.*) \
qemu.pcap $(wildcard qemu.pcap.*)
distclean: realclean
rm -rf conf/gcc.mk
ifneq ($(V),@)
GRADEFLAGS += -v
endif
grade:
@echo $(MAKE) clean
@$(MAKE) clean || \
(echo "'make clean' failed. HINT: Do you have another running instance of JOS?" && exit 1)
./grade-lab$(LAB) $(GRADEFLAGS)
handin: handin-check
ifeq (${COMMIT}, "")
@git --no-pager log -3 --pretty=oneline;
@echo "You did not specify a commit hash.";
@echo "Please set COMMIT variable in the command line:";
@echo "> make handin COMMIT=<your commit-hash>";
@false;
endif
@if git tag -l | grep "${TAG_LAB_SOLN}" >/dev/null; then \
if ! git tag -d ${TAG_LAB_SOLN}; then \
echo ;\
echo "Tag: ${TAG_LAB_SOLN} exists already. Failed removing it."; \
false; \
fi; \
fi;
@echo "git tag ${TAG_LAB_SOLN} -m 'Solution for : Lab${LAB}' ${COMMIT} ";
@if ! git tag ${TAG_LAB_SOLN} -m 'Solution for : Lab${LAB}' ${COMMIT}; then \
echo ; \
echo "*** Hand-in: Tagging your solution failed. Please retry."; \
false; \
fi;
@echo "Your commit was tagged successfully: [ ${COMMIT} : ${TAG_LAB_SOLN} ]";
handin-bonus: handin-check
ifeq (${COMMIT}, "")
@git --no-pager log -3 --pretty=oneline;
@echo "You did not specify a commit hash for BONUS.";
@echo "Please set COMMIT variable in the command line:";
@echo "> make handin COMMIT=<your commit-hash>"
@false;
endif
@if git tag -l | grep "${TAG_LAB_BONUS}" >/dev/null; then \
if ! git tag -d ${TAG_LAB_BONUS}; then \
echo ;\
echo "Tag: ${TAG_LAB_BONUS} exists already. Failed to remove it."; \
false; \
fi; \
fi;
@echo "git tag ${TAG_LAB_BONUS} -m 'Solution for BONUS of : Lab${LAB}' ${COMMIT} ";
@if ! git tag ${TAG_LAB_BONUS} -m 'Solution for BONUS of : Lab${LAB}' ${COMMIT}; then \
echo ; \
echo "*** Hand-in BONUS: Tagging your solution failed. Please retry."; \
false; \
fi;
@echo "Bonus commit tagged successfully: [ ${COMMIT} : ${TAG_LAB_BONUS} ]";
handin-check:
@if test "$$(git symbolic-ref HEAD)" != refs/heads/lab$(LAB); then \
git branch; \
read -p "You are not on the lab$(LAB) branch. Hand-in the current branch? [y/N] " r; \
test "$$r" = y; \
fi
@if ! git diff-files --quiet || ! git diff-index --quiet --cached HEAD; then \
git status; \
echo; \
echo "You have uncomitted changes. Please commit or stash them."; \
false; \
fi
@if test -n "`git ls-files -o --exclude-standard`"; then \
git status; \
read -p "Untracked files will not be handed in. Continue? [y/N] " r; \
test "$$r" = y; \
fi
tarball: handin-check
git archive --format=tar HEAD > ${PATCH_PREFIX}.lab$(LAB)-handin.tar
tar -r --file=${PATCH_PREFIX}.lab$(LAB)-handin.tar ./.git
gzip ${PATCH_PREFIX}.lab$(LAB)-handin.tar
apply-check: ${PATCH_PREFIX}.lab${LAB}.patch
@if ! git apply --check ${PATCH_PREFIX}.lab${LAB}.patch; then \
echo "** Patch does not apply: ${PATCH_PREFIX}.lab${LAB}.patch"; \
false; \
fi; \
apply: ${PATCH_PREFIX}.lab${LAB}.patch apply-check
@if ! git am ${PATCH_PREFIX}.lab${LAB}.patch; then \
echo "Failed to apply your soln patch: ${PATCH_PREFIX}.lab${LAB}.patch"; \
fi; \
# For test runs
prep-%:
$(V)$(MAKE) "INIT_CFLAGS=${INIT_CFLAGS} -DTEST=`case $* in *_*) echo $*;; *) echo user_$*;; esac`" $(IMAGES)
run-%-nox-gdb: prep-% pre-qemu
@sed "s/localhost:1234/localhost:$(GDBPORT)/" < .gdbrc.tmpl > .gdbrc
@echo "add-symbol-file obj/user/$*" >> .gdbrc
@echo "***"
@echo "*** Now run 'make gdb'." 1>&2
@echo "***"
@$(QEMU) -nographic $(QEMUOPTS) -S
run-%-gdb: prep-% pre-qemu
@sed "s/localhost:1234/localhost:$(GDBPORT)/" < .gdbrc.tmpl > .gdbrc
@echo "add-symbol-file obj/user/$*" >> .gdbrc
@echo "***"
@echo "*** Now run 'make gdb'." 1>&2
@echo "***"
@$(QEMU) $(QEMUOPTS) -S
run-%-nox: prep-% pre-qemu
@$(QEMU) -nographic $(QEMUOPTS)
run-%: prep-% pre-qemu
@$(QEMU) $(QEMUOPTS)
# This magic automatically generates makefile dependencies
# for header files included from C source files we compile,
# and keeps those dependencies up-to-date every time we recompile.
# See 'mergedep.pl' for more information.
$(OBJDIR)/.deps: $(foreach dir, $(OBJDIRS), $(wildcard $(OBJDIR)/$(dir)/*.d))
@mkdir -p $(@D)
@$(PERL) mergedep.pl $@ $^
-include $(OBJDIR)/.deps
always:
@:
.PHONY: all always \
handin tarball clean realclean distclean grade handin-prep handin-check gdb