diff --git a/.gitignore b/.gitignore index d425be4bd9..c6d2c4b4f1 100644 --- a/.gitignore +++ b/.gitignore @@ -325,6 +325,7 @@ xen/include/xen/*.new xen/include/xen/acm_policy.h xen/include/xen/compile.h xen/include/xen/lib/x86/cpuid-autogen.h +xen/source xen/test/livepatch/config.h xen/test/livepatch/expect_config.h xen/test/livepatch/*.livepatch diff --git a/xen/Makefile b/xen/Makefile index ebc7854c08..dd05672ff4 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -1,3 +1,7 @@ +# $(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 @@ -19,6 +23,13 @@ export PYTHON ?= $(PYTHON_INTERPRETER) 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 @@ -37,9 +48,6 @@ export CC CXX LD NM OBJCOPY OBJDUMP ADDR2LINE export TARGET := xen -.PHONY: default -default: build - .PHONY: dist dist: install @@ -118,16 +126,88 @@ endif 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 XEN_ROOT := $(CURDIR)/.. +export building_out_of_srctree srctree objtree VPATH + +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 @@ -204,9 +284,6 @@ endif 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 @@ -214,6 +291,37 @@ PHONY += tools_fixdep 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 @@ -229,13 +337,13 @@ filechk_kconfig_allconfig = \ .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 @@ -312,6 +420,10 @@ CFLAGS += -flto 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 @@ -335,6 +447,8 @@ export CFLAGS_UBSAN endif # need-config +__all: build + main-targets := build install uninstall clean distclean MAP .PHONY: $(main-targets) ifneq ($(XEN_TARGET_ARCH),x86_32) @@ -431,13 +545,13 @@ _clean: .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 @@ -506,6 +620,7 @@ cloc: done | cloc --list-file=- endif #config-build +endif # need-sub-make PHONY += FORCE FORCE: diff --git a/xen/Rules.mk b/xen/Rules.mk index 57a0294555..70b7489ea8 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -37,7 +37,7 @@ SPECIAL_DATA_SECTIONS := rodata $(foreach a,1 2 4 8 16, \ $(foreach r,rel rel.ro,data.$(r).local) # The filename build.mk has precedence over Makefile -include $(firstword $(wildcard $(src)/build.mk) $(src)/Makefile) +include $(firstword $(wildcard $(srcdir)/build.mk) $(srcdir)/Makefile) # Linking # --------------------------------------------------------------------------- @@ -328,6 +328,15 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) +# Create directories for object files if they do not exist +obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets)))) +# If targets exist, their directories apparently exist. Skip mkdir. +existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets)))) +obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs))) +ifneq ($(obj-dirs),) +$(shell mkdir -p $(obj-dirs)) +endif + # 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) diff --git a/xen/arch/x86/arch.mk b/xen/arch/x86/arch.mk index cfde143053..fce2ef5b67 100644 --- a/xen/arch/x86/arch.mk +++ b/xen/arch/x86/arch.mk @@ -77,6 +77,9 @@ ifneq ($(CONFIG_PV_SHIM_EXCLUSIVE),y) efi-check := arch/x86/efi/check +# Create the directory for out-of-tree build +$(shell mkdir -p $(dir $(efi-check))) + # Check if the compiler supports the MS ABI. XEN_BUILD_EFI := $(call if-success,$(CC) $(CFLAGS) -c $(srctree)/$(efi-check).c -o $(efi-check).o,y) @@ -116,4 +119,4 @@ export EFI_LDFLAGS endif # Set up the assembler include path properly for older toolchains. -CFLAGS += -Wa,-I$(srctree)/include +CFLAGS += -Wa,-I$(objtree)/include -Wa,-I$(srctree)/include diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index ca8001c72b..784655f5e2 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -7,11 +7,17 @@ targets += $(head-srcs:.S=.o) head-srcs := $(addprefix $(obj)/, $(head-srcs)) +ifdef building_out_of_srctree +$(obj)/head.o: CFLAGS-y += -iquote $(obj) +endif $(obj)/head.o: $(head-srcs) CFLAGS_x86_32 := $(subst -m64,-m32 -march=i686,$(XEN_TREEWIDE_CFLAGS)) $(call cc-options-add,CFLAGS_x86_32,CC,$(EMBEDDED_EXTRA_CFLAGS)) CFLAGS_x86_32 += -Werror -fno-builtin -g0 -msoft-float +ifdef building_out_of_srctree +CFLAGS_x86_32 += -I$(objtree)/include +endif CFLAGS_x86_32 += -I$(srctree)/include # override for 32bit binaries diff --git a/xen/common/efi/efi-common.mk b/xen/common/efi/efi-common.mk index 960d44a6d5..4298ceaee7 100644 --- a/xen/common/efi/efi-common.mk +++ b/xen/common/efi/efi-common.mk @@ -3,12 +3,13 @@ EFIOBJ-$(CONFIG_COMPAT) += compat.o CFLAGS-y += -fshort-wchar CFLAGS-y += -iquote $(srctree)/common/efi +CFLAGS-y += -iquote $(srcdir) # Part of the command line transforms $(obj) # e.g.: It transforms "dir/foo/bar" into successively # "dir foo bar", ".. .. ..", "../../.." $(obj)/%.c: $(srctree)/common/efi/%.c FORCE - $(Q)ln -nfs $(subst $(space),/,$(patsubst %,..,$(subst /, ,$(obj))))/common/efi/$(> $@.new;) mv $@.new $@ @@ -129,8 +130,9 @@ $(obj)/headers++.chk: $(PUBLIC_HEADERS) $(srcdir)/Makefile $(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 $@ @@ -139,7 +141,8 @@ endif 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 diff --git a/xen/test/livepatch/Makefile b/xen/test/livepatch/Makefile index ddb0737131..c258ab0b59 100644 --- a/xen/test/livepatch/Makefile +++ b/xen/test/livepatch/Makefile @@ -11,6 +11,8 @@ endif CODE_ADDR=$(shell nm --defined $(1) | grep $(2) | awk '{print "0x"$$1}') CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}') +CFLAGS-y += -iquote $(obj) + extra-y += xen_hello_world.livepatch xen_hello_world-objs := xen_hello_world_func.o xen_hello_world.o note.o xen_note.o modinfo.o $(obj)/xen_hello_world.o: $(obj)/config.h diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile index a99038cb57..d25312f4fa 100644 --- a/xen/xsm/flask/Makefile +++ b/xen/xsm/flask/Makefile @@ -4,7 +4,8 @@ obj-y += flask_op.o obj-y += ss/ -CFLAGS-y += -I$(obj)/include +CFLAGS-y += -iquote $(obj)/include +CFLAGS-y += -I$(srcdir)/include AWK = awk diff --git a/xen/xsm/flask/ss/Makefile b/xen/xsm/flask/ss/Makefile index aba1339f38..ffe92ec19e 100644 --- a/xen/xsm/flask/ss/Makefile +++ b/xen/xsm/flask/ss/Makefile @@ -8,4 +8,5 @@ obj-y += services.o obj-y += conditional.o obj-y += mls.o +CFLAGS-y += -iquote $(objtree)/xsm/flask/include CFLAGS-y += -I$(srctree)/xsm/flask/include