1# -*- mode: Makefile; -*-
2
3ifeq ($(filter /%,$(XEN_ROOT)),)
4$(error XEN_ROOT must be absolute)
5endif
6
7# Convenient variables
8comma   := ,
9open    := (
10close   := )
11squote  := '
12#' Balancing squote, to help syntax highlighting
13empty   :=
14space   := $(empty) $(empty)
15
16# fallback for older make
17realpath = $(wildcard $(foreach file,$(1),$(shell cd -P $(dir $(file)) && echo "$$PWD/$(notdir $(file))")))
18or       = $(if $(strip $(1)),$(1),$(if $(strip $(2)),$(2),$(if $(strip $(3)),$(3),$(if $(strip $(4)),$(4)))))
19
20-include $(XEN_ROOT)/.config
21
22ifeq ($(origin XEN_COMPILE_ARCH), undefined)
23XEN_COMPILE_ARCH    := $(shell uname -m | sed -e s/i.86/x86_32/ \
24                         -e s/i86pc/x86_32/ -e s/amd64/x86_64/ \
25                         -e s/armv7.*/arm32/ -e s/armv8.*/arm64/ \
26                         -e s/aarch64/arm64/)
27endif
28
29XEN_TARGET_ARCH     ?= $(XEN_COMPILE_ARCH)
30ifeq ($(origin XEN_OS), undefined)
31XEN_OS              := $(shell uname -s)
32endif
33
34CONFIG_$(XEN_OS) := y
35
36SHELL     ?= /bin/sh
37
38# Tools to run on system hosting the build
39HOSTCFLAGS  = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
40HOSTCFLAGS += -fno-strict-aliasing
41
42DISTDIR     ?= $(XEN_ROOT)/dist
43DESTDIR     ?= /
44
45# Allow phony attribute to be listed as dependency rather than fake target
46.PHONY: .phony
47
48# If we are not cross-compiling, default HOSTC{C/XX} to C{C/XX}
49ifeq ($(XEN_TARGET_ARCH), $(XEN_COMPILE_ARCH))
50HOSTCC ?= $(CC)
51HOSTCXX ?= $(CXX)
52endif
53
54# Use Clang/LLVM instead of GCC?
55clang ?= n
56ifeq ($(clang),n)
57gcc := y
58HOSTCC ?= gcc
59HOSTCXX ?= g++
60else
61gcc := n
62HOSTCC ?= clang
63HOSTCXX ?= clang++
64endif
65
66DEPS_INCLUDE = $(addsuffix .d2, $(basename $(wildcard $(DEPS))))
67DEPS_RM = $(DEPS) $(DEPS_INCLUDE)
68
69%.d2: %.d
70	sed "s!\(^\| \)$$PWD/! !" $^ >$@.tmp && mv -f $@.tmp $@
71
72include $(XEN_ROOT)/config/$(XEN_OS).mk
73include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk
74
75ifneq ($(EXTRA_PREFIX),)
76EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
77EXTRA_LIB += $(EXTRA_PREFIX)/lib
78endif
79
80PYTHON      ?= python
81PYTHON_PREFIX_ARG ?= --prefix="$(prefix)"
82# The above requires that prefix contains *no spaces*. This variable is here
83# to permit the user to set PYTHON_PREFIX_ARG to '' to workaround this bug:
84#  https://bugs.launchpad.net/ubuntu/+bug/362570
85
86# cc-option: Check if compiler supports first option, else fall back to second.
87#
88# This is complicated by the fact that with most gcc versions unrecognised
89# -Wno-* options:
90#   (a) are ignored unless the compilation emits a warning; and
91#   (b) even then produce a warning rather than an error
92# Further Clang also only warns for unrecognised -W* options.  To handle this
93# we do a test compile, substituting -Wno-* by -W* and adding -Werror.  This
94# way all unrecognised options are diagnosed uniformly, allowing us to merely
95# check exit status.
96#
97# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
98cc-option = $(shell if $(1) $(2:-Wno-%=-W%) -Werror -c -o /dev/null -x c /dev/null >/dev/null 2>&1; \
99              then echo "$(2)"; else echo "$(3)"; fi ;)
100
101# cc-option-add: Add an option to compilation flags, but only if supported.
102# Usage: $(call cc-option-add CFLAGS,CC,-march=winchip-c6)
103cc-option-add = $(eval $(call cc-option-add-closure,$(1),$(2),$(3)))
104define cc-option-add-closure
105    ifneq ($$(call cc-option,$$($(2)),$(3),n),n)
106        $(1) += $(3)
107    endif
108endef
109
110cc-options-add = $(foreach o,$(3),$(call cc-option-add,$(1),$(2),$(o)))
111
112# cc-ver: Check compiler against the version requirement. Return boolean 'y'/'n'.
113# Usage: ifeq ($(call cc-ver,$(CC),ge,0x030400),y)
114cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
115           '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -$(2) $$(($(3))) ]; \
116           then echo y; else echo n; fi ;)
117
118# cc-ver-check: Check compiler is at least specified version, else fail.
119# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
120cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
121define cc-ver-check-closure
122    ifeq ($$(call cc-ver,$$($(1)),ge,$(2)),n)
123        override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
124        cc-option := n
125    endif
126endef
127
128# Require GCC v4.1+
129check-$(gcc) = $(call cc-ver-check,CC,0x040100,"Xen requires at least gcc-4.1")
130$(eval $(check-y))
131
132ld-ver-build-id = $(shell $(1) --build-id 2>&1 | \
133					grep -q build-id && echo n || echo y)
134
135export XEN_HAS_BUILD_ID ?= n
136ifeq ($(call ld-ver-build-id,$(LD)),n)
137build_id_linker :=
138else
139CFLAGS += -DBUILD_ID
140export XEN_HAS_BUILD_ID=y
141build_id_linker := --build-id=sha1
142endif
143
144define buildmakevars2shellvars
145    export PREFIX="$(prefix)";                                            \
146    export XEN_SCRIPT_DIR="$(XEN_SCRIPT_DIR)";                            \
147    export XEN_ROOT="$(XEN_ROOT)"
148endef
149
150#
151# Compare $(1) and $(2) and replace $(2) with $(1) if they differ
152#
153# Typically $(1) is a newly generated file and $(2) is the target file
154# being regenerated. This prevents changing the timestamp of $(2) only
155# due to being auto regenereated with the same contents.
156define move-if-changed
157	if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
158endef
159
160BUILD_MAKE_VARS := sbindir bindir LIBEXEC LIBEXEC_BIN libdir SHAREDIR \
161                   XENFIRMWAREDIR XEN_CONFIG_DIR XEN_SCRIPT_DIR XEN_LOCK_DIR \
162                   XEN_RUN_DIR XEN_PAGING_DIR XEN_DUMP_DIR XEN_LOG_DIR \
163                   XEN_LIB_DIR XEN_RUN_STORED
164
165buildmakevars2file = $(eval $(call buildmakevars2file-closure,$(1)))
166define buildmakevars2file-closure
167    $(1): .phony
168	rm -f $(1).tmp; \
169	$(foreach var, $(BUILD_MAKE_VARS), \
170	          echo "$(var)=\"$($(var))\"" >>$(1).tmp;) \
171	$(call move-if-changed,$(1).tmp,$(1))
172endef
173
174CFLAGS += -fno-strict-aliasing
175
176CFLAGS += -std=gnu99
177
178CFLAGS += -Wall -Wstrict-prototypes
179
180$(call cc-option-add,CFLAGS,CC,-Wno-unused-but-set-variable)
181$(call cc-option-add,CFLAGS,CC,-Wno-unused-local-typedefs)
182
183LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i))
184CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
185LDFLAGS += $(foreach i, $(PREPEND_LIB), -L$(i))
186CFLAGS += $(foreach i, $(PREPEND_INCLUDES), -I$(i))
187ifeq ($(XEN_TOOLS_RPATH),y)
188LDFLAGS += -Wl,-rpath,$(libdir)
189endif
190APPEND_LDFLAGS += $(foreach i, $(APPEND_LIB), -L$(i))
191APPEND_CFLAGS += $(foreach i, $(APPEND_INCLUDES), -I$(i))
192
193EMBEDDED_EXTRA_CFLAGS := -fno-pie -fno-stack-protector -fno-stack-protector-all
194EMBEDDED_EXTRA_CFLAGS += -fno-exceptions -fno-asynchronous-unwind-tables
195
196XEN_EXTFILES_URL ?= https://xenbits.xen.org/xen-extfiles
197# All the files at that location were downloaded from elsewhere on
198# the internet.  The original download URL is preserved as a comment
199# near the place in the Xen Makefiles where the file is used.
200
201# Where to look for inlined subtrees (for example, from a tarball)
202QEMU_UPSTREAM_INTREE ?= $(XEN_ROOT)/tools/qemu-xen
203QEMU_TRADITIONAL_INTREE ?= $(XEN_ROOT)/tools/qemu-xen-traditional
204
205
206# Handle legacy options
207ifneq (,$(SEABIOS_UPSTREAM_TAG))
208SEABIOS_UPSTREAM_REVISION ?= $(SEABIOS_UPSTREAM_TAG)
209endif
210ifneq (,$(QEMU_REMOTE))
211QEMU_TRADITIONAL_URL ?= $(QEMU_REMOTE)
212endif
213ifneq (,$(CONFIG_QEMU))
214QEMU_TRADITIONAL_LOC ?= $(CONFIG_QEMU)
215endif
216ifneq (,$(QEMU_TAG))
217QEMU_TRADITIONAL_REVISION ?= $(QEMU_TAG)
218endif
219
220OVMF_UPSTREAM_URL ?= https://xenbits.xen.org/git-http/ovmf.git
221OVMF_UPSTREAM_REVISION ?= ba91d0292e593df8528b66f99c1b0b14fadc8e16
222
223QEMU_UPSTREAM_URL ?= https://xenbits.xen.org/git-http/qemu-xen.git
224QEMU_UPSTREAM_REVISION ?= qemu-xen-4.19.0
225
226MINIOS_UPSTREAM_URL ?= https://xenbits.xen.org/git-http/mini-os.git
227MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.19.0
228
229SEABIOS_UPSTREAM_URL ?= https://xenbits.xen.org/git-http/seabios.git
230SEABIOS_UPSTREAM_REVISION ?= rel-1.16.3
231
232ETHERBOOT_NICS ?= rtl8139 8086100e
233
234
235QEMU_TRADITIONAL_URL ?= https://xenbits.xen.org/git-http/qemu-xen-traditional.git
236QEMU_TRADITIONAL_REVISION ?= xen-4.19.0
237# Wed Jul 15 10:01:40 2020 +0100
238# qemu-trad: remove Xen path dependencies
239
240# Specify which qemu-dm to use. This may be `ioemu' to use the old
241# Mercurial in-tree version, or a local directory, or a git URL.
242# QEMU_UPSTREAM_LOC ?= `pwd`/$(XEN_ROOT)/../qemu-xen.git
243
244# Defaults for subtree locations
245QEMU_TRADITIONAL_LOC ?= $(call or,$(wildcard $(QEMU_TRADITIONAL_INTREE)),\
246                                  $(QEMU_TRADITIONAL_URL))
247
248QEMU_UPSTREAM_LOC ?= $(call or,$(wildcard $(QEMU_UPSTREAM_INTREE)),\
249                               $(QEMU_UPSTREAM_URL))
250
251CONFIG_TESTS       ?= y
252