1# -*- mode: Makefile; -*-
2
3ifeq ($(filter /%,$(XEN_ROOT)),)
4$(error XEN_ROOT must be absolute)
5endif
6
7# Convenient variables
8comma   := ,
9squote  := '
10empty   :=
11space   := $(empty) $(empty)
12
13# fallback for older make
14realpath = $(wildcard $(foreach file,$(1),$(shell cd -P $(dir $(file)) && echo "$$PWD/$(notdir $(file))")))
15or       = $(if $(strip $(1)),$(1),$(if $(strip $(2)),$(2),$(if $(strip $(3)),$(3),$(if $(strip $(4)),$(4)))))
16
17-include $(XEN_ROOT)/.config
18
19XEN_COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/ \
20                         -e s/i86pc/x86_32/ -e s/amd64/x86_64/ \
21                         -e s/armv7.*/arm32/ -e s/armv8.*/arm64/ \
22                         -e s/aarch64/arm64/)
23
24XEN_TARGET_ARCH     ?= $(XEN_COMPILE_ARCH)
25XEN_OS              ?= $(shell uname -s)
26
27CONFIG_$(XEN_OS) := y
28
29SHELL     ?= /bin/sh
30
31# Tools to run on system hosting the build
32HOSTCFLAGS  = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
33HOSTCFLAGS += -fno-strict-aliasing
34
35DISTDIR     ?= $(XEN_ROOT)/dist
36DESTDIR     ?= /
37
38# Allow phony attribute to be listed as dependency rather than fake target
39.PHONY: .phony
40
41# If we are not cross-compiling, default HOSTC{C/XX} to C{C/XX}
42ifeq ($(XEN_TARGET_ARCH), $(XEN_COMPILE_ARCH))
43HOSTCC ?= $(CC)
44HOSTCXX ?= $(CXX)
45endif
46
47# Use Clang/LLVM instead of GCC?
48clang ?= n
49ifeq ($(clang),n)
50gcc := y
51HOSTCC ?= gcc
52HOSTCXX ?= g++
53else
54gcc := n
55HOSTCC ?= clang
56HOSTCXX ?= clang++
57endif
58
59DEPS_INCLUDE = $(addsuffix .d2, $(basename $(wildcard $(DEPS))))
60DEPS_RM = $(DEPS) $(DEPS_INCLUDE)
61
62%.d2: %.d
63	sed "s! $$PWD/! !" $^ >$@.tmp && mv -f $@.tmp $@
64
65include $(XEN_ROOT)/config/$(XEN_OS).mk
66include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk
67
68# arguments: variable, common path part, path to test, if yes, if no
69define setvar_dir
70  ifndef $(1)
71    ifneq (,$(wildcard $(2)$(3)))
72      $(1) ?= $(2)$(4)
73    else
74      $(1) ?= $(2)$(5)
75    endif
76  endif
77endef
78
79ifneq ($(EXTRA_PREFIX),)
80EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
81EXTRA_LIB += $(EXTRA_PREFIX)/lib
82endif
83
84PYTHON      ?= python
85PYTHON_PREFIX_ARG ?= --prefix="$(prefix)"
86# The above requires that prefix contains *no spaces*. This variable is here
87# to permit the user to set PYTHON_PREFIX_ARG to '' to workaround this bug:
88#  https://bugs.launchpad.net/ubuntu/+bug/362570
89
90# cc-option: Check if compiler supports first option, else fall back to second.
91#
92# This is complicated by the fact that unrecognised -Wno-* options:
93#   (a) are ignored unless the compilation emits a warning; and
94#   (b) even then produce a warning rather than an error
95# To handle this we do a test compile, passing the option-under-test, on a code
96# fragment that will always produce a warning (integer assigned to pointer).
97# We then grep for the option-under-test in the compiler's output, the presence
98# of which would indicate an "unrecognized command-line option" warning/error.
99#
100# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
101cc-option = $(shell if test -z "`echo 'void*p=1;' | \
102              $(1) $(2) -S -o /dev/null -x c - 2>&1 | grep -- $(2) -`"; \
103              then echo "$(2)"; else echo "$(3)"; fi ;)
104
105# cc-option-add: Add an option to compilation flags, but only if supported.
106# Usage: $(call cc-option-add CFLAGS,CC,-march=winchip-c6)
107cc-option-add = $(eval $(call cc-option-add-closure,$(1),$(2),$(3)))
108define cc-option-add-closure
109    ifneq ($$(call cc-option,$$($(2)),$(3),n),n)
110        $(1) += $(3)
111    endif
112endef
113
114cc-options-add = $(foreach o,$(3),$(call cc-option-add,$(1),$(2),$(o)))
115
116# cc-ver: Check compiler against the version requirement. Return boolean 'y'/'n'.
117# Usage: ifeq ($(call cc-ver,$(CC),ge,0x030400),y)
118cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
119           '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -$(2) $$(($(3))) ]; \
120           then echo y; else echo n; fi ;)
121
122# cc-ver-check: Check compiler is at least specified version, else fail.
123# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
124cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
125define cc-ver-check-closure
126    ifeq ($$(call cc-ver,$$($(1)),ge,$(2)),n)
127        override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
128        cc-option := n
129    endif
130endef
131
132# cc-ifversion: Check compiler version and take branch accordingly
133# Usage $(call cc-ifversion,lt,0x040700,string_if_y,string_if_n)
134cc-ifversion = $(shell [ $(call cc-ver,$(CC),$(1),$(2)) = "y" ] \
135				&& echo $(3) || echo $(4))
136
137# Require GCC v4.1+
138check-$(gcc) = $(call cc-ver-check,CC,0x040100,"Xen requires at least gcc-4.1")
139$(eval $(check-y))
140
141ld-ver-build-id = $(shell $(1) --build-id 2>&1 | \
142					grep -q build-id && echo n || echo y)
143
144export XEN_HAS_BUILD_ID ?= n
145ifeq ($(call ld-ver-build-id,$(LD)),n)
146build_id_linker :=
147else
148CFLAGS += -DBUILD_ID
149export XEN_HAS_BUILD_ID=y
150build_id_linker := --build-id=sha1
151endif
152
153ifndef XEN_HAS_CHECKPOLICY
154    CHECKPOLICY ?= checkpolicy
155    XEN_HAS_CHECKPOLICY := $(shell $(CHECKPOLICY) -h 2>&1 | grep -q xen && echo y || echo n)
156    export XEN_HAS_CHECKPOLICY
157endif
158
159# as-insn: Check whether assembler supports an instruction.
160# Usage: cflags-y += $(call as-insn "insn",option-yes,option-no)
161as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \
162                       | $(1) $(filter-out -M% %.d -include %/include/xen/config.h,$(AFLAGS)) \
163                              -c -x c -o /dev/null - 2>&1),$(4),$(3))
164
165# as-insn-check: Add an option to compilation flags, but only if insn is
166#                supported by assembler.
167# Usage: $(call as-insn-check CFLAGS,CC,"nop",-DHAVE_GAS_NOP)
168as-insn-check = $(eval $(call as-insn-check-closure,$(1),$(2),$(3),$(4)))
169define as-insn-check-closure
170    ifeq ($$(call as-insn,$$($(2)),$(3),y,n),y)
171        $(1) += $(4)
172    endif
173endef
174
175define buildmakevars2shellvars
176    export PREFIX="$(prefix)";                                            \
177    export XEN_SCRIPT_DIR="$(XEN_SCRIPT_DIR)";                            \
178    export XEN_ROOT="$(XEN_ROOT)"
179endef
180
181#
182# Compare $(1) and $(2) and replace $(2) with $(1) if they differ
183#
184# Typically $(1) is a newly generated file and $(2) is the target file
185# being regenerated. This prevents changing the timestamp of $(2) only
186# due to being auto regenereated with the same contents.
187define move-if-changed
188	if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
189endef
190
191BUILD_MAKE_VARS := sbindir bindir LIBEXEC LIBEXEC_BIN libdir SHAREDIR \
192                   XENFIRMWAREDIR XEN_CONFIG_DIR XEN_SCRIPT_DIR XEN_LOCK_DIR \
193                   XEN_RUN_DIR XEN_PAGING_DIR XEN_DUMP_DIR XEN_LOG_DIR \
194                   XEN_LIB_DIR XEN_RUN_STORED
195
196buildmakevars2file = $(eval $(call buildmakevars2file-closure,$(1)))
197define buildmakevars2file-closure
198    $(1): .phony
199	rm -f $(1).tmp; \
200	$(foreach var, $(BUILD_MAKE_VARS), \
201	          echo "$(var)=\"$($(var))\"" >>$(1).tmp;) \
202	$(call move-if-changed,$(1).tmp,$(1))
203endef
204
205buildmakevars2header = $(eval $(call buildmakevars2header-closure,$(1)))
206define buildmakevars2header-closure
207    $(1): .phony
208	rm -f $(1).tmp; \
209	$(foreach var, $(BUILD_MAKE_VARS), \
210	          echo "#define $(var) \"$($(var))\"" >>$(1).tmp;) \
211	$(call move-if-changed,$(1).tmp,$(1))
212endef
213
214CFLAGS += -fno-strict-aliasing
215
216CFLAGS += -std=gnu99
217
218CFLAGS += -Wall -Wstrict-prototypes
219
220$(call cc-option-add,HOSTCFLAGS,HOSTCC,-Wdeclaration-after-statement)
221$(call cc-option-add,CFLAGS,CC,-Wdeclaration-after-statement)
222$(call cc-option-add,CFLAGS,CC,-Wno-unused-but-set-variable)
223$(call cc-option-add,CFLAGS,CC,-Wno-unused-local-typedefs)
224
225LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i))
226CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
227LDFLAGS += $(foreach i, $(PREPEND_LIB), -L$(i))
228CFLAGS += $(foreach i, $(PREPEND_INCLUDES), -I$(i))
229ifeq ($(XEN_TOOLS_RPATH),y)
230LDFLAGS += -Wl,-rpath,$(libdir)
231endif
232APPEND_LDFLAGS += $(foreach i, $(APPEND_LIB), -L$(i))
233APPEND_CFLAGS += $(foreach i, $(APPEND_INCLUDES), -I$(i))
234
235EMBEDDED_EXTRA_CFLAGS := -nopie -fno-stack-protector -fno-stack-protector-all
236EMBEDDED_EXTRA_CFLAGS += -fno-exceptions
237
238XEN_EXTFILES_URL ?= http://xenbits.xen.org/xen-extfiles
239# All the files at that location were downloaded from elsewhere on
240# the internet.  The original download URL is preserved as a comment
241# near the place in the Xen Makefiles where the file is used.
242
243# Where to look for inlined subtrees (for example, from a tarball)
244QEMU_UPSTREAM_INTREE ?= $(XEN_ROOT)/tools/qemu-xen
245QEMU_TRADITIONAL_INTREE ?= $(XEN_ROOT)/tools/qemu-xen-traditional
246
247
248# Handle legacy options
249ifneq (,$(SEABIOS_UPSTREAM_TAG))
250SEABIOS_UPSTREAM_REVISION ?= $(SEABIOS_UPSTREAM_TAG)
251endif
252ifneq (,$(QEMU_REMOTE))
253QEMU_TRADITIONAL_URL ?= $(QEMU_REMOTE)
254endif
255ifneq (,$(CONFIG_QEMU))
256QEMU_TRADITIONAL_LOC ?= $(CONFIG_QEMU)
257endif
258ifneq (,$(QEMU_TAG))
259QEMU_TRADITIONAL_REVISION ?= $(QEMU_TAG)
260endif
261
262ifeq ($(GIT_HTTP),y)
263OVMF_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/ovmf.git
264QEMU_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/qemu-xen.git
265QEMU_TRADITIONAL_URL ?= http://xenbits.xen.org/git-http/qemu-xen-traditional.git
266SEABIOS_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/seabios.git
267MINIOS_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/mini-os.git
268else
269OVMF_UPSTREAM_URL ?= git://xenbits.xen.org/ovmf.git
270QEMU_UPSTREAM_URL ?= git://xenbits.xen.org/qemu-xen.git
271QEMU_TRADITIONAL_URL ?= git://xenbits.xen.org/qemu-xen-traditional.git
272SEABIOS_UPSTREAM_URL ?= git://xenbits.xen.org/seabios.git
273MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
274endif
275OVMF_UPSTREAM_REVISION ?= 947f3737abf65fda63f3ffd97fddfa6986986868
276QEMU_UPSTREAM_REVISION ?= qemu-xen-4.10.0
277MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.10.0
278# Mon Oct 16 16:36:41 2017 +0100
279# Update Xen header files again
280
281SEABIOS_UPSTREAM_REVISION ?= rel-1.10.2
282# Wed Jun 22 14:53:24 2016 +0800
283# fw/msr_feature_control: add support to set MSR_IA32_FEATURE_CONTROL
284
285ETHERBOOT_NICS ?= rtl8139 8086100e
286
287
288QEMU_TRADITIONAL_REVISION ?= xen-4.10.0
289# Fri Sep 15 19:37:27 2017 +0100
290# qemu-xen-traditional: Link against xentoolcore
291
292# Specify which qemu-dm to use. This may be `ioemu' to use the old
293# Mercurial in-tree version, or a local directory, or a git URL.
294# QEMU_UPSTREAM_LOC ?= `pwd`/$(XEN_ROOT)/../qemu-xen.git
295
296# Defaults for subtree locations
297QEMU_TRADITIONAL_LOC ?= $(call or,$(wildcard $(QEMU_TRADITIONAL_INTREE)),\
298                                  $(QEMU_TRADITIONAL_URL))
299
300QEMU_UPSTREAM_LOC ?= $(call or,$(wildcard $(QEMU_UPSTREAM_INTREE)),\
301                               $(QEMU_UPSTREAM_URL))
302
303# Short answer -- do not enable this unless you know what you are
304# doing and are prepared for some pain.
305
306CONFIG_TESTS       ?= y
307