Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
234 lines (179 sloc) 6.32 KB
#
# 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
ifdef LAB
SETTINGLAB := true
else
-include conf/lab.mk
endif
-include conf/env.mk
ifndef SOL
SOL := 0
endif
ifndef LABADJUST
LABADJUST := 0
endif
ifndef LABSETUP
LABSETUP := ./
endif
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 GCCPREFIX explicitly in conf/env.mk
# try to infer the correct GCCPREFIX
ifndef GCCPREFIX
GCCPREFIX := $(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 GCCPREFIX" 1>&2; \
echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
echo "*** To turn off this error, run 'gmake GCCPREFIX= ...'." 1>&2; \
echo "***" 1>&2; exit 1; fi)
endif
# try to infer the correct QEMU
ifndef QEMU
QEMU := $(shell if which qemu > /dev/null; \
then echo qemu; exit; \
else \
qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \
if test -x $$qemu; then echo $$qemu; exit; fi; fi; \
echo "***" 1>&2; \
echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
echo "*** or have you tried setting the QEMU variable in conf/env.mk?" 1>&2; \
echo "***" 1>&2; exit 1)
endif
# try to generate a unique GDB port
GDBPORT := $(shell expr `id -u` % 5000 + 25000)
CC := $(GCCPREFIX)gcc -pipe
AS := $(GCCPREFIX)as
AR := $(GCCPREFIX)ar
LD := $(GCCPREFIX)ld
OBJCOPY := $(GCCPREFIX)objcopy
OBJDUMP := $(GCCPREFIX)objdump
NM := $(GCCPREFIX)nm
# Native commands
NCC := gcc $(CC_VER) -pipe
TAR := gtar
PERL := perl
# Compiler flags
# -fno-builtin is required to avoid refs to undefined functions in the kernel.
# Only optimize to -O1 to discourage inlining, which complicates backtraces.
CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -O1 -fno-builtin -I$(TOP) -MD
CFLAGS += -Wall -Wno-format -Wno-unused -Werror -gstabs -m32
CFLAGS += -I$(TOP)/net/lwip/include \
-I$(TOP)/net/lwip/include/ipv4 \
-I$(TOP)/net/lwip/jos
# 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)
# Common linker flags
LDFLAGS := -m elf_i386
# Linker flags for JOS user programs
ULDFLAGS := -T user/user.ld
GCC_LIB := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
# Lists that the */Makefrag 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)/kern/%.o \
$(OBJDIR)/lib/%.o $(OBJDIR)/fs/%.o $(OBJDIR)/net/%.o \
$(OBJDIR)/user/%.o
KERN_CFLAGS := $(CFLAGS) -DJOS_KERNEL -gstabs
USER_CFLAGS := $(CFLAGS) -DJOS_USER -gstabs
# Include Makefrags for subdirectories
include boot/Makefrag
include kern/Makefrag
include lib/Makefrag
include user/Makefrag
include fs/Makefrag
include net/Makefrag
PORT7 := $(shell expr $(GDBPORT) + 1)
PORT80 := $(shell expr $(GDBPORT) + 2)
IMAGES = $(OBJDIR)/kern/kernel.img $(OBJDIR)/fs/fs.img
QEMUOPTS = -hda $(OBJDIR)/kern/kernel.img -hdb $(OBJDIR)/fs/fs.img -serial mon:stdio \
-net user -net nic,model=i82559er -redir tcp:$(PORT7)::7 \
-redir tcp:$(PORT80)::80 $(QEMUEXTRA)
.gdbinit: .gdbinit.tmpl
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
qemu: $(IMAGES)
$(QEMU) $(QEMUOPTS)
qemu-nox: $(IMAGES)
echo "*** Use Ctrl-a x to exit"
$(QEMU) -nographic $(QEMUOPTS)
qemu-gdb: $(IMAGES) .gdbinit
@echo "*** Now run 'gdb'." 1>&2
$(QEMU) $(QEMUOPTS) -s -S -p $(GDBPORT)
qemu-gdb-nox: $(IMAGES) .gdbinit
@echo "*** Now run 'gdb'." 1>&2
$(QEMU) -nographic $(QEMUOPTS) -s -S -p $(GDBPORT)
which-qemu:
@echo $(QEMU)
# For deleting the build
clean:
rm -rf $(OBJDIR)
realclean: clean
rm -rf lab$(LAB).tar.gz jos.out
distclean: realclean
rm -rf conf/gcc.mk
grade: $(LABSETUP)grade-lab$(LAB).sh
$(V)$(MAKE) clean >/dev/null 2>/dev/null
$(MAKE) all
sh $(LABSETUP)grade-lab$(LAB).sh
handin: tarball
@echo Please visit http://pdos.csail.mit.edu/cgi-bin/828handin
@echo and upload lab$(LAB)-handin.tar.gz. Thanks!
tarball: realclean
tar cf - `find . -type f | grep -v '^\.*$$' | grep -v '/CVS/' | grep -v '/\.svn/' | grep -v '/\.git/' | grep -v 'lab[0-9].*\.tar\.gz'` | gzip > lab$(LAB)-handin.tar.gz
# For test runs
run-%:
$(V)rm -f $(OBJDIR)/kern/init.o $(IMAGES)
$(V)$(MAKE) "DEFS=-DTEST=_binary_obj_user_$*_start -DTESTSIZE=_binary_obj_user_$*_size" $(IMAGES)
echo "*** Use Ctrl-a x to exit"
$(QEMU) -nographic $(QEMUOPTS)
xrun-%:
$(V)rm -f $(OBJDIR)/kern/init.o $(IMAGES)
$(V)$(MAKE) "DEFS=-DTEST=_binary_obj_user_$*_start -DTESTSIZE=_binary_obj_user_$*_size" $(IMAGES)
$(QEMU) $(QEMUOPTS)
# For network connections
which-ports:
@echo "Local port $(PORT7) forwards to JOS port 7 (echo server)"
@echo "Local port $(PORT80) forwards to JOS port 80 (web server)"
nc-80:
nc localhost $(PORT80)
nc-7:
nc localhost $(PORT7)
telnet-80:
telnet localhost $(PORT80)
telnet-7:
telnet localhost $(PORT7)
# 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 clean-labsetup distclean grade labsetup