Cleaned up some printking
[akaros.git] / Makefile
index c2aef64..5f7681f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,10 @@ MAKEFLAGS += -rR --no-print-directory
 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
@@ -185,68 +189,6 @@ export quiet Q KBUILD_VERBOSE
 $(srctree)/scripts/Kbuild.include: ;
 include $(srctree)/scripts/Kbuild.include
 
-# Akaros Build Environment
-# =========================================================================
-AKAROSINCLUDE   := -I$(srctree)/kern/include/
-
-# CROSS_COMPILE is defined per-arch.  Each arch can set other makeflags, kbuild
-# directories, etc. 
-include $(srctree)/kern/arch/$(ARCH)/Makefile
-
-CC         := $(CROSS_COMPILE)gcc 
-CPP        := $(CROSS_COMPILE)g++
-AS         := $(CROSS_COMPILE)as
-AR         := $(CROSS_COMPILE)ar
-LD         := $(CROSS_COMPILE)ld
-OBJCOPY        := $(CROSS_COMPILE)objcopy
-OBJDUMP        := $(CROSS_COMPILE)objdump
-NM         := $(CROSS_COMPILE)nm
-STRIP   := $(CROSS_COMPILE)strip
-
-ifeq ($(goals-has-build-targets),1)
-ifeq ($(shell which $(CROSS_COMPILE)gcc 2>/dev/null ),)
-$(error Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
-        Be sure to build the cross-compiler and update your PATH)
-endif
-# Computing these without a cross compiler complains loudly
-gcc-lib := $(shell $(CC) -print-libgcc-file-name)
-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
-XCC_TARGET_ROOT := $(dir $(shell which $(CC)))../$(patsubst %-,%,\
-                                                   $(CROSS_COMPILE))
-endif
-
-CFLAGS_KERNEL += -O2 -pipe -MD -gstabs
-CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
-CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
-CFLAGS_KERNEL += -fno-stack-protector
-CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused
-CFLAGS_KERNEL += -DROS_KERNEL 
-CFLAGS_KERNEL += -include include/generated/autoconf.h
-
-# TODO: do we need this, or can we rely on the compiler's defines?
-CFLAGS_KERNEL += -D$(ARCH)
-
-# TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
-# source of bugs/problems.
-# note we still pull in stdbool and stddef from the compiler
-CFLAGS_KERNEL += -fno-builtin
-
-AFLAGS_KERNEL := $(CFLAGS_KERNEL)
-
-KBUILD_BUILTIN := 1
-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 KBUILD_BUILTIN KBUILD_CHECKSRC
-
-CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline
-CXXFLAGS_USER += -O2
-
-export CFLAGS_USER CXXFLAGS_USER
-
 # Kbuild Target/Goals Parsing
 # =========================================================================
 # Need to figure out if we're a config or not, and whether or not to include
@@ -341,6 +283,74 @@ else
 include/config/auto.conf: ;
 endif # $(dot-config)
 
+# Akaros Build Environment
+# =========================================================================
+AKAROSINCLUDE   := -I$(srctree)/kern/include/
+
+# CROSS_COMPILE is defined per-arch.  Each arch can set other makeflags, kbuild
+# directories, etc. 
+-include $(srctree)/kern/arch/$(ARCH)/Makefile
+
+CC         := $(CROSS_COMPILE)gcc 
+CPP        := $(CROSS_COMPILE)g++
+AS         := $(CROSS_COMPILE)as
+AR         := $(CROSS_COMPILE)ar
+LD         := $(CROSS_COMPILE)ld
+OBJCOPY        := $(CROSS_COMPILE)objcopy
+OBJDUMP        := $(CROSS_COMPILE)objdump
+NM         := $(CROSS_COMPILE)nm
+STRIP   := $(CROSS_COMPILE)strip
+KERNEL_LD ?= kernel.ld
+
+# These may have bogus values if there is no compiler.  The kernel and user
+# build targets will check cc-exists.  Hopefully no cleaning targets rely on
+# these.  Note that if you change configs, these will get computed once, before
+# silentoldconfig kicks in to regenerate auto.conf, and these values will
+# temporarily be stale.
+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))
+
+CFLAGS_KERNEL += -O2 -pipe -MD
+CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
+CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
+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 -g
+else
+CFLAGS_KERNEL += -m32 -gstabs
+endif
+
+# TODO: do we need this, or can we rely on the compiler's defines?
+CFLAGS_KERNEL += -D$(ARCH)
+
+# TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
+# source of bugs/problems.
+# note we still pull in stdbool and stddef from the compiler
+CFLAGS_KERNEL += -fno-builtin
+
+AFLAGS_KERNEL := $(CFLAGS_KERNEL)
+
+KBUILD_BUILTIN := 1
+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 KBUILD_BUILTIN KBUILD_CHECKSRC
+
+CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline
+CXXFLAGS_USER += -O2
+
+export CFLAGS_USER CXXFLAGS_USER
+
 # Akaros include stuff (includes custom make targets and user overrides)
 # =========================================================================
 
