| # Top-level Makefile for Akaros |
| # Barret Rhoden |
| # |
| # |
| # Notes: |
| # - I downloaded the kbuild guts from git://github.com/lacombar/kconfig.git, |
| # and added things from a recent linux makefile. It is from aug 2011, so |
| # some things might not match up. |
| # - Kernel output in obj/: So Linux has the ability to output into another |
| # directory, via the KBUILD_OUTPUT variable. This induces a recursive make |
| # in the output directory. I mucked with it for a little, but didn't get it |
| # to work quite right. Also, there will be other Akaros issues since this |
| # makefile is also used for userspace and tests. For now, I'm leaving things |
| # the default Linux way. |
| # - Kconfig wants to use include/ in the root directory. We can change some |
| # of the default settings that silentoldconfig uses, but I'll leave it as-is |
| # for now, and just symlink that into kern/include. It'll be easier for us, |
| # and also potentially easier if we ever move kern/ up a level. Similarly, |
| # there are default Kconfigs in arch/, not in kern/arch. I just symlinked |
| # arch->kern/arch to keep everything simple. |
| # |
| # TODO: |
| # - Consider merging the two target-detection bits (Linux's config, mixed, or |
| # dot target, and the symlink handling). Also, could consider moving around |
| # the KFS target. Clean doesn't need to know about it, for instance. |
| # |
| # - Review, with an eye for being better about $(srctree). It might only be |
| # necessary in this file, if we every do the KBUILD_OUTPUT option. But |
| # we don't always want it (like for the implicit rule for Makefile) |
| # |
| # - It's a bit crazy that we build symlinks for parlib, instead of it |
| # managing its own links based on $(ARCH) |
| # |
| # - Consider using Kbuild to build userspace and tests |
| # |
| # - There are a few other TODOs sprinkled throughout the makefile. |
| |
| # Number of make jobs to spawn. Can override this in Makelocal |
| MAKE_JOBS ?= $(shell expr `cat /proc/cpuinfo | grep processor | wc -l` - 1) |
| |
| # 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. |
| VERSION = 0 |
| PATCHLEVEL = 1 |
| SUBLEVEL = 0 |
| EXTRAVERSION = |
| VERNAME = Nanwan |
| |
| KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) |
| |
| export KERNELVERSION VERNAME |
| |
| 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 $$(awk 'BEGIN{for (v in ENVIRON){print v}}'); do unset $$c; done; |
| |
| define export_user_variables |
| CROSS_COMPILE="$(CROSS_COMPILE)"\ |
| CROSS_INCLUDE="$(XCC_TARGET_INCLUDE)"\ |
| ROS_CFLAGS="$(CFLAGS_USER)"\ |
| ROS_LDFLAGS="$(LDFLAGS_USER)" |
| endef |
| |
| # 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)\ |
| unset CC; \ |
| $(call export_user_variables)\ |
| $(MAKE) $(NO_PRINT_DIRECTORY) -j $(MAKE_JOBS) $(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) -j $(MAKE_JOBS) |
| |
| # 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 |
| |
| # Don't need to export these, since the Makelocal is included. |
| KERNEL_OBJ := $(OBJDIR)/kern/akaros-kernel |
| CMP_KERNEL_OBJ := $(KERNEL_OBJ).gz |
| |
| # Symlinks |
| # ========================================================================= |
| # We have a few symlinks so that code can include <arch/whatever.h>. This |
| # section builds and maintains those, as best we can. |
| # |
| # When invoking make, we can pass in ARCH=some-arch. This value gets 'saved' |
| # in the symlink, so that later invocations do not need ARCH=. If this value |
| # differs from the symlink, it appears like we are changing arches, which |
| # triggers a clean and symlink reconstruction. |
| # |
| # When the user changes from one arch to another, they ought to reconfig, since |
| # many of the CONFIG_ vars will depend on the arch. If they try anything other |
| # than one of the "non-build-goals" (cleans or configs), we'll abort. |
| # |
| # Make targets that need these symlinks (like building userspace, the kernel, |
| # configs, etc, should depend on symlinks. |
| |
| clean-goals := clean mrproper realclean userclean testclean doxyclean objclean |
| non-build-goals := %config $(clean-goals) |
| ifeq ($(filter $(non-build-goals), $(MAKECMDGOALS)),) |
| goals-has-build-targets := 1 |
| endif |
| |
| PHONY += symlinks clean_symlinks |
| clean_symlinks: objclean |
| @rm -f kern/include/arch kern/boot user/parlib/include/parlib/arch |
| |
| arch-link := $(notdir $(shell readlink kern/include/arch)) |
| valid-arches := $(notdir $(wildcard kern/arch/*)) |
| |
| ifneq ($(ARCH),) |
| ifeq ($(filter $(valid-arches), $(ARCH)),) |
| $(error ARCH $(ARCH) invalid, must be one of: $(valid-arches)) |
| endif |
| ifneq ($(ARCH),$(arch-link)) |
| ifeq ($(goals-has-build-targets),1) |
| $(error Attempted to make [$(MAKECMDGOALS)] while changing ARCH. \ |
| You need to make *config.) |
| endif |
| symlinks: clean_symlinks |
| @echo Making symlinks... |
| $(Q)ln -fs ../arch/$(ARCH) kern/include/arch |
| $(Q)ln -fs arch/$(ARCH)/boot kern/boot |
| $(Q)ln -fs $(ARCH) user/parlib/include/parlib/arch |
| $(Q)$(MAKE) -f $(srctree)/Makefile clean |
| |
| else |
| symlinks: |
| |
| endif # ifneq ($(ARCH),$(arch-link)) |
| else # $(ARCH) is empty |
| ifneq ($(arch-link),) |
| ARCH := $(arch-link) |
| symlinks: |
| |
| else |
| # Only allow a clean |
| ifeq ($(filter $(clean-goals), $(MAKECMDGOALS)),) |
| $(error No arch saved or specified. Make *config with ARCH=arch. \ |
| 'arch' must be one of: $(valid-arches)) |
| endif |
| ARCH := none # catch bugs |
| endif # ifneq ($(arch-link),) |
| endif # ifeq ($(ARCH),) |
| |
| SRCARCH := $(ARCH) |
| export ARCH SRCARCH |
| |
| # Generic Kbuild Environment |
| # ========================================================================= |
| |
| # To put more focus on warnings, be less verbose as default |
| # Use 'make V=1' to see the full commands |
| |
| ifeq ("$(origin V)", "command line") |
| KBUILD_VERBOSE = $(V) |
| endif |
| ifndef KBUILD_VERBOSE |
| KBUILD_VERBOSE = 0 |
| endif |
| |
| srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR)) |
| objtree := $(CURDIR) |
| |
| export srctree objtree |
| |
| CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ |
| else if [ -x /bin/bash ]; then echo /bin/bash; \ |
| else echo sh; fi ; fi) |
| |
| HOSTCC = gcc |
| HOSTCXX = g++ |
| HOSTCFLAGS = -Wall -Wno-char-subscripts -Wmissing-prototypes \ |
| -Wstrict-prototypes -O2 -fomit-frame-pointer |
| HOSTCXXFLAGS = -O2 |
| |
| export CONFIG_SHELL HOSTCC HOSTCXX HOSTCFLAGS HOSTCXXFLAGS |
| |
| # Beautify output |
| # --------------------------------------------------------------------------- |
| # |
| # Normally, we echo the whole command before executing it. By making |
| # that echo $($(quiet)$(cmd)), we now have the possibility to set |
| # $(quiet) to choose other forms of output instead, e.g. |
| # |
| # quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@ |
| # cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< |
| # |
| # If $(quiet) is empty, the whole command will be printed. |
| # If it is set to "quiet_", only the short version will be printed. |
| # If it is set to "silent_", nothing will be printed at all, since |
| # the variable $(silent_cmd_cc_o_c) doesn't exist. |
| # |
| # A simple variant is to prefix commands with $(Q) - that's useful |
| # for commands that shall be hidden in non-verbose mode. |
| # |
| # $(Q)ln $@ :< |
| # |
| # If KBUILD_VERBOSE equals 0 then the above command will be hidden. |
| # If KBUILD_VERBOSE equals 1 then the above command is displayed. |
| |
| ifeq ($(KBUILD_VERBOSE),1) |
| quiet = |
| Q = |
| else |
| quiet=quiet_ |
| Q = @ |
| endif |
| export quiet Q KBUILD_VERBOSE |
| |
| # We need some generic definitions (do not try to remake the file). |
| $(srctree)/scripts/Kbuild.include: ; |
| include $(srctree)/scripts/Kbuild.include |
| |
| # Kbuild Target/Goals Parsing |
| # ========================================================================= |
| # Need to figure out if we're a config or not, and whether or not to include |
| # our .config / auto.conf. Configs are basically their own makefile, (ifeq), |
| # and cleans are allowed to proceed without worrying about the dot-config. |
| |
| # Basic helpers built in scripts/ |
| PHONY += scripts_basic |
| scripts_basic: |
| $(Q)$(MAKE) $(build)=scripts/basic |
| |
| PHONY += scripts |
| |
| scripts: scripts_basic include/config/auto.conf include/config/tristate.conf |
| $(Q)$(MAKE) $(build)=$(@) |
| |
| config-targets := 0 |
| mixed-targets := 0 |
| dot-config := 1 |
| |
| no-dot-config-targets := $(clean-goals) |
| |
| ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) |
| ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) |
| dot-config := 0 |
| endif |
| endif |
| |
| ifneq ($(filter config %config,$(MAKECMDGOALS)),) |
| config-targets := 1 |
| ifneq ($(filter-out config %config,$(MAKECMDGOALS)),) |
| mixed-targets := 1 |
| endif |
| endif |
| |
| ifeq ($(mixed-targets),1) |
| # =========================================================================== |
| # We're called with mixed targets (*config and build targets). |
| # Handle them one by one. |
| |
| %:: FORCE |
| $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@ |
| |
| else |
| ifeq ($(config-targets),1) |
| # =========================================================================== |
| # *config targets only - make sure prerequisites are updated, and descend |
| # in scripts/kconfig to make the *config target |
| |
| # Default config file, per arch. This path will resolve to |
| # arch/$ARCH/configs/defconfig (arch -> kern/arch). Each arch can override |
| # this if they want, or just symlink to one in the main root directory. |
| KBUILD_DEFCONFIG := defconfig |
| export KBUILD_DEFCONFIG |
| |
| config: scripts_basic symlinks FORCE |
| $(Q)mkdir -p include/config |
| $(Q)$(MAKE) $(build)=scripts/kconfig $@ |
| |
| %config: scripts_basic symlinks FORCE |
| $(Q)mkdir -p include/config |
| $(Q)$(MAKE) $(build)=scripts/kconfig $@ |
| |
| else |
| # =========================================================================== |
| # Build targets only - this includes vmlinux, arch specific targets, clean |
| # targets and others. In general all targets except *config targets. |
| |
| ifeq ($(dot-config),1) |
| KCONFIG_CONFIG ?= .config |
| export KCONFIG_CONFIG |
| |
| # Read in config |
| -include include/config/auto.conf |
| |
| # Read in dependencies to all Kconfig* files, make sure to run |
| # oldconfig if changes are detected. |
| -include include/config/auto.conf.cmd |
| |
| # To avoid any implicit rule to kick in, define an empty command |
| $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; |
| |
| # If .config is newer than include/config/auto.conf, someone tinkered |
| # with it and forgot to run make oldconfig. |
| # if auto.conf.cmd is missing then we are probably in a cleaned tree so |
| # we execute the config step to be sure to catch updated Kconfig files |
| include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd |
| $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig |
| |
| else |
| # Dummy target needed, because used as prerequisite |
| 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 := $(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 |
| CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer |
| CFLAGS_KERNEL += -fno-stack-protector |
| CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused -Werror -Wreturn-type |
| CFLAGS_KERNEL += -DROS_KERNEL -D__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 |
| ifeq ($(CONFIG_BETTER_BACKTRACE),y) |
| CFLAGS_KERNEL += -fno-optimize-sibling-calls |
| 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 XCC_TARGET_LIB XCC_TARGET_INCLUDE |
| export KBUILD_BUILTIN KBUILD_CHECKSRC |
| |
| CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline \ |
| -Wsystem-headers -Werror -Wreturn-type |
| CXXFLAGS_USER += -O2 |
| CFLAGS_USER_LIBS += -fPIC -static -fno-omit-frame-pointer -g |
| |
| export CFLAGS_USER CXXFLAGS_USER CFLAGS_USER_LIBS |
| |
| # Akaros include stuff (includes custom make targets and user overrides) |
| # ========================================================================= |
| |
| # The user can override this, though it won't apply for any of the in-tree |
| # kernel build output. Right now, it's only passed down to tests/ |
| dummy-1 := $(shell mkdir -p $(OBJDIR)/kern/) |
| |
| # Since we're doing this outside of the dot-config part, some targets, such as |
| # clean, won't read in our .config/auto.conf, and won't know about the |
| # 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 := $(subst $\",,$(CONFIG_KFS_PATHS)) |
| ifeq ($(kfs-paths),) |
| kfs-paths := kern/kfs |
| endif |
| |
| FIRST_KFS_PATH = $(firstword $(kfs-paths)) |
| ABS_KFS_PATH = $(abspath $(FIRST_KFS_PATH)) |
| |
| export OBJDIR FIRST_KFS_PATH ABS_KFS_PATH |
| |
| # Avoiding implicit rules |
| $(srctree)/Makelocal: ; |
| # TODO: one issue is that we import all types of targets: build, clean, etc. |
| # That makes it a bit tougher to reorganize with ifeqs. |
| -include $(srctree)/Makelocal |
| |
| # Akaros Kernel Build |
| # ========================================================================= |
| # Add top level directories, either to an existing entry (core-y) or to its |
| # own. |
| # |
| # From these, we determine deps and dirs. We recursively make through the |
| # dirs, generating built-in.o at each step, which are the deps from which we |
| # link akaros. |
| # |
| # 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/ kern/lib/ $(AKAROS_EXTERNAL_DIRS) |
| arch-y += kern/arch/$(ARCH)/ |
| |
| akaros-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y))) |
| |
| all-arch-dirs := $(patsubst %,kern/arch/%/,$(valid-arches)) |
| akaros-all-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(all-arch-dirs))) |
| |
| 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) |
| |
| kern_cpio := $(OBJDIR)/kern/initramfs.cpio |
| kern_cpio_obj := $(kern_cpio).o |
| |
| # 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 -oAH newc -O $(CURDIR)/$(kern_cpio); \ |
| cd $$OLDPWD; \ |
| done; |
| |
| 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) $< $@ |
| |
| 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 |
| |
| $(ext2_bdev_obj): $(ext2-bdev) |
| $(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 = $(CONFIG_SHELL) scripts/link-kernel.sh $@ \ |
| kern/arch/$(ARCH)/$(KERNEL_LD) $(LDFLAGS_KERNEL) \ |
| --build-id=sha1 \ |
| $(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 |
| # complaints of $(targets), so that all is probably messed up). |
| $(KERNEL_OBJ): $(akaros-deps) $(kern_cpio_obj) $(ext2_bdev_obj) |
| $(call if_changed,link-akaros) |
| |
| akaros-kernel: $(KERNEL_OBJ) |
| |
| $(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) 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 $^ > $@ |
| |
| # TODO: not sure what all we want to have available for config targets |
| # (anything after this is allowed. We currently need clean targets available |
| # (config->symlinks->clean). |
| endif #ifeq ($(config-targets),1) |
| endif #ifeq ($(mixed-targets),1) |
| |
| # Akaros Userspace Building and Misc Helpers |
| # ========================================================================= |
| # Recursively make user libraries and tests. |
| # |
| # User library makefiles are built to expect to be called from their own |
| # directories. The test code can be called from the root directory. |
| |
| # List all userspace directories here, and state any dependencies between them, |
| # such as how pthread depends on parlib. |
| |
| # Critical libraries, also built during the toolchain install |
| user-base-dirs = parlib pthread benchutil iplib ndblib perfmon |
| benchutil: parlib |
| pthread: parlib benchutil |
| iplib: parlib |
| ndblib: iplib |
| |
| # Higher-level libraries. Built before tests/, but after apps-install. |
| # TODO: would like to move perfmon here, since it's not meant to be low-level. |
| # But the apps-install has perf, which depends on user/perfmon. |
| user-extra-dirs = vmm electric-fence |
| $(user-extra-dirs): $(user-base-dirs) |
| |
| user-dirs = $(user-base-dirs) $(user-extra-dirs) |
| |
| PHONY += install-base-libs $(user-dirs) |
| install-base-libs: $(user-base-dirs) symlinks cc-exists |
| |
| $(user-dirs): |
| @$(MAKE) -C user/$@ DEPLIBS="$^" && $(MAKE) -C user/$@ install |
| |
| PHONY += user |
| user: $(user-dirs) |
| |
| PHONY += userclean $(clean-user-dirs) |
| clean-user-dirs := $(addprefix _clean_user_,$(user-dirs)) |
| userclean: $(clean-user-dirs) testclean utestclean |
| |
| $(clean-user-dirs): |
| @$(MAKE) -C user/$(patsubst _clean_user_%,%,$@) clean |
| |
| tests/: tests |
| tests: user |
| @$(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-gcc-libs = $(XCC_TARGET_ROOT)/../lib/ |
| xcc-so-files = $(addprefix $(XCC_TARGET_LIB), *.so*) \ |
| $(addprefix $(xcc-gcc-libs), *.so*) |
| |
| $(OBJDIR)/.dont-force-fill-kfs: |
| $(Q)rm -rf $(addprefix $(FIRST_KFS_PATH)/lib/, $(notdir $(xcc-so-files))) |
| @echo "Cross Compiler 'so' files removed from 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 user tests |
| @mkdir -p $(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 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 |
| docs: |
| @echo " Making doxygen" |
| @doxygen-dir=$(doxygen-dir) doxygen $(doxygen-dir)/rosdoc.cfg |
| @if [ ! -d $(doxygen-dir)/rosdoc/html/img ]; \ |
| then \ |
| ln -s ../../img $(doxygen-dir)/rosdoc/html; \ |
| fi |
| |
| doxyclean: |
| @echo + clean [ROSDOC] |
| @rm -rf $(doxygen-dir)/rosdoc |
| |
| objclean: |
| @echo + clean [OBJDIR] |
| @rm -rf $(OBJDIR) |
| |
| realclean: userclean mrproper doxyclean objclean |
| |
| # Bundled apps |
| # ========================================================================= |
| |
| app-dirs = |
| tagged-app-dirs := $(subst /,__,$(app-dirs)) |
| app-dirs-install := $(addprefix _install_,$(tagged-app-dirs)) |
| app-dirs-clean := $(addprefix _clean_,$(tagged-app-dirs)) |
| |
| PHONY += $(app-dirs-install) $(app-dirs-clean) |
| |
| $(app-dirs-install): |
| @$(MAKE) -C $(patsubst _install_%,%,$(subst __,/,$@)) install |
| |
| $(app-dirs-clean): |
| @$(MAKE) -C $(patsubst _clean_%,%,$(subst __,/,$@)) clean |
| |
| PHONY += apps-install |
| apps-install: $(app-dirs-install) |
| @$(shell mkdir -p $(AKAROS_ROOT)/build_logs) |
| @$(call make_as_parent, -C tools/apps/busybox) > build_logs/busybox_install.log 2>&1 |
| @echo busybox install succeeded. |
| @$(call make_as_parent, -C tools/apps/ipconfig install) > build_logs/ipconfig_install.log 2>&1 |
| @echo ipconfig install succeeded. |
| @$(call make_as_parent, -C tools/dev-libs/elfutils install) > build_logs/elfutils_install.log 2>&1 |
| @echo elfutils install succeeded. |
| @$(call make_as_parent, -C tools/dev-util/perf install) > build_logs/perf_install.log 2>&1 |
| @echo perf install succeeded. |
| @$(call make_as_parent, -C tools/sys-apps/bash install) > build_logs/bash_install.log 2>&1 |
| @echo bash install succeeded. |
| @$(call make_as_parent, -C tools/sys-apps/grep install) > build_logs/grep_install.log 2>&1 |
| @echo grep install succeeded. |
| |
| PHONY += apps-clean |
| apps-clean: $(app-dirs-clean) |
| @$(shell mkdir -p $(AKAROS_ROOT)/build_logs) |
| @$(call make_as_parent, -C tools/apps/busybox clean) > build_logs/busybox_clean.log 2>&1 |
| @echo busybox clean succeeded. |
| @$(call make_as_parent, -C tools/apps/ipconfig clean) > build_logs/ipconfig_clean.log 2>&1 |
| @echo ipconfig clean succeeded. |
| @$(call make_as_parent, -C tools/dev-libs/elfutils clean) > build_logs/elfutils_clean.log 2>&1 |
| @echo elfutils clean succeeded. |
| @$(call make_as_parent, -C tools/dev-util/perf clean) > build_logs/perf_clean.log 2>&1 |
| @echo perf clean succeeded. |
| @$(call make_as_parent, -C tools/sys-apps/bash clean) > build_logs/bash_clean.log 2>&1 |
| @echo bash clean succeeded. |
| @$(call make_as_parent, -C tools/sys-apps/grep clean) > build_logs/grep_clean.log 2>&1 |
| @echo grep clean succeeded. |
| |
| # 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-base-libs |
| @$(MAKE) testclean utestclean |
| @$(call make_as_parent, apps-clean) |
| @$(call make_as_parent, apps-install) |
| @$(MAKE) tests utest |
| @$(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 |
| # cleaning with the 'userclean' target attached to clean, though historically |
| # 'clean' means the kernel. |
| |
| # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir |
| # Usage: |
| # $(Q)$(MAKE) $(clean)=dir |
| clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj |
| |
| # clean - Delete all generated files |
| # |
| clean-dirs := $(addprefix _clean_,$(akaros-all-dirs)) |
| |
| PHONY += $(clean-dirs) clean |
| $(clean-dirs): |
| $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) |
| |
| RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \ |
| -o -name .pc -o -name .hg -o -name .git \) -prune -o |
| clean: $(clean-dirs) |
| @find $(patsubst _clean_%,%,$(clean-dirs)) $(RCS_FIND_IGNORE) \ |
| \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ |
| -o -name '*.ko.*' \ |
| -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ |
| -o -name '*.symtypes' -o -name 'modules.order' \ |
| -o -name modules.builtin -o -name '.tmp_*.o.*' \ |
| -o -name '*.gcno' \) -type f -print | xargs rm -f |
| |
| # Could add in an archclean if we need arch-specific cleanup, or a userclean if |
| # we want to start cleaning that too. |
| #clean: archclean |
| #clean: userclean |
| |
| # mrproper - Delete all generated files, including .config, and reset ARCH |
| # |
| mrproper-dirs := $(addprefix _mrproper_,scripts) |
| |
| PHONY += $(mrproper-dirs) mrproper |
| $(mrproper-dirs): |
| $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) |
| |
| mrproper: $(mrproper-dirs) clean clean_symlinks |
| @-rm -f .config |
| @find $(patsubst _mrproper_%,%,$(mrproper-dirs)) $(RCS_FIND_IGNORE) \ |
| \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ |
| -o -name '*.ko.*' \ |
| -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ |
| -o -name '*.symtypes' -o -name 'modules.order' \ |
| -o -name modules.builtin -o -name '.tmp_*.o.*' \ |
| -o -name '*.gcno' \) -type f -print | xargs rm -f |
| |
| # Epilogue |
| # ========================================================================= |
| |
| PHONY += FORCE |
| FORCE: |
| |
| # Don't put the srctree on this, make is looking for Makefile, not |
| # /full/path/to/Makefile. |
| Makefile: ; # avoid implicit rule on Makefile |
| |
| # Declare the contents of the .PHONY variable as phony. We keep that |
| # information in a variable so we can use it in if_changed and friends. |
| .PHONY: $(PHONY) |