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
  29# we 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
 198HOSTLD       = ld
 199
 200export CONFIG_SHELL HOSTCC HOSTCXX HOSTCFLAGS HOSTCXXFLAGS HOSTLD
 201
 202# Beautify output
 203# ---------------------------------------------------------------------------
 204#
 205# Normally, we echo the whole command before executing it. By making
 206# that echo $($(quiet)$(cmd)), we now have the possibility to set
 207# $(quiet) to choose other forms of output instead, e.g.
 208#
 209#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
 210#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
 211#
 212# If $(quiet) is empty, the whole command will be printed.
 213# If it is set to "quiet_", only the short version will be printed.
 214# If it is set to "silent_", nothing will be printed at all, since
 215# the variable $(silent_cmd_cc_o_c) doesn't exist.
 216#
 217# A simple variant is to prefix commands with $(Q) - that's useful
 218# for commands that shall be hidden in non-verbose mode.
 219#
 220#       $(Q)ln $@ :<
 221#
 222# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
 223# If KBUILD_VERBOSE equals 1 then the above command is displayed.
 224
 225ifeq ($(KBUILD_VERBOSE),1)
 226  quiet =
 227  Q =
 228else
 229  quiet=quiet_
 230  Q = @
 231endif
 232export quiet Q KBUILD_VERBOSE
 233
 234# We need some generic definitions (do not try to remake the file).
 235$(srctree)/scripts/Kbuild.include: ;
 236include $(srctree)/scripts/Kbuild.include
 237
 238# Kbuild Target/Goals Parsing
 239# =========================================================================
 240# Need to figure out if we're a config or not, and whether or not to include
 241# our .config / auto.conf.  Configs are basically their own makefile, (ifeq),
 242# and cleans are allowed to proceed without worrying about the dot-config.
 243
 244# Basic helpers built in scripts/
 245PHONY += scripts_basic
 246scripts_basic:
 247        $(Q)$(MAKE) $(build)=scripts/basic
 248
 249PHONY += scripts
 250
 251scripts: scripts_basic include/config/auto.conf include/config/tristate.conf
 252        $(Q)$(MAKE) $(build)=$(@)
 253
 254config-targets := 0
 255mixed-targets  := 0
 256dot-config     := 1
 257
 258no-dot-config-targets := $(clean-goals)
 259
 260ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
 261    ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
 262        dot-config := 0
 263    endif
 264endif
 265
 266ifneq ($(filter config %config,$(MAKECMDGOALS)),)
 267    config-targets := 1
 268    ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
 269        mixed-targets := 1
 270    endif
 271endif
 272
 273ifeq ($(mixed-targets),1)
 274# ===========================================================================
 275# We're called with mixed targets (*config and build targets).
 276# Handle them one by one.
 277
 278%:: FORCE
 279        $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
 280
 281else
 282ifeq ($(config-targets),1)
 283# ===========================================================================
 284# *config targets only - make sure prerequisites are updated, and descend
 285# in scripts/kconfig to make the *config target
 286
 287# Default config file, per arch.  This path will resolve to
 288# arch/$ARCH/configs/defconfig (arch -> kern/arch).  Each arch can override
 289# this if they want, or just symlink to one in the main root directory.
 290KBUILD_DEFCONFIG := defconfig
 291export KBUILD_DEFCONFIG
 292
 293config: scripts_basic symlinks FORCE
 294        $(Q)mkdir -p include/config
 295        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 296
 297%config: scripts_basic symlinks FORCE
 298        $(Q)mkdir -p include/config
 299        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 300
 301else
 302# ===========================================================================
 303# Build targets only - this includes vmlinux, arch specific targets, clean
 304# targets and others. In general all targets except *config targets.
 305
 306ifeq ($(dot-config),1)
 307KCONFIG_CONFIG ?= .config
 308export KCONFIG_CONFIG
 309
 310# Read in config
 311-include include/config/auto.conf
 312
 313# Read in dependencies to all Kconfig* files, make sure to run
 314# oldconfig if changes are detected.
 315-include include/config/auto.conf.cmd
 316
 317# To avoid any implicit rule to kick in, define an empty command
 318$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
 319
 320# If .config is newer than include/config/auto.conf, someone tinkered
 321# with it and forgot to run make oldconfig.
 322# if auto.conf.cmd is missing then we are probably in a cleaned tree so
 323# we execute the config step to be sure to catch updated Kconfig files
 324include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
 325        $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 326
 327else
 328# Dummy target needed, because used as prerequisite
 329include/config/auto.conf: ;
 330endif # $(dot-config)
 331
 332# Akaros Build Environment
 333# =========================================================================
 334AKAROSINCLUDE   := -I$(srctree)/kern/include/
 335
 336# CROSS_COMPILE is defined per-arch.  Each arch can set other makeflags, kbuild
 337# directories, etc.
 338-include $(srctree)/kern/arch/$(ARCH)/Makefile
 339
 340CC          := $(CROSS_COMPILE)gcc
 341CPP         := $(CROSS_COMPILE)g++
 342AS          := $(CROSS_COMPILE)as
 343AR          := $(CROSS_COMPILE)ar
 344LD          := $(CROSS_COMPILE)ld
 345OBJCOPY     := $(CROSS_COMPILE)objcopy
 346OBJDUMP     := $(CROSS_COMPILE)objdump
 347NM          := $(CROSS_COMPILE)nm
 348STRIP       := $(CROSS_COMPILE)strip
 349KERNEL_LD ?= kernel.ld
 350
 351# These may have bogus values if there is no compiler.  The kernel and user
 352# build targets will check cc-exists.  Hopefully no cleaning targets rely on
 353# these.  Note that if you change configs, these will get computed once, before
 354# silentoldconfig kicks in to regenerate auto.conf, and these values will
 355# temporarily be stale.
 356gcc-lib := $(shell $(CC) -print-libgcc-file-name 2>/dev/null)
 357NOSTDINC_FLAGS += -nostdinc -isystem \
 358                  $(shell $(CC) -print-file-name=include 2>/dev/null)
 359XCC_TARGET_ROOT := $(shell $(CC) --print-sysroot 2> /dev/null)
 360XCC_TARGET_LIB := $(XCC_TARGET_ROOT)/usr/lib/
 361XCC_TARGET_INCLUDE := $(XCC_TARGET_ROOT)/usr/include/
 362
 363CFLAGS_KERNEL += -O2 -pipe -MD
 364CFLAGS_KERNEL += -std=gnu99 -fgnu89-inline
 365CFLAGS_KERNEL += -fno-strict-aliasing -fno-omit-frame-pointer
 366CFLAGS_KERNEL += -fno-stack-protector
 367CFLAGS_KERNEL += -Wall -Wno-format -Wno-unused -Werror -Wreturn-type
 368CFLAGS_KERNEL += -DROS_KERNEL -D__KERNEL__
 369CFLAGS_KERNEL += -include include/generated/autoconf.h -include include/common.h
 370CFLAGS_KERNEL += -fplan9-extensions
 371ifeq ($(CONFIG_64BIT),y)
 372CFLAGS_KERNEL += -m64 -g
 373else
 374CFLAGS_KERNEL += -m32 -gstabs
 375endif
 376ifeq ($(CONFIG_BETTER_BACKTRACE),y)
 377CFLAGS_KERNEL += -fno-optimize-sibling-calls
 378endif
 379
 380# TODO: do we need this, or can we rely on the compiler's defines?
 381CFLAGS_KERNEL += -D$(ARCH)
 382
 383# TODO: this requires our own strchr (kern/src/stdio.c), which is a potential
 384# source of bugs/problems.
 385# note we still pull in stdbool and stddef from the compiler
 386CFLAGS_KERNEL += -fno-builtin
 387
 388AFLAGS_KERNEL := $(CFLAGS_KERNEL)
 389
 390KBUILD_BUILTIN := 1
 391KBUILD_CHECKSRC := 0
 392
 393export AKAROSINCLUDE CROSS_COMPILE
 394export CC CPP AS AR LD OBJCOPY OBJDUMP NM STRIP
 395export CFLAGS_KERNEL AFLAGS_KERNEL
 396export NOSTDINC_FLAGS XCC_TARGET_ROOT XCC_TARGET_LIB XCC_TARGET_INCLUDE
 397export KBUILD_BUILTIN KBUILD_CHECKSRC
 398
 399CFLAGS_USER += -O2 -std=gnu99 -fno-stack-protector -fgnu89-inline \
 400               -Wsystem-headers -Werror -Wreturn-type
 401CXXFLAGS_USER += -O2
 402CFLAGS_USER_LIBS += -fPIC -static -fno-omit-frame-pointer -g
 403
 404export CFLAGS_USER CXXFLAGS_USER CFLAGS_USER_LIBS
 405
 406# Akaros include stuff (includes custom make targets and user overrides)
 407# =========================================================================
 408
 409# The user can override this, though it won't apply for any of the in-tree
 410# kernel build output.  Right now, it's only passed down to tests/
 411dummy-1 := $(shell mkdir -p $(OBJDIR)/kern/)
 412
 413# Since we're doing this outside of the dot-config part, some targets, such as
 414# clean, won't read in our .config/auto.conf, and won't know about the
 415# KFS_PATH.  Future rules related to KFS will have issues (mkdir with no
 416# argument, or a find of the entire pwd).  It's also possible someone provided
 417# an empty path.  To deal with both, we'll just have a sensible default.
 418kfs-paths :=  $(subst $\",,$(CONFIG_KFS_PATHS))
 419ifeq ($(kfs-paths),)
 420kfs-paths := kern/kfs
 421endif
 422
 423FIRST_KFS_PATH = $(firstword $(kfs-paths))
 424ABS_KFS_PATH = $(abspath $(FIRST_KFS_PATH))
 425
 426export OBJDIR FIRST_KFS_PATH ABS_KFS_PATH
 427
 428# Avoiding implicit rules
 429$(srctree)/Makelocal: ;
 430# TODO: one issue is that we import all types of targets: build, clean, etc.
 431# That makes it a bit tougher to reorganize with ifeqs.
 432-include $(srctree)/Makelocal
 433
 434# Akaros Kernel Build
 435# =========================================================================
 436# Add top level directories, either to an existing entry (core-y) or to its
 437# own.
 438#
 439# From these, we determine deps and dirs.  We recursively make through the
 440# dirs, generating built-in.o at each step, which are the deps from which we
 441# link akaros.
 442#
 443# We have all-arch-dirs and all-dirs, so that we can still clean even without
 444# an arch symlink.
 445
 446core-y += kern/src/ kern/drivers/ kern/lib/ $(AKAROS_EXTERNAL_DIRS)
 447arch-y += kern/arch/$(ARCH)/
 448
 449akaros-dirs     := $(patsubst %/,%,$(filter %/, $(core-y) $(arch-y)))
 450
 451all-arch-dirs   := $(patsubst %,kern/arch/%/,$(valid-arches))
 452akaros-all-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(all-arch-dirs)))
 453
 454core-y          := $(patsubst %/, %/built-in.o, $(core-y))
 455arch-y          := $(patsubst %/, %/built-in.o, $(arch-y))
 456
 457kbuild_akaros_main := $(core-y) $(arch-y)
 458akaros-deps := $(kbuild_akaros_main)  kern/arch/$(ARCH)/$(KERNEL_LD)
 459
 460kern_cpio := $(OBJDIR)/kern/initramfs.cpio
 461kern_cpio_obj := $(kern_cpio).o
 462
 463# a bit hacky: we want to make sure the directories exist, and error out
 464# otherwise.  we also want to error out before the initramfs target, otherwise
 465# we might not get the error (if initramfs files are all up to date).  the
 466# trickiest thing here is that kfs-paths-check could be stale and require an
 467# oldconfig.  running make twice should suffice.
 468kfs-paths-check := $(shell for i in $(kfs-paths); do \
 469                               if [ ! -d "$$i" ]; then \
 470                                   echo "Can't find KFS directory $$i"; \
 471                                   $(MAKE) -f $(srctree)/Makefile \
 472                                   silentoldconfig > /dev/null; \
 473                                   exit -1; \
 474                               fi; \
 475                           done; echo "ok")
 476
 477ifneq (ok,$(kfs-paths-check))
 478$(error $(kfs-paths-check), try make one more time in case of stale configs)
 479endif
 480
 481kern_initramfs_files := $(shell find $(kfs-paths))
 482
 483# Need to make an empty cpio, then append each kfs-path's contents
 484$(kern_cpio) initramfs: $(kern_initramfs_files)
 485        @echo "  Building initramfs:"
 486        @if [ "$(CONFIG_KFS_CPIO_BIN)" != "" ]; then \
 487                sh $(CONFIG_KFS_CPIO_BIN); \
 488        fi
 489        @cat /dev/null | cpio --quiet -oH newc -O $(kern_cpio)
 490        $(Q)for i in $(kfs-paths); do cd $$i; \
 491                echo "    Adding $$i to initramfs..."; \
 492                find -L . | cpio --quiet -oAH newc -O $(CURDIR)/$(kern_cpio); \
 493                cd $$OLDPWD; \
 494        done;
 495
 496ld_emulation = $(shell $(OBJDUMP) -i 2>/dev/null | \
 497                       grep -v BFD | grep ^[a-z] | head -n1)
 498ld_arch = $(shell $(OBJDUMP) -i 2>/dev/null |\
 499                  grep -v BFD | grep "^  [a-z]" | head -n1)
 500
 501# Our makefile doesn't detect a change in subarch, and old binary objects that
 502# don't need to be updated won't get rebuilt, but they also can't link with the
 503# new subarch (32 bit vs 64 bit).  If we detect the wrong type, we'll force a
 504# rebuild.
 505existing-cpio-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \
 506                        grep format | sed 's/.*format //g')
 507ifneq ($(existing-cpio-emul),)
 508ifneq ($(existing-cpio-emul),$(ld_emulation))
 509$(kern_cpio_obj): cpio-rebuild
 510cpio-rebuild:
 511        $(Q)rm $(kern_cpio_obj)
 512endif
 513endif
 514
 515$(kern_cpio_obj): $(kern_cpio)
 516        $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@
 517
 518existing-ext2b-emul := $(shell objdump -f $(kern_cpio_obj) 2> /dev/null | \
 519                         grep format | sed 's/.*format //g')
 520ifneq ($(existing-ext2b-emul),)
 521ifneq ($(existing-ext2b-emul),$(ld_emulation))
 522$(ext2_bdev_obj): ext2b-rebuild
 523ext2b-rebuild:
 524        $(Q)rm $(ext2_bdev_obj)
 525endif
 526endif
 527
 528$(ext2_bdev_obj): $(ext2-bdev)
 529        $(Q)$(OBJCOPY) -I binary -B $(ld_arch) -O $(ld_emulation) $< $@
 530
 531# Not the worlds most elegant link command.  link-kernel takes the obj output
 532# name, then the linker script, then everything else you'd dump on the ld
 533# command line, including linker options and objects to link together.
 534#
 535# After the script is done, we run the arch-specific command directly.
 536quiet_cmd_link-akaros = LINK    $@
 537      cmd_link-akaros = $(CONFIG_SHELL) scripts/link-kernel.sh $@ \
 538                        kern/arch/$(ARCH)/$(KERNEL_LD) $(LDFLAGS_KERNEL) \
 539                        --build-id=sha1 \
 540                        $(akaros-deps) $(gcc-lib) $(kern_cpio_obj) \
 541                        $(ext2_bdev_obj); \
 542                        $(ARCH_POST_LINK_CMD)
 543
 544# For some reason, the if_changed doesn't work with FORCE (like it does in
 545# Linux).  It looks like it can't find the .cmd file or something (also
 546# complaints of $(targets), so that all is probably messed up).
 547$(KERNEL_OBJ): $(akaros-deps) $(kern_cpio_obj) $(ext2_bdev_obj)
 548        $(call if_changed,link-akaros)
 549
 550akaros-kernel: $(KERNEL_OBJ)
 551
 552$(sort $(akaros-deps)): $(akaros-dirs) ;
 553
 554# Recursively Kbuild all of our directories.  If we're changing arches
 555# mid-make, we might have issues ( := on akaros-dirs, etc).
 556PHONY += $(akaros-dirs) cc_exists
 557$(akaros-dirs): scripts symlinks cc-exists
 558        $(Q)$(MAKE) $(build)=$@
 559
 560cc-exists:
 561        @if [ "`which $(CROSS_COMPILE)gcc`" = "" ]; then echo \
 562            Could not find a $(CROSS_COMPILE) version of GCC/binutils. \
 563            Be sure to build the cross-compiler and update your PATH; exit 1; fi
 564
 565$(CMP_KERNEL_OBJ): $(KERNEL_OBJ)
 566        @echo "Compressing kernel image"
 567        $(Q)gzip -c $^ > $@
 568
 569# TODO: not sure what all we want to have available for config targets
 570# (anything after this is allowed.  We currently need clean targets available
 571# (config->symlinks->clean).
 572endif #ifeq ($(config-targets),1)
 573endif #ifeq ($(mixed-targets),1)
 574
 575# Akaros Userspace Building and Misc Helpers
 576# =========================================================================
 577# Recursively make user libraries and tests.
 578#
 579# User library makefiles are built to expect to be called from their own
 580# directories.  The test code can be called from the root directory.
 581
 582# List all userspace directories here, and state any dependencies between them,
 583# such as how pthread depends on parlib.
 584
 585# Critical libraries, also built during the toolchain install
 586user-base-dirs = parlib pthread benchutil iplib ndblib perfmon
 587benchutil: parlib
 588pthread: parlib benchutil
 589iplib: parlib
 590ndblib: iplib
 591
 592# Higher-level libraries.  Built before tests/, but after apps-install.
 593# TODO: would like to move perfmon here, since it's not meant to be low-level.
 594# But the apps-install has perf, which depends on user/perfmon.
 595user-extra-dirs = vmm electric-fence
 596$(user-extra-dirs): $(user-base-dirs)
 597
 598user-dirs = $(user-base-dirs) $(user-extra-dirs)
 599
 600PHONY += install-base-libs $(user-dirs)
 601install-base-libs: $(user-base-dirs) symlinks cc-exists
 602
 603$(user-dirs):
 604        @$(MAKE) -C user/$@ DEPLIBS="$^" && $(MAKE) -C user/$@ install
 605
 606PHONY += user
 607user: $(user-dirs)
 608
 609PHONY += userclean $(clean-user-dirs)
 610clean-user-dirs := $(addprefix _clean_user_,$(user-dirs))
 611userclean: $(clean-user-dirs) testclean utestclean
 612
 613$(clean-user-dirs):
 614        @$(MAKE) -C user/$(patsubst _clean_user_%,%,$@) clean
 615
 616tests/: tests
 617tests: user
 618        @$(MAKE) -f tests/Makefile
 619
 620PHONY += utest
 621utest: $(user-dirs)
 622        @$(MAKE) -C user/$@
 623
 624testclean:
 625        @$(MAKE) -f tests/Makefile clean
 626
 627utestclean:
 628        @$(MAKE) -C user/utest clean
 629
 630# KFS related stuff
 631PHONY += fill-kfs unfill-kfs
 632xcc-gcc-libs = $(XCC_TARGET_ROOT)/../lib/
 633xcc-so-files = $(addprefix $(XCC_TARGET_LIB), *.so*) \
 634               $(addprefix $(xcc-gcc-libs), *.so*)
 635
 636$(OBJDIR)/.dont-force-fill-kfs:
 637        $(Q)rm -rf $(addprefix $(FIRST_KFS_PATH)/lib/, $(notdir $(xcc-so-files)))
 638        @echo "Cross Compiler 'so' files removed from KFS"
 639        @$(MAKE) -f tests/Makefile uninstall
 640        @echo "Apps from /test removed from KFS"
 641        @$(MAKE) -C user/utest uninstall
 642        @echo "User space tests removed from KFS"
 643        @touch $(OBJDIR)/.dont-force-fill-kfs
 644
 645fill-kfs: $(OBJDIR)/.dont-force-fill-kfs user tests
 646        @mkdir -p $(FIRST_KFS_PATH)/lib
 647        $(Q)cp -uP $(xcc-so-files) $(FIRST_KFS_PATH)/lib
 648        @echo "Cross Compiler 'so' files installed to KFS"
 649        @$(MAKE) -f tests/Makefile install
 650        @echo "Apps from /test installed to KFS"
 651        @$(MAKE) -C user/utest install
 652        @echo "User space tests installed to KFS"
 653
 654# Use doxygen to make documentation for ROS (Untested since 2010 or so)
 655doxygen-dir := $(CUR_DIR)/Documentation/doxygen
 656docs:
 657        @echo "  Making doxygen"
 658        @doxygen-dir=$(doxygen-dir) doxygen $(doxygen-dir)/rosdoc.cfg
 659        @if [ ! -d $(doxygen-dir)/rosdoc/html/img ]; \
 660         then \
 661                ln -s ../../img $(doxygen-dir)/rosdoc/html; \
 662         fi
 663
 664doxyclean:
 665        @echo + clean [ROSDOC]
 666        @rm -rf $(doxygen-dir)/rosdoc
 667
 668objclean:
 669        @echo + clean [OBJDIR]
 670        @rm -rf $(OBJDIR)
 671
 672realclean: userclean mrproper doxyclean objclean
 673
 674# Bundled apps
 675# =========================================================================
 676
 677app-dirs =
 678tagged-app-dirs := $(subst /,__,$(app-dirs))
 679app-dirs-install := $(addprefix _install_,$(tagged-app-dirs))
 680app-dirs-clean := $(addprefix _clean_,$(tagged-app-dirs))
 681
 682PHONY += $(app-dirs-install) $(app-dirs-clean)
 683
 684$(app-dirs-install):
 685        @$(MAKE) -C $(patsubst _install_%,%,$(subst __,/,$@)) install
 686
 687$(app-dirs-clean):
 688        @$(MAKE) -C $(patsubst _clean_%,%,$(subst __,/,$@)) clean
 689
 690PHONY +=  apps-install
 691apps-install: $(app-dirs-install)
 692        @$(shell mkdir -p $(AKAROS_ROOT)/build_logs)
 693        @$(call make_as_parent, -C tools/apps/busybox) > build_logs/busybox_install.log 2>&1
 694        @echo busybox install succeeded.
 695        @$(call make_as_parent, -C tools/apps/ipconfig install) > build_logs/ipconfig_install.log 2>&1
 696        @echo ipconfig install succeeded.
 697        @$(call make_as_parent, -C tools/dev-libs/elfutils install) > build_logs/elfutils_install.log 2>&1
 698        @echo elfutils install succeeded.
 699        @$(call make_as_parent, -C tools/dev-util/perf install) > build_logs/perf_install.log 2>&1
 700        @echo perf install succeeded.
 701        @$(call make_as_parent, -C tools/sys-apps/bash install) > build_logs/bash_install.log 2>&1
 702        @echo bash install succeeded.
 703        @$(call make_as_parent, -C tools/sys-apps/grep install) > build_logs/grep_install.log 2>&1
 704        @echo grep install succeeded.
 705
 706PHONY += apps-clean
 707apps-clean: $(app-dirs-clean)
 708        @$(shell mkdir -p $(AKAROS_ROOT)/build_logs)
 709        @$(call make_as_parent, -C tools/apps/busybox clean) > build_logs/busybox_clean.log 2>&1
 710        @echo busybox clean succeeded.
 711        @$(call make_as_parent, -C tools/apps/ipconfig clean) > build_logs/ipconfig_clean.log 2>&1
 712        @echo ipconfig clean succeeded.
 713        @$(call make_as_parent, -C tools/dev-libs/elfutils clean) > build_logs/elfutils_clean.log 2>&1
 714        @echo elfutils clean succeeded.
 715        @$(call make_as_parent, -C tools/dev-util/perf clean) > build_logs/perf_clean.log 2>&1
 716        @echo perf clean succeeded.
 717        @$(call make_as_parent, -C tools/sys-apps/bash clean) > build_logs/bash_clean.log 2>&1
 718        @echo bash clean succeeded.
 719        @$(call make_as_parent, -C tools/sys-apps/grep clean) > build_logs/grep_clean.log 2>&1
 720        @echo grep clean succeeded.
 721
 722# Cross Compiler
 723# =========================================================================
 724
 725xcc_build_dir := tools/compilers/gcc-glibc
 726xcc_target := $(ARCH)
 727ifeq ($(xcc_target),x86)
 728    xcc_target := $(xcc_target)_64
 729endif
 730xcc_cleans := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\
 731                      grep "VALID_CLEANS := " |\
 732                      sed -e 's/VALID_CLEANS := //')
 733xcc_subcmds := $(shell $(MAKE) -C $(xcc_build_dir) -pn |\
 734                       grep "VALID_SUBCMDS := " |\
 735                       sed -e 's/VALID_SUBCMDS := //')
 736xcc_clean_goals := $(patsubst %, xcc-%, $(xcc_cleans))
 737xcc_subcmd_goals := $(patsubst %, xcc-%, $(xcc_subcmds))
 738
 739PHONY += xcc
 740xcc: xcc-build
 741
 742PHONY += $(xcc_clean_goals)
 743$(xcc_clean_goals):
 744        @target="$(patsubst xcc-%,%,$(@))";\
 745        $(call make_as_parent, -C $(xcc_build_dir) $${target})
 746
 747PHONY += $(xcc_subcmd_goals)
 748$(xcc_subcmd_goals):
 749        @subcmd="$(patsubst xcc-%,%,$(@))";\
 750        target="$(xcc_target) $${subcmd}";\
 751        $(call make_as_parent, -C $(xcc_build_dir) $${target})
 752
 753PHONY += xcc-upgrade
 754xcc-upgrade: xcc
 755        @$(MAKE) userclean
 756        @$(MAKE) install-base-libs
 757        @$(MAKE) testclean utestclean
 758        @$(call make_as_parent, apps-clean)
 759        @$(call make_as_parent, apps-install)
 760        @$(MAKE) tests utest
 761        @$(MAKE) fill-kfs
 762        @$(MAKE) akaros-kernel
 763
 764PHONY += xcc-upgrade-from-scratch
 765xcc-upgrade-from-scratch: xcc-clean xcc-uninstall
 766        @$(call make_as_parent, xcc-upgrade)
 767
 768# Cleaning
 769# =========================================================================
 770# This is mostly the Linux kernel cleaning.  We could hook in to the userspace
 771# cleaning with the 'userclean' target attached to clean, though historically
 772# 'clean' means the kernel.
 773
 774# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
 775# Usage:
 776# $(Q)$(MAKE) $(clean)=dir
 777clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
 778
 779# clean - Delete all generated files
 780#
 781clean-dirs         := $(addprefix _clean_,$(akaros-all-dirs))
 782
 783PHONY += $(clean-dirs) clean
 784$(clean-dirs):
 785        $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
 786
 787RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \
 788                   -o -name .pc -o -name .hg -o -name .git \) -prune -o
 789clean: $(clean-dirs)
 790        @find $(patsubst _clean_%,%,$(clean-dirs)) $(RCS_FIND_IGNORE) \
 791            \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 792            -o -name '*.ko.*' \
 793            -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
 794            -o -name '*.symtypes' -o -name 'modules.order' \
 795            -o -name modules.builtin -o -name '.tmp_*.o.*' \
 796            -o -name '*.gcno' \) -type f -print | xargs rm -f
 797
 798# Could add in an archclean if we need arch-specific cleanup, or a userclean if
 799# we want to start cleaning that too.
 800#clean: archclean
 801#clean: userclean
 802
 803# mrproper - Delete all generated files, including .config, and reset ARCH
 804#
 805mrproper-dirs      := $(addprefix _mrproper_,scripts)
 806
 807PHONY += $(mrproper-dirs) mrproper
 808$(mrproper-dirs):
 809        $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
 810
 811mrproper: $(mrproper-dirs) clean clean_symlinks
 812        @-rm -f .config
 813        @find $(patsubst _mrproper_%,%,$(mrproper-dirs)) $(RCS_FIND_IGNORE) \
 814            \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 815            -o -name '*.ko.*' \
 816            -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
 817            -o -name '*.symtypes' -o -name 'modules.order' \
 818            -o -name modules.builtin -o -name '.tmp_*.o.*' \
 819            -o -name '*.gcno' \) -type f -print | xargs rm -f
 820
 821# Epilogue
 822# =========================================================================
 823
 824PHONY += FORCE
 825FORCE:
 826
 827# Don't put the srctree on this, make is looking for Makefile, not
 828# /full/path/to/Makefile.
 829Makefile: ; # avoid implicit rule on Makefile
 830
 831# Declare the contents of the .PHONY variable as phony.  We keep that
 832# information in a variable so we can use it in if_changed and friends.
 833.PHONY: $(PHONY)
 834