@@ -357,7 +367,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
@@ -384,7 +394,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/ $(AKAROS_EXTERNAL_DIRS)
 arch-y += kern/arch/$(ARCH)/
 
 akaros-dirs     := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y)))
@@ -396,7 +406,7 @@ core-y          := $(patsubst %/, %/built-in.o, $(core-y))
 arch-y          := $(patsubst %/, %/built-in.o, $(arch-y))
 
 kbuild_akaros_main := $(core-y) $(arch-y)
-akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/kernel.ld
+akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/$(KERNEL_LD)
 
 kern_cpio := $(OBJDIR)/kern/initramfs.cpio
 kern_cpio_obj := $(kern_cpio).o
@@ -411,38 +421,83 @@ 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)
 
+# 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 $@ \
-                              $(akaros-deps) \
-                              $(gcc-lib) \
-                              $(kern_cpio_obj) \
-                              $(ext2_bdev_obj) ; \
-                              $(OBJDUMP) -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
@@ -456,10 +511,15 @@ $(sort $(akaros-deps)): $(akaros-dirs) ;
 
 # Recursively Kbuild all of our directories.  If we're changing arches
 # mid-make, we might have issues ( := on akaros-dirs, etc).
-PHONY += $(akaros-dirs)
-$(akaros-dirs): scripts symlinks
+PHONY += $(akaros-dirs) cc_exists
+$(akaros-dirs): scripts symlinks cc-exists
        $(Q)$(MAKE) $(build)=$@
 
+cc-exists:
+       @if [ "`which $(CROSS_COMPILE)gcc`" = "" ]; then echo \
+           Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
+           Be sure to build the cross-compiler and update your PATH; exit 1; fi
+
 $(CMP_KERNEL_OBJ): $(KERNEL_OBJ)
        @echo "Compressing kernel image"
        $(Q)gzip -c $^ > $@
@@ -480,11 +540,15 @@ 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 bsd
+benchutil: parlib
+pthread: parlib benchutil
+iplib: parlib
+ndblib: iplib
+bsd: parlib iplib
 
 PHONY += install-libs $(user-dirs)
-install-libs: $(user-dirs) symlinks
+install-libs: $(user-dirs) symlinks cc-exists
 
 $(user-dirs):
        @cd user/$@ && $(MAKE) && $(MAKE) install
@@ -492,7 +556,7 @@ $(user-dirs):
 
 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
@@ -501,24 +565,37 @@ tests/: tests
 tests: install-libs
        @$(MAKE) -f tests/Makefile
 
+PHONY += utest
+utest: $(user-dirs)
+       @cd user/$@ && $(MAKE) 
+
 testclean:
        @$(MAKE) -f tests/Makefile clean
 
+utestclean:
+       @cd user/utest && $(MAKE) clean
+
 # KFS related stuff
 PHONY += fill-kfs unfill-kfs
 XCC_SO_FILES = $(addprefix $(XCC_TARGET_ROOT)/lib/, *.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"
+       @cd user/utest && $(MAKE) uninstall
+       @echo "User space tests removed from KFS"
        @touch $(OBJDIR)/.dont-force-fill-kfs
 
 fill-kfs: $(OBJDIR)/.dont-force-fill-kfs install-libs
        @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"
+       @cd user/utest && $(MAKE) 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