X-Git-Url: http://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=blobdiff_plain;f=Makefile;h=27eb77a4fa97f66584c8ade5f015aafbe16b99a8;hp=af50234ebbdd8540214fc6faa1efa719caca5fd3;hb=bde00f5648a41dbb91a6725067f97882dcf92380;hpb=fe786485f73677148b69662777107971d40d4562 diff --git a/Makefile b/Makefile index af50234..27eb77a 100644 --- a/Makefile +++ b/Makefile @@ -36,17 +36,41 @@ # # - There are a few other TODOs sprinkled throughout the makefile. +# Allow people to override our setting of the --no-print-directory option in +# their Makelocal. This is useful, for example, to allow emacs to find the +# correct file when errors are encountered using its builtin 'M-x compile' +# command. +NO_PRINT_DIRECTORY ?= --no-print-directory + +# Save the ability to export the parent's original environment for future use +export_parent_env := $(shell export | sed 's/$$/;/') + +# Save the ability to clear the current environment for future use +clear_current_env := for c in $$(env | cut -d '=' -f 1); do unset $$c; done; + +# Define a set of commands to reset the environment to the parent's environment +# and then run a local make target +define make_as_parent + $(clear_current_env)\ + $(export_parent_env)\ + $(MAKE) $(NO_PRINT_DIRECTORY) $(1) +endef + # Do not: # o use make's built-in rules and variables # (this increases performance and avoids hard-to-debug behaviour); # o print "Entering directory ..."; -MAKEFLAGS += -rR --no-print-directory +MAKEFLAGS += -rR $(NO_PRINT_DIRECTORY) # That's our default target when none is given on the command line # This can be overriden with a Makelocal PHONY := all all: akaros-kernel +# Export the location of this top level directory +AKAROS_ROOT = $(CURDIR) +export AKAROS_ROOT + # Setup dumping ground for object files and any temporary files we need to # generate for non-kbuild targets OBJDIR ?= obj @@ -306,8 +330,9 @@ KERNEL_LD ?= kernel.ld gcc-lib := $(shell $(CC) -print-libgcc-file-name 2>/dev/null) NOSTDINC_FLAGS += -nostdinc -isystem \ $(shell $(CC) -print-file-name=include 2>/dev/null) -XCC_TARGET_ROOT := $(dir $(shell which $(CC) 2> /dev/null))../$(patsubst %-,%,\ - $(CROSS_COMPILE)) +XCC_TARGET_ROOT := $(shell $(CC) --print-sysroot 2> /dev/null) +XCC_TARGET_LIB := $(XCC_TARGET_ROOT)/usr/lib/ +XCC_TARGET_INCLUDE := $(XCC_TARGET_ROOT)/usr/include/ CFLAGS_KERNEL += -O2 -pipe -MD CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline @@ -316,8 +341,9 @@ CFLAGS_KERNEL += -fno-stack-protector CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused CFLAGS_KERNEL += -DROS_KERNEL CFLAGS_KERNEL += -include include/generated/autoconf.h -include include/common.h +CFLAGS_KERNEL += -fplan9-extensions ifeq ($(CONFIG_64BIT),y) -CFLAGS_KERNEL += -m64 +CFLAGS_KERNEL += -m64 -g else CFLAGS_KERNEL += -m32 -gstabs endif @@ -338,13 +364,15 @@ KBUILD_CHECKSRC := 0 export AKAROSINCLUDE CROSS_COMPILE export CC CPP AS AR LD OBJCOPY OBJDUMP NM STRIP export CFLAGS_KERNEL AFLAGS_KERNEL -export NOSTDINC_FLAGS XCC_TARGET_ROOT +export NOSTDINC_FLAGS XCC_TARGET_ROOT XCC_TARGET_LIB XCC_TARGET_INCLUDE export KBUILD_BUILTIN KBUILD_CHECKSRC -CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline +CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline \ + -Wsystem-headers CXXFLAGS_USER += -O2 +CFLAGS_USER_LIBS += -fPIC -static -fno-omit-frame-pointer -g -export CFLAGS_USER CXXFLAGS_USER +export CFLAGS_USER CXXFLAGS_USER CFLAGS_USER_LIBS # Akaros include stuff (includes custom make targets and user overrides) # ========================================================================= @@ -362,7 +390,7 @@ CMP_KERNEL_OBJ := $(KERNEL_OBJ).gz # KFS_PATH. Future rules related to KFS will have issues (mkdir with no # argument, or a find of the entire pwd). It's also possible someone provided # an empty path. To deal with both, we'll just have a sensible default. -kfs-paths := $(patsubst "%",%,$(CONFIG_KFS_PATHS)) +kfs-paths := $(subst $\",,$(CONFIG_KFS_PATHS)) ifeq ($(kfs-paths),) kfs-paths := kern/kfs endif @@ -389,7 +417,7 @@ $(srctree)/Makelocal: ; # We have all-arch-dirs and all-dirs, so that we can still clean even without # an arch symlink. -core-y += kern/src/ kern/drivers/ +core-y += kern/src/ kern/drivers/ kern/lib/ $(AKAROS_EXTERNAL_DIRS) arch-y += kern/arch/$(ARCH)/ akaros-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y))) @@ -416,39 +444,85 @@ endif ext2_bdev_obj = $(OBJDIR)/kern/$(shell basename $(ext2-bdev)).o endif -kern_initramfs_files := $(shell mkdir -p $(kfs-paths); \ - find $(kfs-paths)) +# a bit hacky: we want to make sure the directories exist, and error out +# otherwise. we also want to error out before the initramfs target, otherwise +# we might not get the error (if initramfs files are all up to date). the +# trickiest thing here is that kfs-paths-check could be stale and require an +# oldconfig. running make twice should suffice. +kfs-paths-check := $(shell for i in $(kfs-paths); do \ + if [ ! -d "$$i" ]; then \ + echo "Can't find KFS directory $$i"; \ + $(MAKE) -f $(srctree)/Makefile \ + silentoldconfig > /dev/null; \ + exit -1; \ + fi; \ + done; echo "ok") + +ifneq (ok,$(kfs-paths-check)) +$(error $(kfs-paths-check), try make one more time in case of stale configs) +endif +kern_initramfs_files := $(shell find $(kfs-paths)) + +# Need to make an empty cpio, then append each kfs-path's contents $(kern_cpio) initramfs: $(kern_initramfs_files) @echo " Building initramfs:" @if [ "$(CONFIG_KFS_CPIO_BIN)" != "" ]; then \ sh $(CONFIG_KFS_CPIO_BIN); \ fi + @cat /dev/null | cpio --quiet -oH newc -O $(kern_cpio) $(Q)for i in $(kfs-paths); do cd $$i; \ echo " Adding $$i to initramfs..."; \ - find -L . | cpio --quiet -oH newc > \ - $(CURDIR)/$(kern_cpio); \ + find -L . | cpio --quiet -oAH newc -O $(CURDIR)/$(kern_cpio); \ cd $$OLDPWD; \ done; -ld_emulation = $(shell $(OBJDUMP) -i | grep -v BFD | grep ^[a-z] |head -n1) -ld_arch = $(shell $(OBJDUMP) -i | grep -v BFD | grep "^ [a-z]" | head -n1) +ld_emulation = $(shell $(OBJDUMP) -i 2>/dev/null | \ + grep -v BFD | grep ^[a-z] | head -n1) +ld_arch = $(shell $(OBJDUMP) -i 2>/dev/null |\ + grep -v BFD | grep "^ [a-z]" | head -n1) + +# Our makefile doesn't detect a change in subarch, and old binary objects that +# don't need to be updated won't get rebuilt, but they also can't link with the +# new subarch (32 bit vs 64 bit). If we detect the wrong type, we'll force a +# rebuild. +existing-cpio-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \ + grep format | sed 's/.*format //g') +ifneq ($(existing-cpio-emul),) +ifneq ($(existing-cpio-emul),$(ld_emulation)) +$(kern_cpio_obj): cpio-rebuild +cpio-rebuild: + $(Q)rm $(kern_cpio_obj) +endif +endif $(kern_cpio_obj): $(kern_cpio) - $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@ + $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@ + +existing-ext2b-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \ + grep format | sed 's/.*format //g') +ifneq ($(existing-ext2b-emul),) +ifneq ($(existing-ext2b-emul),$(ld_emulation)) +$(ext2_bdev_obj): ext2b-rebuild +ext2b-rebuild: + $(Q)rm $(ext2_bdev_obj) +endif +endif -# If no ext2, this will be (empty) : (empty) $(ext2_bdev_obj): $(ext2-bdev) - $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $^ $@ + $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@ +# Not the worlds most elegant link command. link-kernel takes the obj output +# name, then the linker script, then everything else you'd dump on the ld +# command line, including linker options and objects to link together. +# +# After the script is done, we run the arch-specific command directly. quiet_cmd_link-akaros = LINK $@ - cmd_link-akaros = $(LD) -T kern/arch/$(ARCH)/$(KERNEL_LD) -o $@ \ - $(LDFLAGS_KERNEL) \ - $(akaros-deps) \ - $(gcc-lib) \ - $(kern_cpio_obj) \ - $(ext2_bdev_obj) ; \ - $(OBJDUMP) $(OBJDUMP_FLAGS) -S $@ > $@.asm + cmd_link-akaros = $(CONFIG_SHELL) scripts/link-kernel.sh $@ \ + kern/arch/$(ARCH)/$(KERNEL_LD) $(LDFLAGS_KERNEL) \ + $(akaros-deps) $(gcc-lib) $(kern_cpio_obj) \ + $(ext2_bdev_obj); \ + $(ARCH_POST_LINK_CMD) # For some reason, the if_changed doesn't work with FORCE (like it does in # Linux). It looks like it can't find the .cmd file or something (also @@ -491,45 +565,64 @@ endif #ifeq ($(mixed-targets),1) # List all userspace directories here, and state any dependencies between them, # such as how pthread depends on parlib. -user-dirs = parlib pthread benchutil -pthread: parlib +user-dirs = parlib pthread benchutil iplib ndblib vmm +benchutil: parlib +pthread: parlib benchutil +iplib: parlib +ndblib: iplib +vmm: parlib PHONY += install-libs $(user-dirs) install-libs: $(user-dirs) symlinks cc-exists $(user-dirs): - @cd user/$@ && $(MAKE) && $(MAKE) install + @$(MAKE) -C user/$@ DEPLIBS="$^" && $(MAKE) -C user/$@ install PHONY += userclean $(clean-user-dirs) clean-user-dirs := $(addprefix _clean_user_,$(user-dirs)) -userclean: $(clean-user-dirs) testclean +userclean: $(clean-user-dirs) testclean utestclean $(clean-user-dirs): - @cd user/$(patsubst _clean_user_%,%,$@) && $(MAKE) clean + @$(MAKE) -C user/$(patsubst _clean_user_%,%,$@) clean tests/: tests tests: install-libs @$(MAKE) -f tests/Makefile +PHONY += utest +utest: $(user-dirs) + @$(MAKE) -C user/$@ + testclean: @$(MAKE) -f tests/Makefile clean +utestclean: + @$(MAKE) -C user/utest clean + # KFS related stuff PHONY += fill-kfs unfill-kfs -XCC_SO_FILES = $(addprefix $(XCC_TARGET_ROOT)/lib/, *.so*) +xcc-gcc-libs = $(XCC_TARGET_ROOT)/../lib/ +xcc-so-files = $(addprefix $(XCC_TARGET_LIB), *.so*) \ + $(addprefix $(xcc-gcc-libs), *.so*) $(OBJDIR)/.dont-force-fill-kfs: - @rm -rf $(addprefix $(FIRST_KFS_PATH)/lib, $(notdir $(XCC_SO_FILES))) + $(Q)rm -rf $(addprefix $(FIRST_KFS_PATH)/lib/, $(notdir $(xcc-so-files))) @echo "Cross Compiler 'so' files removed from KFS" - @$(MAKE) -f tests/Makefile unfill-kfs + @$(MAKE) -f tests/Makefile uninstall + @echo "Apps from /test removed from KFS" + @$(MAKE) -C user/utest uninstall + @echo "User space tests removed from KFS" @touch $(OBJDIR)/.dont-force-fill-kfs -fill-kfs: $(OBJDIR)/.dont-force-fill-kfs install-libs +fill-kfs: $(OBJDIR)/.dont-force-fill-kfs install-libs tests @mkdir -p $(FIRST_KFS_PATH)/lib - @cp -uP $(XCC_SO_FILES) $(FIRST_KFS_PATH)/lib + $(Q)cp -uP $(xcc-so-files) $(FIRST_KFS_PATH)/lib @echo "Cross Compiler 'so' files installed to KFS" - @$(MAKE) -f tests/Makefile fill-kfs + @$(MAKE) -f tests/Makefile install + @echo "Apps from /test installed to KFS" + @$(MAKE) -C user/utest install + @echo "User space tests installed to KFS" # Use doxygen to make documentation for ROS (Untested since 2010 or so) doxygen-dir := $(CUR_DIR)/Documentation/doxygen @@ -551,6 +644,63 @@ objclean: realclean: userclean mrproper doxyclean objclean +# Bundled apps +# ========================================================================= + +PHONY += apps-install +apps-install: + @$(call make_as_parent, -C tools/apps/busybox) + +PHONY += apps-clean +apps-clean: + @$(call make_as_parent, -C tools/apps/busybox clean) + +# Cross Compiler +# ========================================================================= + +xcc_build_dir := tools/compilers/gcc-glibc +xcc_target := $(ARCH) +ifeq ($(xcc_target),x86) + xcc_target := $(xcc_target)_64 +endif +xcc_cleans := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\ + grep "VALID_CLEANS := " |\ + sed -e 's/VALID_CLEANS := //') +xcc_subcmds := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\ + grep "VALID_SUBCMDS := " |\ + sed -e 's/VALID_SUBCMDS := //') +xcc_clean_goals := $(patsubst %, xcc-%, $(xcc_cleans)) +xcc_subcmd_goals := $(patsubst %, xcc-%, $(xcc_subcmds)) + +PHONY += xcc +xcc: xcc-build + +PHONY += $(xcc_clean_goals) +$(xcc_clean_goals): + @target="$(patsubst xcc-%,%,$(@))";\ + $(call make_as_parent, -C $(xcc_build_dir) $${target}) + +PHONY += $(xcc_subcmd_goals) +$(xcc_subcmd_goals): + @subcmd="$(patsubst xcc-%,%,$(@))";\ + target="$(xcc_target) $${subcmd}";\ + $(call make_as_parent, -C $(xcc_build_dir) $${target}) + +PHONY += xcc-upgrade +xcc-upgrade: xcc + @$(MAKE) userclean + @$(MAKE) install-libs + @$(MAKE) testclean utestclean + @$(MAKE) tests utest + @$(call make_as_parent, apps-clean) + @$(call make_as_parent, apps-install) + @$(MAKE) fill-kfs + @$(MAKE) akaros-kernel + +PHONY += xcc-upgrade-from-scratch +xcc-upgrade-from-scratch: xcc-clean xcc-uninstall + @$(call make_as_parent, xcc-upgrade) + # Cleaning # ========================================================================= # This is mostly the Linux kernel cleaning. We could hook in to the userspace