+# $(lastword,) for GNU Make older than 3.81
+lastword = $(word $(words $(1)),$(1))
+this-makefile := $(call lastword,$(MAKEFILE_LIST))
+
# This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated.
export XEN_VERSION = 4
export CHECKPOLICY ?= checkpolicy
+$(if $(filter __%, $(MAKECMDGOALS)), \
+ $(error targets prefixed with '__' are only for internal use))
+
+# That's our default target when none is given on the command line
+PHONY := __all
+__all:
+
# Do not use make's built-in rules and variables
MAKEFLAGS += -rR
export TARGET := xen
-.PHONY: default
-default: build
-
.PHONY: dist
dist: install
export quiet Q KBUILD_VERBOSE
+# $(realpath,) for GNU Make older than 3.81
+realpath = $(wildcard $(foreach file,$(1),$(shell cd -P $(dir $(file)) && echo "$$PWD/$(notdir $(file))")))
+
+ifeq ("$(origin O)", "command line")
+ KBUILD_OUTPUT := $(O)
+endif
+
+ifneq ($(KBUILD_OUTPUT),)
+# Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
+# expand a shell special character '~'. We use a somewhat tedious way here.
+abs_objtree := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
+$(if $(abs_objtree),, \
+ $(error failed to create output directory "$(KBUILD_OUTPUT)"))
+
+# $(realpath ...) resolves symlinks
+abs_objtree := $(call realpath,$(abs_objtree))
+else
abs_objtree := $(CURDIR)
-abs_srctree := $(CURDIR)
+endif
+
+ifeq ($(abs_objtree),$(CURDIR))
+# Suppress "Entering directory ..." unless we are changing the work directory.
+MAKEFLAGS += --no-print-directory
+else
+need-sub-make := 1
+endif
+
+abs_srctree := $(call realpath,$(dir $(this-makefile)))
+
+ifneq ($(words $(subst :, ,$(abs_srctree))), 1)
+$(error source directory cannot contain spaces or colons)
+endif
+
+ifneq ($(abs_srctree),$(abs_objtree))
+# Look for make include files relative to root of kernel src
+#
+# This does not become effective immediately because MAKEFLAGS is re-parsed
+# once after the Makefile is read. We need to invoke sub-make.
+MAKEFLAGS += --include-dir=$(abs_srctree)
+need-sub-make := 1
+endif
export abs_srctree abs_objtree
+export root-make-done := y
+
+ifeq ($(need-sub-make),1)
+
+PHONY += $(MAKECMDGOALS) __sub-make
+
+$(filter-out $(this-makefile), $(MAKECMDGOALS)) __all: __sub-make
+ @:
+
+# Invoke a second make in the output directory, passing relevant variables
+__sub-make:
+ $(Q)$(MAKE) -C $(abs_objtree) -f $(abs_srctree)/Makefile $(MAKECMDGOALS)
+
+endif # need-sub-make
+endif # root-make-done
+
+# We process the rest of the Makefile if this is the final invocation of make
+ifeq ($(need-sub-make),)
+
+ifeq ($(abs_srctree),$(abs_objtree))
+ # building in the source tree
+ srctree := .
+ building_out_of_srctree :=
+else
+ ifeq ($(abs_srctree)/,$(dir $(abs_objtree)))
+ # building in a subdirectory of the source tree
+ srctree := ..
+ else
+ srctree := $(abs_srctree)
+ endif
+ building_out_of_srctree := 1
+endif
-srctree := .
objtree := .
-export srctree objtree
+VPATH := $(srctree)
+
+export building_out_of_srctree srctree objtree VPATH
-export XEN_ROOT := $(CURDIR)/..
+export XEN_ROOT := $(abs_srctree)/..
# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to tools/kconfig/Makefile
export XEN_HAS_CHECKPOLICY := $(call success,$(CHECKPOLICY) -h 2>&1 | grep -q xen)
-export root-make-done := y
-endif # root-make-done
-
# ===========================================================================
# Rules shared between *config targets and build targets
tools_fixdep:
$(Q)$(MAKE) $(build)=tools tools/fixdep
+PHONY += outputmakefile
+# Before starting out-of-tree build, make sure the source tree is clean.
+# outputmakefile generates a Makefile in the output directory, if using a
+# separate output directory. This allows convenient use of make in the
+# output directory.
+# At the same time when output Makefile generated, generate .gitignore to
+# ignore whole output directory
+
+quiet_cmd_makefile = GEN Makefile
+cmd_makefile = { \
+ echo "\# Automatically generated by $(srctree)/Makefile: don't edit"; \
+ echo "include $(srctree)/Makefile"; \
+ } > Makefile
+
+outputmakefile:
+ $(Q)ln -fsn $(srctree) source
+ifdef building_out_of_srctree
+ $(Q)if [ -f $(srctree)/.config -o \
+ -d $(srctree)/include/config -o \
+ -d $(srctree)/include/generated ]; then \
+ echo >&2 "***"; \
+ echo >&2 "*** The source tree is not clean, please run 'make$(if $(findstring command line, $(origin XEN_TARGET_ARCH)), XEN_TARGET_ARCH=$(XEN_TARGET_ARCH)) distclean'"; \
+ echo >&2 "*** in $(abs_srctree)";\
+ echo >&2 "***"; \
+ false; \
+ fi
+ $(call cmd,makefile)
+ $(Q)test -e .gitignore || \
+ { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
+endif
+
ifeq ($(config-build),y)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
.allconfig.tmp: FORCE
set -e; { $(call filechk_kconfig_allconfig); } > $@
-config: tools_fixdep FORCE
+config: tools_fixdep outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools/kconfig $@
# Config.mk tries to include .config file, don't try to remake it
%/.config: ;
-%config: .allconfig.tmp tools_fixdep FORCE
+%config: .allconfig.tmp tools_fixdep outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools/kconfig KCONFIG_ALLCONFIG=$< $@
else # !config-build
LDFLAGS-$(CONFIG_CC_IS_CLANG) += -plugin LLVMgold.so
endif
+ifdef building_out_of_srctree
+ CFLAGS += -I$(objtree)/include
+ CFLAGS += -I$(objtree)/arch/$(TARGET_ARCH)/include
+endif
CFLAGS += -I$(srctree)/include
CFLAGS += -I$(srctree)/arch/$(TARGET_ARCH)/include
endif # need-config
+__all: build
+
main-targets := build install uninstall clean distclean MAP
.PHONY: $(main-targets)
ifneq ($(XEN_TARGET_ARCH),x86_32)
.PHONY: _distclean
_distclean: clean
- rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out GTAGS GPATH GRTAGS GSYMS .config
+ rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out GTAGS GPATH GRTAGS GSYMS .config source
$(TARGET).gz: $(TARGET)
gzip -n -f -9 < $< > $@.new
mv $@.new $@
-$(TARGET): FORCE
+$(TARGET): outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools
$(Q)$(MAKE) $(build)=. include/xen/compile.h
$(Q)$(MAKE) $(build)=include all
done | cloc --list-file=-
endif #config-build
+endif # need-sub-make
PHONY += FORCE
FORCE:
$(foreach i, $(filter %.h,$^), \
echo "#include "\"$(i)\" \
| $(CC) -x c -std=c99 -Wall -Werror \
- -include stdint.h $(foreach j, $($(i)-prereq), -include $(j).h) \
+ -include stdint.h \
+ $(foreach j, $($(patsubst $(srctree)/%,%,$i)-prereq), -include $(j).h) \
-S -o /dev/null - \
|| exit $$?; echo $(i) >> $@.new;)
mv $@.new $@
$(foreach i, $(filter %.h,$^), \
echo "#include "\"$(i)\" \
| $(CXX) -x c++ -std=gnu++98 -Wall -Werror -D__XEN_TOOLS__ \
- -include stdint.h -include $(src)/public/xen.h \
- $(foreach j, $($(i)-prereq), -include c$(j)) -S -o /dev/null - \
+ -include stdint.h -include $(srcdir)/public/xen.h \
+ $(foreach j, $($(patsubst $(srctree)/%,%,$i)-prereq), -include c$(j)) \
+ -S -o /dev/null - \
|| exit $$?; echo $(i) >> $@.new;)
mv $@.new $@
ifeq ($(XEN_TARGET_ARCH),x86_64)
.PHONY: lib-x86-all
lib-x86-all:
- $(MAKE) -C $(obj)/xen/lib/x86 all
+ @mkdir -p $(obj)/xen/lib/x86
+ $(MAKE) -C $(obj)/xen/lib/x86 -f $(abs_srctree)/$(src)/xen/lib/x86/Makefile all
all: lib-x86-all
endif