$(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
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
+ifeq ($(CONFIG_64BIT),y)
+CFLAGS_KERNEL += -m64
+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)
# =========================================================================
# 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
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
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
# 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 $^ > $@
pthread: parlib
PHONY += install-libs $(user-dirs)
-install-libs: $(user-dirs) symlinks
+install-libs: $(user-dirs) symlinks cc-exists
$(user-dirs):
@cd user/$@ && $(MAKE) && $(MAKE) install
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
@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