# 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 XEN_SUBVERSION = 14 export XEN_EXTRAVERSION ?= .1$(XEN_VENDORVERSION) export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) -include xen-version export XEN_WHOAMI ?= $(USER) export XEN_DOMAIN ?= $(shell ([ -x /bin/dnsdomainname ] && /bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo [unknown])) export XEN_BUILD_DATE ?= $(shell LC_ALL=C date) export XEN_BUILD_TIME ?= $(shell LC_ALL=C date +%T) export XEN_BUILD_HOST ?= $(shell hostname) # Best effort attempt to find a python interpreter, defaulting to Python 3 if # available. Fall back to just `python` if `which` is nowhere to be found. PYTHON_INTERPRETER := $(word 1,$(shell which python3 python python2 2>/dev/null) python) export PYTHON ?= $(PYTHON_INTERPRETER) export BASEDIR := $(CURDIR) export XEN_ROOT := $(BASEDIR)/.. # Do not use make's built-in rules and variables MAKEFLAGS += -rR EFI_MOUNTPOINT ?= $(BOOT_DIR)/efi ARCH=$(XEN_TARGET_ARCH) SRCARCH=$(shell echo $(ARCH) | sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g') # Don't break if the build process wasn't called from the top level # we need XEN_TARGET_ARCH to generate the proper config include $(XEN_ROOT)/Config.mk # Set ARCH/SUBARCH appropriately. export TARGET_SUBARCH := $(XEN_TARGET_ARCH) export TARGET_ARCH := $(shell echo $(XEN_TARGET_ARCH) | \ sed -e 's/x86.*/x86/' -e s'/arm\(32\|64\)/arm/g') # Allow someone to change their config file export KCONFIG_CONFIG ?= .config export CC CXX LD .PHONY: default default: build .PHONY: dist dist: install include scripts/Kbuild.include ifneq ($(root-make-done),y) # section to run before calling Rules.mk, but only once. # Beautify output # --------------------------------------------------------------------------- # # Normally, we echo the whole command before executing it. By making # that echo $($(quiet)$(cmd)), we now have the possibility to set # $(quiet) to choose other forms of output instead, e.g. # # quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@ # cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< # # If $(quiet) is empty, the whole command will be printed. # If it is set to "quiet_", only the short version will be printed. # If it is set to "silent_", nothing will be printed at all, since # the variable $(silent_cmd_cc_o_c) doesn't exist. # # A simple variant is to prefix commands with $(Q) - that's useful # for commands that shall be hidden in non-verbose mode. # # $(Q)ln $@ :< # # If KBUILD_VERBOSE equals 0 then the above command will be hidden. # If KBUILD_VERBOSE equals 1 then the above command is displayed. # # To put more focus on warnings, be less verbose as default # Use 'make V=1' to see the full commands ifeq ("$(origin V)", "command line") KBUILD_VERBOSE := $(V) endif ifndef KBUILD_VERBOSE KBUILD_VERBOSE := 0 endif ifeq ($(KBUILD_VERBOSE),1) quiet := Q := else quiet := quiet_ Q := @ endif # If the user is running make -s (silent mode), suppress echoing of # commands ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) quiet := silent_ endif export quiet Q KBUILD_VERBOSE # 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 clean-targets := %clean no-dot-config-targets := $(clean-targets) \ uninstall debug cloc \ cscope TAGS tags MAP gtags \ xenversion config-build := n need-config := y ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) need-config := n endif endif ifneq ($(filter %config,$(MAKECMDGOALS)),) config-build := y endif # CLANG_FLAGS needs to be calculated before calling Kconfig ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) CLANG_FLAGS := ifeq ($(TARGET_ARCH),x86) # The tests to select whether the integrated assembler is usable need to happen # before testing any assembler features, or else the result of the tests would # be stale if the integrated assembler is not used. # Older clang's built-in assembler doesn't understand .skip with labels: # https://bugs.llvm.org/show_bug.cgi?id=27369 t1 = $(call as-insn,$(CC),".L0: .L1: .skip (.L1 - .L0)",,-no-integrated-as) # Check whether clang asm()-s support .include. t2 = $(call as-insn,$(CC) -I$(BASEDIR)/include,".include \"asm-x86/indirect_thunk_asm.h\"",,-no-integrated-as) # Check whether clang keeps .macro-s between asm()-s: # https://bugs.llvm.org/show_bug.cgi?id=36110 t3 = $(call as-insn,$(CC),".macro FOO;.endm"$(close); asm volatile $(open)".macro FOO;.endm",-no-integrated-as) CLANG_FLAGS += $(call or,$(t1),$(t2),$(t3)) endif CLANG_FLAGS += -Werror=unknown-warning-option CFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS endif export root-make-done := y endif # root-make-done # Shorthand for kconfig kconfig = -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) HOSTCC="$(HOSTCC)" HOSTCXX="$(HOSTCXX)" ifeq ($(config-build),y) # =========================================================================== # *config targets only - make sure prerequisites are updated, and descend # in tools/kconfig to make the *config target config: FORCE $(MAKE) $(kconfig) $@ # Config.mk tries to include .config file, don't try to remake it %/.config: ; %config: FORCE $(MAKE) $(kconfig) $@ else # !config-build ifeq ($(need-config),y) -include include/config/auto.conf # Read in dependencies to all Kconfig* files, make sure to run syncconfig if # changes are detected. -include include/config/auto.conf.cmd # Allow people to just run `make` as before and not force them to configure $(KCONFIG_CONFIG): $(MAKE) $(kconfig) defconfig # The actual configuration files used during the build are stored in # include/generated/ and include/config/. Update them if .config is newer than # include/config/auto.conf (which mirrors .config). # # This exploits the 'multi-target pattern rule' trick. # The syncconfig should be executed only once to make all the targets. include/config/%.conf include/config/%.conf.cmd: $(KCONFIG_CONFIG) $(MAKE) $(kconfig) syncconfig ifeq ($(CONFIG_DEBUG),y) CFLAGS += -O1 else CFLAGS += -O2 endif ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS += -fno-omit-frame-pointer else CFLAGS += -fomit-frame-pointer endif CFLAGS += -nostdinc -fno-builtin -fno-common CFLAGS += -Werror -Wredundant-decls -Wno-pointer-arith $(call cc-option-add,CFLAGS,CC,-Wvla) CFLAGS += -pipe -D__XEN__ -include $(BASEDIR)/include/xen/config.h CFLAGS-$(CONFIG_DEBUG_INFO) += -g ifneq ($(CONFIG_CC_IS_CLANG),y) # Clang doesn't understand this command line argument, and doesn't appear to # have a suitable alternative. The resulting compiled binary does function, # but has an excessively large symbol table. CFLAGS += -Wa,--strip-local-absolute endif AFLAGS += -D__ASSEMBLY__ CFLAGS += $(CFLAGS-y) # allow extra CFLAGS externally via EXTRA_CFLAGS_XEN_CORE CFLAGS += $(EXTRA_CFLAGS_XEN_CORE) # Most CFLAGS are safe for assembly files: # -std=gnu{89,99} gets confused by #-prefixed end-of-line comments # -flto makes no sense and annoys clang AFLAGS += $(filter-out -std=gnu% -flto,$(CFLAGS)) $(AFLAGS-y) # LDFLAGS are only passed directly to $(LD) LDFLAGS += $(LDFLAGS_DIRECT) $(LDFLAGS-y) ifeq ($(CONFIG_UBSAN),y) CFLAGS_UBSAN := -fsanitize=undefined else CFLAGS_UBSAN := endif ifeq ($(CONFIG_LTO),y) CFLAGS += -flto LDFLAGS-$(CONFIG_CC_IS_CLANG) += -plugin LLVMgold.so endif include $(BASEDIR)/arch/$(TARGET_ARCH)/arch.mk # define new variables to avoid the ones defined in Config.mk export XEN_CFLAGS := $(CFLAGS) export XEN_AFLAGS := $(AFLAGS) export XEN_LDFLAGS := $(LDFLAGS) export CFLAGS_UBSAN endif # need-config .PHONY: build install uninstall clean distclean MAP build install uninstall debug clean distclean MAP:: ifneq ($(XEN_TARGET_ARCH),x86_32) $(MAKE) -f Rules.mk _$@ else echo "*** Xen x86/32 target no longer supported!" endif .PHONY: _build _build: $(TARGET)$(CONFIG_XEN_INSTALL_SUFFIX) .PHONY: _install _install: D=$(DESTDIR) _install: T=$(notdir $(TARGET)) _install: Z=$(CONFIG_XEN_INSTALL_SUFFIX) _install: $(TARGET)$(CONFIG_XEN_INSTALL_SUFFIX) [ -d $(D)$(BOOT_DIR) ] || $(INSTALL_DIR) $(D)$(BOOT_DIR) $(INSTALL_DATA) $(TARGET)$(Z) $(D)$(BOOT_DIR)/$(T)-$(XEN_FULLVERSION)$(Z) ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION)$(Z) ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION)$(Z) ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) $(D)$(BOOT_DIR)/$(T)$(Z) [ -d "$(D)$(DEBUG_DIR)" ] || $(INSTALL_DIR) $(D)$(DEBUG_DIR) $(INSTALL_DATA) $(TARGET)-syms $(D)$(DEBUG_DIR)/$(T)-syms-$(XEN_FULLVERSION) $(INSTALL_DATA) $(TARGET)-syms.map $(D)$(DEBUG_DIR)/$(T)-syms-$(XEN_FULLVERSION).map $(INSTALL_DATA) $(KCONFIG_CONFIG) $(D)$(BOOT_DIR)/$(T)-$(XEN_FULLVERSION).config if [ -r $(TARGET).efi -a -n '$(EFI_DIR)' ]; then \ [ -d $(D)$(EFI_DIR) ] || $(INSTALL_DIR) $(D)$(EFI_DIR); \ $(INSTALL_DATA) $(TARGET).efi $(D)$(EFI_DIR)/$(T)-$(XEN_FULLVERSION).efi; \ if [ -e $(TARGET).efi.map ]; then \ $(INSTALL_DATA) $(TARGET).efi.map $(D)$(DEBUG_DIR)/$(T)-$(XEN_FULLVERSION).efi.map; \ fi; \ ln -sf $(T)-$(XEN_FULLVERSION).efi $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION).efi; \ ln -sf $(T)-$(XEN_FULLVERSION).efi $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).efi; \ ln -sf $(T)-$(XEN_FULLVERSION).efi $(D)$(EFI_DIR)/$(T).efi; \ if [ -n '$(EFI_MOUNTPOINT)' -a -n '$(EFI_VENDOR)' ]; then \ $(INSTALL_DATA) $(TARGET).efi $(D)$(EFI_MOUNTPOINT)/efi/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi; \ elif [ "$(D)" = "$(patsubst $(shell cd $(XEN_ROOT) && pwd)/%,%,$(D))" ]; then \ echo 'EFI installation only partially done (EFI_VENDOR not set)' >&2; \ fi; \ fi .PHONY: tests tests: $(MAKE) -f $(BASEDIR)/Rules.mk -C test tests .PHONY: install-tests install-tests: $(MAKE) -f $(BASEDIR)/Rules.mk -C test install .PHONY: _uninstall _uninstall: D=$(DESTDIR) _uninstall: T=$(notdir $(TARGET)) _uninstall: Z=$(CONFIG_XEN_INSTALL_SUFFIX) _uninstall: rm -f $(D)$(BOOT_DIR)/$(T)-$(XEN_FULLVERSION).config rm -f $(D)$(BOOT_DIR)/$(T)-$(XEN_FULLVERSION)$(Z) rm -f $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION)$(Z) rm -f $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION)$(Z) rm -f $(D)$(BOOT_DIR)/$(T)$(Z) rm -f $(D)$(DEBUG_DIR)/$(T)-syms-$(XEN_FULLVERSION) rm -f $(D)$(DEBUG_DIR)/$(T)-syms-$(XEN_FULLVERSION).map rm -f $(D)$(EFI_DIR)/$(T)-$(XEN_FULLVERSION).efi rm -f $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION).efi rm -f $(D)$(DEBUG_DIR)/$(T)-$(XEN_FULLVERSION).efi.map rm -f $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).efi rm -f $(D)$(EFI_DIR)/$(T).efi rm -f $(D)$(EFI_MOUNTPOINT)/efi/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi .PHONY: _debug _debug: $(OBJDUMP) -D -S $(TARGET)-syms > $(TARGET).s .PHONY: _clean _clean: delete-unfresh-files $(MAKE) -C tools clean $(MAKE) $(clean) include $(MAKE) $(clean) common $(MAKE) $(clean) drivers $(MAKE) $(clean) xsm $(MAKE) $(clean) crypto $(MAKE) $(clean) arch/arm $(MAKE) $(clean) arch/x86 $(MAKE) $(clean) test $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) SRCARCH=$(SRCARCH) clean find . \( -name "*.o" -o -name ".*.d" -o -name ".*.d2" \ -o -name "*.gcno" -o -name ".*.cmd" \) -exec rm -f {} \; rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map *~ core rm -f include/asm-*/asm-offsets.h rm -f .banner .PHONY: _distclean _distclean: clean rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out GTAGS GPATH GRTAGS GSYMS .config $(TARGET).gz: $(TARGET) gzip -n -f -9 < $< > $@.new mv $@.new $@ $(TARGET): delete-unfresh-files $(MAKE) -C tools $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm [ -e arch/$(TARGET_ARCH)/efi ] && for f in boot.c runtime.c compat.c efi.h;\ do test -r arch/$(TARGET_ARCH)/efi/$$f || \ ln -nsf ../../../common/efi/$$f arch/$(TARGET_ARCH)/efi/; \ done; \ true $(MAKE) -f $(BASEDIR)/Rules.mk -C include $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s $(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $@ # drivers/char/console.o contains static banner/compile info. Blow it away. # Don't refresh these files during e.g., 'sudo make install' .PHONY: delete-unfresh-files delete-unfresh-files: @if [ ! -r include/xen/compile.h -o -O include/xen/compile.h ]; then \ rm -f include/xen/compile.h; \ fi .banner: Makefile @if which figlet >/dev/null 2>&1 ; then \ echo " Xen $(XEN_FULLVERSION)" | figlet -f tools/xen.flf > $@.tmp; \ else \ echo " Xen $(XEN_FULLVERSION)" > $@.tmp; \ fi @mv -f $@.tmp $@ # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. include/xen/compile.h: include/xen/compile.h.in .banner @sed -e 's/@@date@@/$(XEN_BUILD_DATE)/g' \ -e 's/@@time@@/$(XEN_BUILD_TIME)/g' \ -e 's/@@whoami@@/$(XEN_WHOAMI)/g' \ -e 's/@@domain@@/$(XEN_DOMAIN)/g' \ -e 's/@@hostname@@/$(XEN_BUILD_HOST)/g' \ -e 's!@@compiler@@!$(shell $(CC) $(CFLAGS) --version 2>&1 | head -1)!g' \ -e 's/@@version@@/$(XEN_VERSION)/g' \ -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ -e 's!@@changeset@@!$(shell tools/scmversion $(XEN_ROOT) || echo "unavailable")!g' \ < include/xen/compile.h.in > $@.new @cat .banner @sed -rf tools/process-banner.sed < .banner >> $@.new @mv -f $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s @(set -e; \ echo "/*"; \ echo " * DO NOT MODIFY."; \ echo " *"; \ echo " * This file was auto-generated from $<"; \ echo " *"; \ echo " */"; \ echo ""; \ echo "#ifndef __ASM_OFFSETS_H__"; \ echo "#define __ASM_OFFSETS_H__"; \ echo ""; \ sed -rne "/^[^#].*==>/{s:.*==>(.*)<==.*:\1:; s: [\$$#]: :; p;}"; \ echo ""; \ echo "#endif") <$< >$@ SUBDIRS = xsm arch/$(TARGET_ARCH) common drivers test define all_sources ( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \ find include -name 'asm-*' -prune -o -name '*.h' -print; \ find $(SUBDIRS) -name '*.[chS]' -print ) endef define set_exuberant_flags exuberant_flags=`$1 --version 2>/dev/null | (grep -iq exuberant && \ echo "-I __initdata,__exitdata,__acquires,__releases \ -I EXPORT_SYMBOL \ --extra=+f --c-kinds=+px") || true` endef .PHONY: xenversion xenversion: @echo $(XEN_FULLVERSION) .PHONY: TAGS TAGS: set -e; rm -f TAGS; \ $(call set_exuberant_flags,etags); \ $(all_sources) | xargs etags $$exuberant_flags -a .PHONY: tags tags: set -e; rm -f tags; \ $(call set_exuberant_flags,ctags); \ $(all_sources) | xargs ctags $$exuberant_flags -a .PHONY: gtags gtags: set -e; rm -f GTAGS GSYMS GPATH GRTAGS $(all_sources) | gtags -f - .PHONY: cscope cscope: $(all_sources) > cscope.files cscope -k -b -q .PHONY: _MAP _MAP: $(NM) -n $(TARGET)-syms | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' > System.map %.o %.i %.s: %.c FORCE $(MAKE) -f $(BASEDIR)/Rules.mk -C $(*D) $(@F) %.o %.s: %.S FORCE $(MAKE) -f $(BASEDIR)/Rules.mk -C $(*D) $(@F) %/: FORCE $(MAKE) -f $(BASEDIR)/Rules.mk -C $* built_in.o built_in_bin.o build-intermediate = $(eval $(call build-intermediate-closure,$(1))) define build-intermediate-closure $(1): FORCE $(MAKE) -f $(BASEDIR)/Rules.mk -C $$(@D) $$(@F) endef $(foreach base,arch/x86/mm/guest_walk_% \ arch/x86/mm/hap/guest_walk_%level \ arch/x86/mm/shadow/guest_%, \ $(foreach ext,o i s,$(call build-intermediate,$(base).$(ext)))) .PHONY: cloc cloc: $(eval tmpfile := $(shell mktemp)) $(foreach f, $(shell find $(BASEDIR) -name *.o.d), \ $(eval path := $(dir $(f))) \ $(eval names := $(shell grep -o "[a-zA-Z0-9_/-]*\.[cS]" $(f))) \ $(foreach sf, $(names), \ $(shell if test -f $(path)/$(sf) ; then echo $(path)/$(sf) >> $(tmpfile); fi;))) cloc --list-file=$(tmpfile) rm $(tmpfile) endif #config-build PHONY += FORCE FORCE: # 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)