build: adding out-of-tree support to the xen build

This implement out-of-tree support, there's two ways to create an
out-of-tree build tree (after that, `make` in that new directory
works):
    make O=build
    mkdir build; cd build; make -f ../Makefile
also works with an absolute path for both.

This implementation only works if the source tree is clean, as we use
VPATH.

This patch copies most new code with handling out-of-tree build from
Linux v5.12.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Acked-by: Julien Grall <jgrall@amazon.com>
Tested-by: Julien Grall <jgrall@amazon.com>
Acked-by: Ross Lagerwall <ross.lagerwall@citrix.com> # livepatch
This commit is contained in:
Anthony PERARD authored and Jan Beulich committed 2022-04-13 12:33:21 +02:00
1 parent 5b752808ff
commit 7115fa562f
10 files changed
+164 -22

No files matched your search

+1
View File
@@ -325,6 +325,7 @@ xen/include/xen/*.new
xen/include/xen/acm_policy.h xen/include/xen/acm_policy.h
xen/include/xen/compile.h xen/include/xen/compile.h
xen/include/xen/lib/x86/cpuid-autogen.h xen/include/xen/lib/x86/cpuid-autogen.h
xen/source
xen/test/livepatch/config.h xen/test/livepatch/config.h
xen/test/livepatch/expect_config.h xen/test/livepatch/expect_config.h
xen/test/livepatch/*.livepatch xen/test/livepatch/*.livepatch
+129 -14
View File
@@ -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. # This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated. # All other places this is stored (eg. compile.h) should be autogenerated.
export XEN_VERSION = 4 export XEN_VERSION = 4
@@ -19,6 +23,13 @@ export PYTHON ?= $(PYTHON_INTERPRETER)
export CHECKPOLICY ?= checkpolicy 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 # Do not use make's built-in rules and variables
MAKEFLAGS += -rR MAKEFLAGS += -rR
@@ -37,9 +48,6 @@ export CC CXX LD NM OBJCOPY OBJDUMP ADDR2LINE
export TARGET := xen export TARGET := xen
.PHONY: default
default: build
.PHONY: dist .PHONY: dist
dist: install dist: install
@@ -118,16 +126,88 @@ endif
export quiet Q KBUILD_VERBOSE 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_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 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 := . 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 # 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 # 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 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 # Rules shared between *config targets and build targets
@@ -214,6 +291,37 @@ PHONY += tools_fixdep
tools_fixdep: tools_fixdep:
$(Q)$(MAKE) $(build)=tools 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) ifeq ($(config-build),y)
# =========================================================================== # ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend # *config targets only - make sure prerequisites are updated, and descend
@@ -229,13 +337,13 @@ filechk_kconfig_allconfig = \
.allconfig.tmp: FORCE .allconfig.tmp: FORCE
set -e; { $(call filechk_kconfig_allconfig); } > $@ set -e; { $(call filechk_kconfig_allconfig); } > $@
config: tools_fixdep FORCE config: tools_fixdep outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools/kconfig $@ $(Q)$(MAKE) $(build)=tools/kconfig $@
# Config.mk tries to include .config file, don't try to remake it # Config.mk tries to include .config file, don't try to remake it
%/.config: ; %/.config: ;
%config: .allconfig.tmp tools_fixdep FORCE %config: .allconfig.tmp tools_fixdep outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools/kconfig KCONFIG_ALLCONFIG=$< $@ $(Q)$(MAKE) $(build)=tools/kconfig KCONFIG_ALLCONFIG=$< $@
else # !config-build else # !config-build
@@ -312,6 +420,10 @@ CFLAGS += -flto
LDFLAGS-$(CONFIG_CC_IS_CLANG) += -plugin LLVMgold.so LDFLAGS-$(CONFIG_CC_IS_CLANG) += -plugin LLVMgold.so
endif 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)/include
CFLAGS += -I$(srctree)/arch/$(TARGET_ARCH)/include CFLAGS += -I$(srctree)/arch/$(TARGET_ARCH)/include
@@ -335,6 +447,8 @@ export CFLAGS_UBSAN
endif # need-config endif # need-config
__all: build
main-targets := build install uninstall clean distclean MAP main-targets := build install uninstall clean distclean MAP
.PHONY: $(main-targets) .PHONY: $(main-targets)
ifneq ($(XEN_TARGET_ARCH),x86_32) ifneq ($(XEN_TARGET_ARCH),x86_32)
@@ -431,13 +545,13 @@ _clean:
.PHONY: _distclean .PHONY: _distclean
_distclean: clean _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) $(TARGET).gz: $(TARGET)
gzip -n -f -9 < $< > $@.new gzip -n -f -9 < $< > $@.new
mv $@.new $@ mv $@.new $@
$(TARGET): FORCE $(TARGET): outputmakefile FORCE
$(Q)$(MAKE) $(build)=tools $(Q)$(MAKE) $(build)=tools
$(Q)$(MAKE) $(build)=. include/xen/compile.h $(Q)$(MAKE) $(build)=. include/xen/compile.h
$(Q)$(MAKE) $(build)=include all $(Q)$(MAKE) $(build)=include all
@@ -506,6 +620,7 @@ cloc:
done | cloc --list-file=- done | cloc --list-file=-
endif #config-build endif #config-build
endif # need-sub-make
PHONY += FORCE PHONY += FORCE
FORCE: FORCE:
+10 -1
View File
@@ -37,7 +37,7 @@ SPECIAL_DATA_SECTIONS := rodata $(foreach a,1 2 4 8 16, \
$(foreach r,rel rel.ro,data.$(r).local) $(foreach r,rel rel.ro,data.$(r).local)
# The filename build.mk has precedence over Makefile # 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 # Linking
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -328,6 +328,15 @@ existing-targets := $(wildcard $(sort $(targets)))
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -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 # 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. # information in a variable so we can use it in if_changed and friends.
.PHONY: $(PHONY) .PHONY: $(PHONY)
+4 -1
View File
@@ -77,6 +77,9 @@ ifneq ($(CONFIG_PV_SHIM_EXCLUSIVE),y)
efi-check := arch/x86/efi/check 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. # 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) 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 endif
# Set up the assembler include path properly for older toolchains. # Set up the assembler include path properly for older toolchains.
CFLAGS += -Wa,-I$(srctree)/include CFLAGS += -Wa,-I$(objtree)/include -Wa,-I$(srctree)/include
+6
View File
@@ -7,11 +7,17 @@ targets += $(head-srcs:.S=.o)
head-srcs := $(addprefix $(obj)/, $(head-srcs)) head-srcs := $(addprefix $(obj)/, $(head-srcs))
ifdef building_out_of_srctree
$(obj)/head.o: CFLAGS-y += -iquote $(obj)
endif
$(obj)/head.o: $(head-srcs) $(obj)/head.o: $(head-srcs)
CFLAGS_x86_32 := $(subst -m64,-m32 -march=i686,$(XEN_TREEWIDE_CFLAGS)) CFLAGS_x86_32 := $(subst -m64,-m32 -march=i686,$(XEN_TREEWIDE_CFLAGS))
$(call cc-options-add,CFLAGS_x86_32,CC,$(EMBEDDED_EXTRA_CFLAGS)) $(call cc-options-add,CFLAGS_x86_32,CC,$(EMBEDDED_EXTRA_CFLAGS))
CFLAGS_x86_32 += -Werror -fno-builtin -g0 -msoft-float 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 CFLAGS_x86_32 += -I$(srctree)/include
# override for 32bit binaries # override for 32bit binaries
+2 -1
View File
@@ -3,12 +3,13 @@ EFIOBJ-$(CONFIG_COMPAT) += compat.o
CFLAGS-y += -fshort-wchar CFLAGS-y += -fshort-wchar
CFLAGS-y += -iquote $(srctree)/common/efi CFLAGS-y += -iquote $(srctree)/common/efi
CFLAGS-y += -iquote $(srcdir)
# Part of the command line transforms $(obj) # Part of the command line transforms $(obj)
# e.g.: It transforms "dir/foo/bar" into successively # e.g.: It transforms "dir/foo/bar" into successively
# "dir foo bar", ".. .. ..", "../../.." # "dir foo bar", ".. .. ..", "../../.."
$(obj)/%.c: $(srctree)/common/efi/%.c FORCE $(obj)/%.c: $(srctree)/common/efi/%.c FORCE
$(Q)ln -nfs $(subst $(space),/,$(patsubst %,..,$(subst /, ,$(obj))))/common/efi/$(<F) $@ $(Q)ln -nfs $(subst $(space),/,$(patsubst %,..,$(subst /, ,$(obj))))/source/common/efi/$(<F) $@
clean-files += $(patsubst %.o, %.c, $(EFIOBJ-y:.init.o=.o) $(EFIOBJ-)) clean-files += $(patsubst %.o, %.c, $(EFIOBJ-y:.init.o=.o) $(EFIOBJ-))
+7 -4
View File
@@ -115,7 +115,8 @@ $(obj)/headers99.chk: $(PUBLIC_C99_HEADERS) $(srcdir)/Makefile
$(foreach i, $(filter %.h,$^), \ $(foreach i, $(filter %.h,$^), \
echo "#include "\"$(i)\" \ echo "#include "\"$(i)\" \
| $(CC) -x c -std=c99 -Wall -Werror \ | $(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 - \ -S -o /dev/null - \
|| exit $$?; echo $(i) >> $@.new;) || exit $$?; echo $(i) >> $@.new;)
mv $@.new $@ mv $@.new $@
@@ -129,8 +130,9 @@ $(obj)/headers++.chk: $(PUBLIC_HEADERS) $(srcdir)/Makefile
$(foreach i, $(filter %.h,$^), \ $(foreach i, $(filter %.h,$^), \
echo "#include "\"$(i)\" \ echo "#include "\"$(i)\" \
| $(CXX) -x c++ -std=gnu++98 -Wall -Werror -D__XEN_TOOLS__ \ | $(CXX) -x c++ -std=gnu++98 -Wall -Werror -D__XEN_TOOLS__ \
-include stdint.h -include $(src)/public/xen.h \ -include stdint.h -include $(srcdir)/public/xen.h \
$(foreach j, $($(i)-prereq), -include c$(j)) -S -o /dev/null - \ $(foreach j, $($(patsubst $(srctree)/%,%,$i)-prereq), -include c$(j)) \
-S -o /dev/null - \
|| exit $$?; echo $(i) >> $@.new;) || exit $$?; echo $(i) >> $@.new;)
mv $@.new $@ mv $@.new $@
@@ -139,7 +141,8 @@ endif
ifeq ($(XEN_TARGET_ARCH),x86_64) ifeq ($(XEN_TARGET_ARCH),x86_64)
.PHONY: lib-x86-all .PHONY: lib-x86-all
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 all: lib-x86-all
endif endif
+2
View File
@@ -11,6 +11,8 @@ endif
CODE_ADDR=$(shell nm --defined $(1) | grep $(2) | awk '{print "0x"$$1}') 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}') CODE_SZ=$(shell nm --defined -S $(1) | grep $(2) | awk '{ print "0x"$$2}')
CFLAGS-y += -iquote $(obj)
extra-y += xen_hello_world.livepatch 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 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 $(obj)/xen_hello_world.o: $(obj)/config.h
+2 -1
View File
@@ -4,7 +4,8 @@ obj-y += flask_op.o
obj-y += ss/ obj-y += ss/
CFLAGS-y += -I$(obj)/include CFLAGS-y += -iquote $(obj)/include
CFLAGS-y += -I$(srcdir)/include
AWK = awk AWK = awk
+1
View File
@@ -8,4 +8,5 @@ obj-y += services.o
obj-y += conditional.o obj-y += conditional.o
obj-y += mls.o obj-y += mls.o
CFLAGS-y += -iquote $(objtree)/xsm/flask/include
CFLAGS-y += -I$(srctree)/xsm/flask/include CFLAGS-y += -I$(srctree)/xsm/flask/include
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.