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