akaros/Makefile
<<
>>
Prefs
   1# Top-level Makefile for Akaros
   2# Barret Rhoden
   3#
   4#
   5# Notes:
   6#       - I downloaded the kbuild guts from git://github.com/lacombar/kconfig.git,
   7#       and added things from a recent linux makefile.  It is from aug 2011, so
   8#       some things might not match up.
   9#       - Kernel output in obj/: So Linux has the ability to output into another
  10#       directory, via the KBUILD_OUTPUT variable.  This induces a recursive make
  11#       in the output directory.  I mucked with it for a little, but didn't get it
  12#       to work quite right.  Also, there will be other Akaros issues since this
  13#       makefile is also used for userspace and tests.  For now, I'm leaving things
  14#       the default Linux way.
  15#       - Kconfig wants to use include/ in the root directory.  We can change some
  16#       of the default settings that silentoldconfig uses, but I'll leave it as-is
  17#       for now, and just symlink that into kern/include.  It'll be easier for us,
  18#       and also potentially easier if we ever move kern/ up a level.  Similarly,
  19#       there are default Kconfigs in arch/, not in kern/arch.  I just symlinked
  20#       arch->kern/arch to keep everything simple.
  21#
  22# TODO:
  23#       - Consider merging the two target-detection bits (Linux's config, mixed, or
  24#       dot target, and the symlink handling).  Also, could consider moving around
  25#       the KFS target.  Clean doesn't need to know about it, for instance.
  26#
  27#       - Review, with an eye for being better about $(srctree).  It might only be
  28#       necessary in this file, if we every do the KBUILD_OUTPUT option.  But we
  29#       don't always want it (like for the implicit rule for Makefile)
  30#
  31#       - It's a bit crazy that we build symlinks for parlib, instead of it
  32#       managing its own links based on $(ARCH)
  33#
  34#       - Consider using Kbuild to build userspace and tests
  35#
  36#       - There are a few other TODOs sprinkled throughout the makefile.
  37
  38# Number of make jobs to spawn.  Can override this in Makelocal
  39MAKE_JOBS ?= $(shell expr `cat /proc/cpuinfo | grep processor | wc -l` - 1)
  40
  41# Allow people to override our setting of the --no-print-directory option in
  42# their Makelocal. This is useful, for example, to allow emacs to find the
  43# correct file when errors are encountered using its builtin 'M-x compile'
  44# command.
  45VERSION = 0
  46PATCHLEVEL = 1
  47SUBLEVEL = 0
  48EXTRAVERSION =
  49VERNAME = Nanwan
  50
  51KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
  52
  53export KERNELVERSION VERNAME
  54
  55NO_PRINT_DIRECTORY ?= --no-print-directory
  56
  57# Save the ability to export the parent's original environment for future use
  58export_parent_env := $(shell export | sed 's/$$/;/')
  59
  60# Save the ability to clear the current environment for future use
  61clear_current_env := for c in $$(awk 'BEGIN{for (v in ENVIRON){print v}}'); do unset $$c; done;
  62
  63define export_user_variables
  64        CROSS_COMPILE="$(CROSS_COMPILE)"\
  65        CROSS_INCLUDE="$(XCC_TARGET_INCLUDE)"\
  66        ROS_CFLAGS="$(CFLAGS_USER)"\
  67        ROS_LDFLAGS="$(LDFLAGS_USER)"
  68endef
  69
  70# Define a set of commands to reset the environment to the parent's environment
  71# and then run a local make target
  72define make_as_parent
  73        $(clear_current_env)\
  74        $(export_parent_env)\
  75        unset CC; \
  76        $(call export_user_variables)\
  77        $(MAKE) $(NO_PRINT_DIRECTORY) -j $(MAKE_JOBS) $(1)
  78endef
  79
  80# Do not:
  81# o  use make's built-in rules and variables
  82#    (this increases performance and avoids hard-to-debug behaviour);
  83# o  print "Entering directory ...";
  84MAKEFLAGS += -rR $(NO_PRINT_DIRECTORY) -j $(MAKE_JOBS)
  85
  86# That's our default target when none is given on the command line
  87# This can be overriden with a Makelocal
  88PHONY := all
  89all: akaros-kernel
  90
  91# Export the location of this top level directory
  92AKAROS_ROOT = $(CURDIR)
  93export AKAROS_ROOT
  94
  95# Setup dumping ground for object files and any temporary files we need to
  96# generate for non-kbuild targets
  97OBJDIR ?= obj
  98
  99# Don't need to export these, since the Makelocal is included.
 100KERNEL_OBJ := $(OBJDIR)/kern/akaros-kernel
 101CMP_KERNEL_OBJ := $(KERNEL_OBJ).gz
 102
 103# Symlinks
 104# =========================================================================
 105# We have a few symlinks so that code can include <arch/whatever.h>.  This
 106# section builds and maintains those, as best we can.
 107#
 108# When invoking make, we can pass in ARCH=some-arch.  This value gets 'saved'
 109# in the symlink, so that later invocations do not need ARCH=.  If this value
 110# differs from the symlink, it appears like we are changing arches, which
 111# triggers a clean and symlink reconstruction.
 112#
 113# When the user changes from one arch to another, they ought to reconfig, since
 114# many of the CONFIG_ vars will depend on the arch.  If they try anything other
 115# than one of the "non-build-goals" (cleans or configs), we'll abort.
 116#
 117# Make targets that need these symlinks (like building userspace, the kernel,
 118# configs, etc, should depend on symlinks.
 119
 120clean-goals := clean mrproper realclean userclean testclean doxyclean objclean
 121non-build-goals := %config $(clean-goals)
 122ifeq ($(filter $(non-build-goals), $(MAKECMDGOALS)),)
 123goals-has-build-targets := 1
 124endif
 125
 126PHONY += symlinks clean_symlinks
 127clean_symlinks: objclean
 128        @rm -f kern/include/arch kern/boot user/parlib/include/parlib/arch
 129
 130arch-link := $(notdir $(shell readlink kern/include/arch))
 131valid-arches := $(notdir $(wildcard kern/arch/*))
 132
 133ifneq ($(ARCH),)
 134    ifeq ($(filter $(valid-arches), $(ARCH)),)
 135        $(error ARCH $(ARCH) invalid, must be one of: $(valid-arches))
 136    endif
 137    ifneq ($(ARCH),$(arch-link))
 138        ifeq ($(goals-has-build-targets),1)
 139            $(error Attempted to make [$(MAKECMDGOALS)] while changing ARCH. \
 140                    You need to make *config.)
 141        endif
 142symlinks: clean_symlinks
 143        @echo Making symlinks...
 144        $(Q)ln -fs ../arch/$(ARCH) kern/include/arch
 145        $(Q)ln -fs arch/$(ARCH)/boot kern/boot
 146        $(Q)ln -fs $(ARCH) user/parlib/include/parlib/arch
 147        $(Q)$(MAKE) -f $(srctree)/Makefile clean
 148
 149    else
 150symlinks:
 151
 152    endif # ifneq ($(ARCH),$(arch-link))
 153else # $(ARCH) is empty
 154    ifneq ($(arch-link),)
 155        ARCH := $(arch-link)
 156symlinks:
 157
 158    else
 159        # Only allow a clean
 160        ifeq ($(filter $(clean-goals), $(MAKECMDGOALS)),)
 161            $(error No arch saved or specified.  Make *config with ARCH=arch. \
 162                    'arch' must be one of: $(valid-arches))
 163        endif
 164        ARCH := none # catch bugs
 165    endif # ifneq ($(arch-link),)
 166endif # ifeq ($(ARCH),)
 167
 168SRCARCH := $(ARCH)
 169export ARCH SRCARCH
 170
 171# Generic Kbuild Environment
 172# =========================================================================
 173
 174# To put more focus on warnings, be less verbose as default
 175# Use 'make V=1' to see the full commands
 176
 177ifeq ("$(origin V)", "command line")
 178  KBUILD_VERBOSE = $(V)
 179endif
 180ifndef KBUILD_VERBOSE
 181  KBUILD_VERBOSE = 0
 182endif
 183
 184srctree         := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
 185objtree         := $(CURDIR)
 186
 187export srctree objtree
 188
 189CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 190          else if [ -x /bin/bash ]; then echo /bin/bash; \
 191          else echo sh; fi ; fi)
 192
 193HOSTCC       = gcc
 194HOSTCXX      = g++
 195HOSTCFLAGS   = -Wall -Wno-char-subscripts -Wmissing-prototypes \
 196               -Wstrict-prototypes -O2 -fomit-frame-pointer
 197HOSTCXXFLAGS = -O2
 198
 199export CONFIG_SHELL HOSTCC HOSTCXX HOSTCFLAGS HOSTCXXFLAGS
 200
 201# Beautify output
 202# ---------------------------------------------------------------------------
 203#
 204# Normally, we echo the whole command before executing it. By making
 205# that echo $($(quiet)$(cmd)), we now have the possibility to set
 206# $(quiet) to choose other forms of output instead, e.g.
 207#
 208#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
 209#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
 210#
 211# If $(quiet) is empty, the whole command will be printed.
 212# If it is set to "quiet_", only the short version will be printed.
 213# If it is set to "silent_", nothing will be printed at all, since
 214# the variable $(silent_cmd_cc_o_c) doesn't exist.
 215#
 216# A simple variant is to prefix commands with $(Q) - that's useful
 217# for commands that shall be hidden in non-verbose mode.
 218#
 219#       $(Q)ln $@ :<
 220#
 221# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
 222# If KBUILD_VERBOSE equals 1 then the above command is displayed.
 223
 224ifeq ($(KBUILD_VERBOSE),1)
 225  quiet =
 226  Q =
 227else
 228  quiet=quiet_
 229  Q = @
 230endif
 231export quiet Q KBUILD_VERBOSE
 232
 233# We need some generic definitions (do not try to remake the file).
 234$(srctree)/scripts/Kbuild.include: ;
 235include $(srctree)/scripts/Kbuild.include
 236
 237# Kbuild Target/Goals Parsing
 238# =========================================================================
 239# Need to figure out if we're a config or not, and whether or not to include
 240# our .config / auto.conf.  Configs are basically their own makefile, (ifeq),
 241# and cleans are allowed to proceed without worrying about the dot-config.
 242
 243# Basic helpers built in scripts/
 244PHONY += scripts_basic
 245scripts_basic:
 246        $(Q)$(MAKE) $(build)=scripts/basic
 247
 248PHONY += scripts
 249
 250scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
 251        $(Q)$(MAKE) $(build)=$(@)
 252
 253config-targets := 0
 254mixed-targets  := 0
 255dot-config     := 1
 256
 257no-dot-config-targets := $(clean-goals)
 258
 259ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
 260    ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
 261        dot-config := 0
 262    endif
 263endif
 264
 265ifneq ($(filter config %config,$(MAKECMDGOALS)),)
 266    config-targets := 1
 267    ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
 268        mixed-targets := 1
 269    endif
 270endif
 271
 272ifeq ($(mixed-targets),1)
 273# ===========================================================================
 274# We're called with mixed targets (*config and build targets).
 275# Handle them one by one.
 276
 277%:: FORCE
 278        $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
 279
 280else
 281ifeq ($(config-targets),1)
 282# ===========================================================================
 283# *config targets only - make sure prerequisites are updated, and descend
 284# in scripts/kconfig to make the *config target
 285
 286# Default config file, per arch.  This path will resolve to
 287# arch/$ARCH/configs/defconfig (arch -> kern/arch).  Each arch can override
 288# this if they want, or just symlink to one in the main root directory.
 289KBUILD_DEFCONFIG := defconfig
 290export KBUILD_DEFCONFIG
 291
 292config: scripts_basic symlinks FORCE
 293        $(Q)mkdir -p include/config
 294        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 295
 296%config: scripts_basic symlinks FORCE
 297        $(Q)mkdir -p include/config
 298        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 299
 300else
 301# ===========================================================================
 302# Build targets only - this includes vmlinux, arch specific targets, clean
 303# targets and others. In general all targets except *config targets.
 304
 305ifeq ($(dot-config),1)
 306KCONFIG_CONFIG ?= .config
 307export KCONFIG_CONFIG
 308
 309# Read in config
 310-include include/config/auto.conf
 311
 312# Read in dependencies to all Kconfig* files, make sure to run
 313# oldconfig if changes are detected.
 314-include include/config/auto.conf.cmd
 315
 316# To avoid any implicit rule to kick in, define an empty command
 317$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
 318
 319# If .config is newer than include/config/auto.conf, someone tinkered
 320# with it and forgot to run make oldconfig.
 321# if auto.conf.cmd is missing then we are probably in a cleaned tree so
 322# we execute the config step to be sure to catch updated Kconfig files
 323include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
 324        $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 325
 326else
 327# Dummy target needed, because used as prerequisite
 328include/config/auto.conf: ;
 329endif # $(dot-config)
 330
 331# Akaros Build Environment
 332# =========================================================================
 333AKAROSINCLUDE   := -I$(srctree)/kern/include/
 334
 335# CROSS_COMPILE is defined per-arch.  Each arch can set other makeflags, kbuild
 336# directories, etc.
 337-include $(srctree)/kern/arch/$(ARCH)/Makefile
 338
 339CC          := $(CROSS_COMPILE)gcc
 340CPP         := $(CROSS_COMPILE)g++
 341AS          := $(CROSS_COMPILE)as
 342AR          := $(CROSS_COMPILE)ar
 343LD          := $(CROSS_COMPILE)ld
 344OBJCOPY := $(CROSS_COMPILE)objcopy
 345OBJDUMP := $(CROSS_COMPILE)objdump
 346NM          := $(CROSS_COMPILE)nm
 347STRIP   := $(CROSS_COMPILE)strip
 348KERNEL_LD ?= kernel.ld
 349
 350# These may have bogus values if there is no compiler.  The kernel and user
 351# build targets will check cc-exists.  Hopefully no cleaning targets rely on
 352# these.  Note that if you change configs, these will get computed once, before
 353# silentoldconfig kicks in to regenerate auto.conf, and these values will
 354# temporarily be stale.
 355gcc-lib := $(shell $(CC) -print-libgcc-file-name 2>/dev/null)
 356NOSTDINC_FLAGS += -nostdinc -isystem \
 357                  $(shell $(CC) -print-file-name=include 2>/dev/null)
 358XCC_TARGET_ROOT := $(shell $(CC) --print-sysroot 2> /dev/null)
 359XCC_TARGET_LIB := $(XCC_TARGET_ROOT)/usr/lib/
 360XCC_TARGET_INCLUDE := $(XCC_TARGET_ROOT)/usr/include/
 361
 362CFLAGS_KERNEL += -O2 -pipe -MD
 363CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
 364CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
 365CFLAGS_KERNEL += -fno-stack-protector
 366CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused -Werror -Wreturn-type
 367CFLAGS_KERNEL += -DROS_KERNEL -D__KERNEL__
 368CFLAGS_KERNEL += -include include/generated/autoconf.h -include include/common.h
 369CFLAGS_KERNEL += -fplan9-extensions
 370ifeq ($(CONFIG_64BIT),y)
 371CFLAGS_KERNEL += -m64 -g
 372else
 373CFLAGS_KERNEL += -m32 -gstabs
 374endif
 375ifeq ($(CONFIG_BETTER_BACKTRACE),y)
 376CFLAGS_KERNEL += -fno-optimize-sibling-calls
 377endif
 378
 379# TODO: do we need this, or can we rely on the compiler's defines?
 380CFLAGS_KERNEL += -D$(ARCH)
 381
 382# TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
 383# source of bugs/problems.
 384# note we still pull in stdbool and stddef from the compiler
 385CFLAGS_KERNEL += -fno-builtin
 386
 387AFLAGS_KERNEL := $(CFLAGS_KERNEL)
 388
 389KBUILD_BUILTIN := 1
 390KBUILD_CHECKSRC := 0
 391
 392export AKAROSINCLUDE CROSS_COMPILE
 393export CC CPP AS AR LD OBJCOPY OBJDUMP NM STRIP
 394export CFLAGS_KERNEL AFLAGS_KERNEL
 395export NOSTDINC_FLAGS XCC_TARGET_ROOT XCC_TARGET_LIB XCC_TARGET_INCLUDE
 396export KBUILD_BUILTIN KBUILD_CHECKSRC
 397
 398CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline \
 399               -Wsystem-headers -Werror -Wreturn-type
 400CXXFLAGS_USER += -O2
 401CFLAGS_USER_LIBS += -fPIC -static -fno-omit-frame-pointer -g
 402
 403export CFLAGS_USER CXXFLAGS_USER CFLAGS_USER_LIBS
 404
 405# Akaros include stuff (includes custom make targets and user overrides)
 406# =========================================================================
 407
 408# The user can override this, though it won't apply for any of the in-tree
 409# kernel build output.  Right now, it's only passed down to tests/
 410dummy-1 := $(shell mkdir -p $(OBJDIR)/kern/)
 411
 412# Since we're doing this outside of the dot-config part, some targets, such as
 413# clean, won't read in our .config/auto.conf, and won't know about the
 414# KFS_PATH.  Future rules related to KFS will have issues (mkdir with no
 415# argument, or a find of the entire pwd).  It's also possible someone provided
 416# an empty path.  To deal with both, we'll just have a sensible default.
 417kfs-paths :=  $(subst $\",,$(CONFIG_KFS_PATHS))
 418ifeq ($(kfs-paths),)
 419kfs-paths := kern/kfs
 420endif
 421
 422FIRST_KFS_PATH = $(firstword $(kfs-paths))
 423ABS_KFS_PATH = $(abspath $(FIRST_KFS_PATH))
 424
 425export OBJDIR FIRST_KFS_PATH ABS_KFS_PATH
 426
 427# Avoiding implicit rules
 428$(srctree)/Makelocal: ;
 429# TODO: one issue is that we import all types of targets: build, clean, etc.
 430# That makes it a bit tougher to reorganize with ifeqs.
 431-include $(srctree)/Makelocal
 432
 433# Akaros Kernel Build
 434# =========================================================================
 435# Add top level directories, either to an existing entry (core-y) or to its
 436# own.
 437#
 438# From these, we determine deps and dirs.  We recursively make through the
 439# dirs, generating built-in.o at each step, which are the deps from which we
 440# link akaros.
 441#
 442# We have all-arch-dirs and all-dirs, so that we can still clean even without
 443# an arch symlink.
 444
 445core-y += kern/src/ kern/drivers/ kern/lib/ $(AKAROS_EXTERNAL_DIRS)
 446arch-y += kern/arch/$(ARCH)/
 447
 448akaros-dirs     := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y)))
 449
 450all-arch-dirs   := $(patsubst %,kern/arch/%/,$(valid-arches))
 451akaros-all-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(all-arch-dirs)))
 452
 453core-y          := $(patsubst %/, %/built-in.o, $(core-y))
 454arch-y          := $(patsubst %/, %/built-in.o, $(arch-y))
 455
 456kbuild_akaros_main := $(core-y) $(arch-y)
 457akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/$(KERNEL_LD)
 458
 459kern_cpio := $(OBJDIR)/kern/initramfs.cpio
 460kern_cpio_obj := $(kern_cpio).o
 461
 462# a bit hacky: we want to make sure the directories exist, and error out
 463# otherwise.  we also want to error out before the initramfs target, otherwise
 464# we might not get the error (if initramfs files are all up to date).  the
 465# trickiest thing here is that kfs-paths-check could be stale and require an
 466# oldconfig.  running make twice should suffice.
 467kfs-paths-check := $(shell for i in $(kfs-paths); do \
 468                               if [ ! -d "$$i" ]; then \
 469                                   echo "Can't find KFS directory $$i"; \
 470                                       $(MAKE) -f $(srctree)/Makefile \
 471                                                                           silentoldconfig > /dev/null; \
 472                                   exit -1; \
 473                               fi; \
 474                           done; echo "ok")
 475
 476ifneq (ok,$(kfs-paths-check))
 477$(error $(kfs-paths-check), try make one more time in case of stale configs)
 478endif
 479
 480kern_initramfs_files := $(shell find $(kfs-paths))
 481
 482# Need to make an empty cpio, then append each kfs-path's contents
 483$(kern_cpio) initramfs: $(kern_initramfs_files)
 484        @echo "  Building initramfs:"
 485        @if [ "$(CONFIG_KFS_CPIO_BIN)" != "" ]; then \
 486        sh $(CONFIG_KFS_CPIO_BIN); \
 487    fi
 488        @cat /dev/null | cpio --quiet -oH newc -O $(kern_cpio)
 489        $(Q)for i in $(kfs-paths); do cd $$i; \
 490        echo "    Adding $$i to initramfs..."; \
 491        find -L . | cpio --quiet -oAH newc -O $(CURDIR)/$(kern_cpio); \
 492        cd $$OLDPWD; \
 493    done;
 494
 495ld_emulation = $(shell $(OBJDUMP) -i 2>/dev/null | \
 496                       grep -v BFD | grep ^[a-z] | head -n1)
 497ld_arch = $(shell $(OBJDUMP) -i 2>/dev/null |\
 498                  grep -v BFD | grep "^  [a-z]" | head -n1)
 499
 500# Our makefile doesn't detect a change in subarch, and old binary objects that
 501# don't need to be updated won't get rebuilt, but they also can't link with the
 502# new subarch (32 bit vs 64 bit).  If we detect the wrong type, we'll force a
 503# rebuild.
 504existing-cpio-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \
 505                        grep format | sed 's/.*format //g')
 506ifneq ($(existing-cpio-emul),)
 507ifneq ($(existing-cpio-emul),$(ld_emulation))
 508$(kern_cpio_obj): cpio-rebuild
 509cpio-rebuild:
 510        $(Q)rm $(kern_cpio_obj)
 511endif
 512endif
 513
 514$(kern_cpio_obj): $(kern_cpio)
 515        $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@
 516
 517existing-ext2b-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \
 518                         grep format | sed 's/.*format //g')
 519ifneq ($(existing-ext2b-emul),)
 520ifneq ($(existing-ext2b-emul),$(ld_emulation))
 521$(ext2_bdev_obj): ext2b-rebuild
 522ext2b-rebuild:
 523        $(Q)rm $(ext2_bdev_obj)
 524endif
 525endif
 526
 527$(ext2_bdev_obj): $(ext2-bdev)
 528        $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@
 529
 530# Not the worlds most elegant link command.  link-kernel takes the obj output
 531# name, then the linker script, then everything else you'd dump on the ld
 532# command line, including linker options and objects to link together.
 533#
 534# After the script is done, we run the arch-specific command directly.
 535quiet_cmd_link-akaros = LINK    $@
 536      cmd_link-akaros = $(CONFIG_SHELL) scripts/link-kernel.sh $@ \
 537                        kern/arch/$(ARCH)/$(KERNEL_LD) $(LDFLAGS_KERNEL) \
 538                        --build-id=sha1 \
 539                        $(akaros-deps) $(gcc-lib) $(kern_cpio_obj) \
 540                        $(ext2_bdev_obj); \
 541                        $(ARCH_POST_LINK_CMD)
 542
 543# For some reason, the if_changed doesn't work with FORCE (like it does in
 544# Linux).  It looks like it can't find the .cmd file or something (also
 545# complaints of $(targets), so that all is probably messed up).
 546$(KERNEL_OBJ): $(akaros-deps) $(kern_cpio_obj) $(ext2_bdev_obj)
 547        $(call if_changed,link-akaros)
 548
 549akaros-kernel: $(KERNEL_OBJ)
 550
 551$(sort $(akaros-deps)): $(akaros-dirs) ;
 552
 553# Recursively Kbuild all of our directories.  If we're changing arches
 554# mid-make, we might have issues ( := on akaros-dirs, etc).
 555PHONY += $(akaros-dirs) cc_exists
 556$(akaros-dirs): scripts symlinks cc-exists
 557        $(Q)$(MAKE) $(build)=$@
 558
 559cc-exists:
 560        @if [ "`which $(CROSS_COMPILE)gcc`" = "" ]; then echo \
 561            Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
 562            Be sure to build the cross-compiler and update your PATH; exit 1; fi
 563
 564$(CMP_KERNEL_OBJ): $(KERNEL_OBJ)
 565        @echo "Compressing kernel image"
 566        $(Q)gzip -c $^ > $@
 567
 568# TODO: not sure what all we want to have available for config targets
 569# (anything after this is allowed.  We currently need clean targets available
 570# (config->symlinks->clean).
 571endif #ifeq ($(config-targets),1)
 572endif #ifeq ($(mixed-targets),1)
 573
 574# Akaros Userspace Building and Misc Helpers
 575# =========================================================================
 576# Recursively make user libraries and tests.
 577#
 578# User library makefiles are built to expect to be called from their own
 579# directories.  The test code can be called from the root directory.
 580
 581# List all userspace directories here, and state any dependencies between them,
 582# such as how pthread depends on parlib.
 583
 584# Critical libraries, also built during the toolchain install
 585user-base-dirs = parlib pthread benchutil iplib ndblib perfmon
 586benchutil: parlib
 587pthread: parlib benchutil
 588iplib: parlib
 589ndblib: iplib
 590
 591# Higher-level libraries.  Built before tests/, but after apps-install.
 592# TODO: would like to move perfmon here, since it's not meant to be low-level.
 593# But the apps-install has perf, which depends on user/perfmon.
 594user-extra-dirs = vmm electric-fence
 595$(user-extra-dirs): $(user-base-dirs)
 596
 597user-dirs = $(user-base-dirs) $(user-extra-dirs)
 598
 599PHONY += install-base-libs $(user-dirs)
 600install-base-libs: $(user-base-dirs) symlinks cc-exists
 601
 602$(user-dirs):
 603        @$(MAKE) -C user/$@ DEPLIBS="$^" && $(MAKE) -C user/$@ install
 604
 605PHONY += user
 606user: $(user-dirs)
 607
 608PHONY += userclean $(clean-user-dirs)
 609clean-user-dirs := $(addprefix _clean_user_,$(user-dirs))
 610userclean: $(clean-user-dirs) testclean utestclean
 611
 612$(clean-user-dirs):
 613        @$(MAKE) -C user/$(patsubst _clean_user_%,%,$@) clean
 614
 615tests/: tests
 616tests: user
 617        @$(MAKE) -f tests/Makefile
 618
 619PHONY += utest
 620utest: $(user-dirs)
 621        @$(MAKE) -C user/$@
 622
 623testclean:
 624        @$(MAKE) -f tests/Makefile clean
 625
 626utestclean:
 627        @$(MAKE) -C user/utest clean
 628
 629# KFS related stuff
 630PHONY += fill-kfs unfill-kfs
 631xcc-gcc-libs = $(XCC_TARGET_ROOT)/../lib/
 632xcc-so-files = $(addprefix $(XCC_TARGET_LIB), *.so*) \
 633               $(addprefix $(xcc-gcc-libs), *.so*)
 634
 635$(OBJDIR)/.dont-force-fill-kfs:
 636        $(Q)rm -rf $(addprefix $(FIRST_KFS_PATH)/lib/, $(notdir $(xcc-so-files)))
 637        @echo "Cross Compiler 'so' files removed from KFS"
 638        @$(MAKE) -f tests/Makefile uninstall
 639        @echo "Apps from /test removed from KFS"
 640        @$(MAKE) -C user/utest uninstall
 641        @echo "User space tests removed from KFS"
 642        @touch $(OBJDIR)/.dont-force-fill-kfs
 643
 644fill-kfs: $(OBJDIR)/.dont-force-fill-kfs user tests
 645        @mkdir -p $(FIRST_KFS_PATH)/lib
 646        $(Q)cp -uP $(xcc-so-files) $(FIRST_KFS_PATH)/lib
 647        @echo "Cross Compiler 'so' files installed to KFS"
 648        @$(MAKE) -f tests/Makefile install
 649        @echo "Apps from /test installed to KFS"
 650        @$(MAKE) -C user/utest install
 651        @echo "User space tests installed to KFS"
 652
 653# Use doxygen to make documentation for ROS (Untested since 2010 or so)
 654doxygen-dir := $(CUR_DIR)/Documentation/doxygen
 655docs:
 656        @echo "  Making doxygen"
 657        @doxygen-dir=$(doxygen-dir) doxygen $(doxygen-dir)/rosdoc.cfg
 658        @if [ ! -d $(doxygen-dir)/rosdoc/html/img ]; \
 659         then \
 660                ln -s ../../img $(doxygen-dir)/rosdoc/html; \
 661         fi
 662
 663doxyclean:
 664        @echo + clean [ROSDOC]
 665        @rm -rf $(doxygen-dir)/rosdoc
 666
 667objclean:
 668        @echo + clean [OBJDIR]
 669        @rm -rf $(OBJDIR)
 670
 671realclean: userclean mrproper doxyclean objclean
 672
 673# Bundled apps
 674# =========================================================================
 675
 676app-dirs =
 677tagged-app-dirs := $(subst /,__,$(app-dirs))
 678app-dirs-install := $(addprefix _install_,$(tagged-app-dirs))
 679app-dirs-clean := $(addprefix _clean_,$(tagged-app-dirs))
 680
 681PHONY += $(app-dirs-install) $(app-dirs-clean)
 682
 683$(app-dirs-install):
 684        @$(MAKE) -C $(patsubst _install_%,%,$(subst __,/,$@)) install
 685
 686$(app-dirs-clean):
 687        @$(MAKE) -C $(patsubst _clean_%,%,$(subst __,/,$@)) clean
 688
 689PHONY +=  apps-install
 690apps-install: $(app-dirs-install)
 691        @$(shell mkdir -p $(AKAROS_ROOT)/build_logs)
 692        @$(call make_as_parent, -C tools/apps/busybox) > build_logs/busybox_install.log 2>&1
 693        @echo busybox install succeeded.
 694        @$(call make_as_parent, -C tools/apps/ipconfig install) > build_logs/ipconfig_install.log 2>&1
 695        @echo ipconfig install succeeded.
 696        @$(call make_as_parent, -C tools/dev-libs/elfutils install) > build_logs/elfutils_install.log 2>&1
 697        @echo elfutils install succeeded.
 698        @$(call make_as_parent, -C tools/dev-util/perf install) > build_logs/perf_install.log 2>&1
 699        @echo perf install succeeded.
 700        @$(call make_as_parent, -C tools/sys-apps/bash install) > build_logs/bash_install.log 2>&1
 701        @echo bash install succeeded.
 702        @$(call make_as_parent, -C tools/sys-apps/grep install) > build_logs/grep_install.log 2>&1
 703        @echo grep install succeeded.
 704
 705PHONY += apps-clean
 706apps-clean: $(app-dirs-clean)
 707        @$(shell mkdir -p $(AKAROS_ROOT)/build_logs)
 708        @$(call make_as_parent, -C tools/apps/busybox clean) > build_logs/busybox_clean.log 2>&1
 709        @echo busybox clean succeeded.
 710        @$(call make_as_parent, -C tools/apps/ipconfig clean) > build_logs/ipconfig_clean.log 2>&1
 711        @echo ipconfig clean succeeded.
 712        @$(call make_as_parent, -C tools/dev-libs/elfutils clean) > build_logs/elfutils_clean.log 2>&1
 713        @echo elfutils clean succeeded.
 714        @$(call make_as_parent, -C tools/dev-util/perf clean) > build_logs/perf_clean.log 2>&1
 715        @echo perf clean succeeded.
 716        @$(call make_as_parent, -C tools/sys-apps/bash clean) > build_logs/bash_clean.log 2>&1
 717        @echo bash clean succeeded.
 718        @$(call make_as_parent, -C tools/sys-apps/grep clean) > build_logs/grep_clean.log 2>&1
 719        @echo grep clean succeeded.
 720
 721# Cross Compiler
 722# =========================================================================
 723
 724xcc_build_dir := tools/compilers/gcc-glibc
 725xcc_target := $(ARCH)
 726ifeq ($(xcc_target),x86)
 727    xcc_target := $(xcc_target)_64
 728endif
 729xcc_cleans := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\
 730                      grep "VALID_CLEANS := " |\
 731                      sed -e 's/VALID_CLEANS := //')
 732xcc_subcmds := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\
 733                       grep "VALID_SUBCMDS := " |\
 734                       sed -e 's/VALID_SUBCMDS := //')
 735xcc_clean_goals := $(patsubst %, xcc-%, $(xcc_cleans))
 736xcc_subcmd_goals := $(patsubst %, xcc-%, $(xcc_subcmds))
 737
 738PHONY += xcc
 739xcc: xcc-build
 740
 741PHONY += $(xcc_clean_goals)
 742$(xcc_clean_goals):
 743        @target="$(patsubst xcc-%,%,$(@))";\
 744        $(call make_as_parent, -C $(xcc_build_dir) $${target})
 745
 746PHONY += $(xcc_subcmd_goals)
 747$(xcc_subcmd_goals):
 748        @subcmd="$(patsubst xcc-%,%,$(@))";\
 749        target="$(xcc_target) $${subcmd}";\
 750        $(call make_as_parent, -C $(xcc_build_dir) $${target})
 751
 752PHONY += xcc-upgrade
 753xcc-upgrade: xcc
 754        @$(MAKE) userclean
 755        @$(MAKE) install-base-libs
 756        @$(MAKE) testclean utestclean
 757        @$(call make_as_parent, apps-clean)
 758        @$(call make_as_parent, apps-install)
 759        @$(MAKE) tests utest
 760        @$(MAKE) fill-kfs
 761        @$(MAKE) akaros-kernel
 762
 763PHONY += xcc-upgrade-from-scratch
 764xcc-upgrade-from-scratch: xcc-clean xcc-uninstall
 765        @$(call make_as_parent, xcc-upgrade)
 766
 767# Cleaning
 768# =========================================================================
 769# This is mostly the Linux kernel cleaning.  We could hook in to the userspace
 770# cleaning with the 'userclean' target attached to clean, though historically
 771# 'clean' means the kernel.
 772
 773# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
 774# Usage:
 775# $(Q)$(MAKE) $(clean)=dir
 776clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
 777
 778# clean - Delete all generated files
 779#
 780clean-dirs         := $(addprefix _clean_,$(akaros-all-dirs))
 781
 782PHONY += $(clean-dirs) clean
 783$(clean-dirs):
 784        $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
 785
 786RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
 787                   -o -name .pc -o -name .hg -o -name .git \) -prune -o
 788clean: $(clean-dirs)
 789        @find $(patsubst _clean_%,%,$(clean-dirs)) $(RCS_FIND_IGNORE) \
 790            \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 791            -o -name '*.ko.*' \
 792            -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
 793            -o -name '*.symtypes' -o -name 'modules.order' \
 794            -o -name modules.builtin -o -name '.tmp_*.o.*' \
 795            -o -name '*.gcno' \) -type f -print | xargs rm -f
 796
 797# Could add in an archclean if we need arch-specific cleanup, or a userclean if
 798# we want to start cleaning that too.
 799#clean: archclean
 800#clean: userclean
 801
 802# mrproper - Delete all generated files, including .config, and reset ARCH
 803#
 804mrproper-dirs      := $(addprefix _mrproper_,scripts)
 805
 806PHONY += $(mrproper-dirs) mrproper
 807$(mrproper-dirs):
 808        $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
 809
 810mrproper: $(mrproper-dirs) clean clean_symlinks
 811        @-rm -f .config
 812        @find $(patsubst _mrproper_%,%,$(mrproper-dirs)) $(RCS_FIND_IGNORE) \
 813            \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 814            -o -name '*.ko.*' \
 815            -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
 816            -o -name '*.symtypes' -o -name 'modules.order' \
 817            -o -name modules.builtin -o -name '.tmp_*.o.*' \
 818            -o -name '*.gcno' \) -type f -print | xargs rm -f
 819
 820# Epilogue
 821# =========================================================================
 822
 823PHONY += FORCE
 824FORCE:
 825
 826# Don't put the srctree on this, make is looking for Makefile, not
 827# /full/path/to/Makefile.
 828Makefile: ; # avoid implicit rule on Makefile
 829
 830# Declare the contents of the .PHONY variable as phony.  We keep that
 831# information in a variable so we can use it in if_changed and friends.
 832.PHONY: $(PHONY)
 833