| 1 | # Makefile for QEMU. |
| 2 | |
| 3 | ifneq ($(words $(subst :, ,$(CURDIR))), 1) |
| 4 | $(error main directory cannot contain spaces nor colons) |
| 5 | endif |
| 6 | |
| 7 | # Always point to the root of the build tree (needs GNU make). |
| 8 | BUILD_DIR=$(CURDIR) |
| 9 | |
| 10 | # Before including a proper config-host.mak, assume we are in the source tree |
| 11 | SRC_PATH=. |
| 12 | |
| 13 | # Don't use implicit rules or variables |
| 14 | # we have explicit rules for everything |
| 15 | MAKEFLAGS += -rR |
| 16 | |
| 17 | SHELL = bash -o pipefail |
| 18 | |
| 19 | # Usage: $(call quiet-command,command and args,"NAME","args to print") |
| 20 | # This will run "command and args", and either: |
| 21 | # if V=1 just print the whole command and args |
| 22 | # otherwise print the 'quiet' output in the format " NAME args to print" |
| 23 | # NAME should be a short name of the command, 7 letters or fewer. |
| 24 | # If called with only a single argument, will print nothing in quiet mode. |
| 25 | quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1 |
| 26 | quiet-@ = $(if $(V),,@) |
| 27 | quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3) |
| 28 | |
| 29 | UNCHECKED_GOALS := TAGS gtags cscope ctags dist \ |
| 30 | help check-help print-% \ |
| 31 | docker docker-% lcitool-refresh vm-help vm-test vm-build-% |
| 32 | |
| 33 | all: |
| 34 | .PHONY: all clean distclean recurse-all dist msi FORCE |
| 35 | |
| 36 | # Don't try to regenerate Makefile or configure |
| 37 | # We don't generate any of them |
| 38 | Makefile: ; |
| 39 | configure: ; |
| 40 | |
| 41 | # All following code might depend on configuration variables |
| 42 | ifneq ($(wildcard config-host.mak),) |
| 43 | include config-host.mak |
| 44 | |
| 45 | include Makefile.prereqs |
| 46 | Makefile.prereqs: config-host.mak |
| 47 | |
| 48 | # 0. ensure the build tree is okay |
| 49 | |
| 50 | # Check that we're not trying to do an out-of-tree build from |
| 51 | # a tree that's been used for an in-tree build. |
| 52 | ifneq ($(realpath $(SRC_PATH)),$(realpath .)) |
| 53 | ifneq ($(wildcard $(SRC_PATH)/config-host.mak),) |
| 54 | $(error This is an out of tree build but your source tree ($(SRC_PATH)) \ |
| 55 | seems to have been used for an in-tree build. You can fix this by running \ |
| 56 | "$(MAKE) distclean && rm -rf *-linux-user *-softmmu" in your source tree) |
| 57 | endif |
| 58 | endif |
| 59 | |
| 60 | # force a rerun of configure if config-host.mak is too old or corrupted |
| 61 | ifeq ($(MESON),) |
| 62 | .PHONY: config-host.mak |
| 63 | x := $(shell rm -rf meson-private meson-info meson-logs) |
| 64 | endif |
| 65 | ifeq ($(NINJA),) |
| 66 | .PHONY: config-host.mak |
| 67 | x := $(shell rm -rf meson-private meson-info meson-logs) |
| 68 | else |
| 69 | export NINJA |
| 70 | endif |
| 71 | ifeq ($(wildcard build.ninja),) |
| 72 | .PHONY: config-host.mak |
| 73 | x := $(shell rm -rf meson-private meson-info meson-logs) |
| 74 | endif |
| 75 | ifeq ($(origin prefix),file) |
| 76 | .PHONY: config-host.mak |
| 77 | x := $(shell rm -rf meson-private meson-info meson-logs) |
| 78 | endif |
| 79 | |
| 80 | # 1. ensure config-host.mak is up-to-date |
| 81 | config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/scripts/meson-buildoptions.sh \ |
| 82 | $(SRC_PATH)/pythondeps.toml $(SRC_PATH)/VERSION |
| 83 | @echo config-host.mak is out-of-date, running configure |
| 84 | @if test -f meson-private/coredata.dat; then \ |
| 85 | ./config.status --skip-meson; \ |
| 86 | else \ |
| 87 | ./config.status; \ |
| 88 | fi |
| 89 | |
| 90 | # 2. meson.stamp exists if meson has run at least once (so ninja reconfigure |
| 91 | # works), but otherwise never needs to be updated |
| 92 | |
| 93 | meson-private/coredata.dat: meson.stamp |
| 94 | meson.stamp: config-host.mak |
| 95 | @touch meson.stamp |
| 96 | |
| 97 | # 3. ensure meson-generated build files are up-to-date |
| 98 | |
| 99 | ninja-cmd-goals = |
| 100 | |
| 101 | ifneq ($(NINJA),) |
| 102 | Makefile.ninja: build.ninja |
| 103 | $(quiet-@){ \ |
| 104 | echo 'ninja-targets = \'; \ |
| 105 | $(NINJA) -t targets all | sed 's/:.*//; $$!s/$$/ \\/'; \ |
| 106 | echo 'build-files = \'; \ |
| 107 | $(NINJA) -t query build.ninja | sed -n '1,/^ input:/d; /^ outputs:/q; s/$$/ \\/p'; \ |
| 108 | } > $@.tmp && mv $@.tmp $@ |
| 109 | -include Makefile.ninja |
| 110 | endif |
| 111 | |
| 112 | ifneq ($(MESON),) |
| 113 | # The path to meson always points to pyvenv/bin/meson, but the absolute |
| 114 | # paths could change. In that case, force a regeneration of build.ninja. |
| 115 | # Note that this invocation of $(NINJA), just like when Make rebuilds |
| 116 | # Makefiles, does not include -n. |
| 117 | build.ninja: build.ninja.stamp |
| 118 | $(build-files): |
| 119 | build.ninja.stamp: meson.stamp $(build-files) |
| 120 | @if test "$$(cat build.ninja.stamp)" = "$(MESON)" && test -n "$(NINJA)"; then \ |
| 121 | $(NINJA) build.ninja; \ |
| 122 | else \ |
| 123 | echo "$(MESON) setup --reconfigure $(SRC_PATH)"; \ |
| 124 | $(MESON) setup --reconfigure $(SRC_PATH); \ |
| 125 | fi && echo "$(MESON)" > $@ |
| 126 | |
| 127 | Makefile.mtest: build.ninja scripts/mtest2make.py |
| 128 | $(MESON) introspect --targets --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@ |
| 129 | -include Makefile.mtest |
| 130 | |
| 131 | .PHONY: update-buildoptions |
| 132 | all update-buildoptions: $(SRC_PATH)/scripts/meson-buildoptions.sh |
| 133 | $(SRC_PATH)/scripts/meson-buildoptions.sh: $(SRC_PATH)/meson_options.txt $(SRC_PATH)/scripts/meson-buildoptions.py |
| 134 | $(MESON) introspect --buildoptions $(SRC_PATH)/meson.build | $(PYTHON) \ |
| 135 | scripts/meson-buildoptions.py > $@.tmp && mv $@.tmp $@ |
| 136 | endif |
| 137 | |
| 138 | # 4. Rules to bridge to other makefiles |
| 139 | |
| 140 | ifneq ($(NINJA),) |
| 141 | # Filter out long options to avoid flags like --no-print-directory which |
| 142 | # may result in false positive match for MAKE.n |
| 143 | MAKE.n = $(findstring n,$(firstword $(filter-out --%,$(MAKEFLAGS)))) |
| 144 | MAKE.k = $(findstring k,$(firstword $(filter-out --%,$(MAKEFLAGS)))) |
| 145 | MAKE.q = $(findstring q,$(firstword $(filter-out --%,$(MAKEFLAGS)))) |
| 146 | MAKE.nq = $(if $(word 2, $(MAKE.n) $(MAKE.q)),nq) |
| 147 | NINJAFLAGS = \ |
| 148 | $(if $V,-v) \ |
| 149 | $(if $(MAKE.n), -n) \ |
| 150 | $(if $(MAKE.k), -k0) \ |
| 151 | $(filter-out -j, \ |
| 152 | $(or $(filter -l% -j%, $(MAKEFLAGS)), \ |
| 153 | $(if $(filter --jobserver-auth=%, $(MAKEFLAGS)),, -j1))) \ |
| 154 | -d keepdepfile |
| 155 | ninja-cmd-goals += $(or $(MAKECMDGOALS), all) |
| 156 | ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g)) |
| 157 | |
| 158 | makefile-targets := build.ninja ctags TAGS cscope dist clean |
| 159 | # "ninja -t targets" also lists all prerequisites. If build system |
| 160 | # files are marked as PHONY, however, Make will always try to execute |
| 161 | # "ninja build.ninja". |
| 162 | ninja-targets := $(filter-out $(build-files) $(makefile-targets), $(ninja-targets)) |
| 163 | .PHONY: $(ninja-targets) run-ninja |
| 164 | $(ninja-targets): run-ninja |
| 165 | |
| 166 | # Use "| cat" to give Ninja a more "make-y" output. Use "+" to bypass the |
| 167 | # --output-sync line. |
| 168 | run-ninja: config-host.mak |
| 169 | ifneq ($(filter $(ninja-targets), $(ninja-cmd-goals)),) |
| 170 | +$(if $(MAKE.nq),@:,$(quiet-@)$(NINJA) $(NINJAFLAGS) \ |
| 171 | $(sort $(filter $(ninja-targets), $(ninja-cmd-goals))) | cat) |
| 172 | endif |
| 173 | endif |
| 174 | |
| 175 | else # config-host.mak does not exist |
| 176 | ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail)) |
| 177 | $(error Please call configure before running make) |
| 178 | endif |
| 179 | endif # config-host.mak does not exist |
| 180 | |
| 181 | SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet) |
| 182 | |
| 183 | include $(SRC_PATH)/tests/Makefile.include |
| 184 | |
| 185 | all: recurse-all |
| 186 | |
| 187 | SUBDIR_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(SUBDIRS))) |
| 188 | .PHONY: $(SUBDIR_RULES) |
| 189 | $(SUBDIR_RULES): |
| 190 | $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),) |
| 191 | |
| 192 | .PHONY: recurse-all recurse-clean |
| 193 | recurse-all: $(addsuffix /all, $(SUBDIRS)) |
| 194 | recurse-clean: $(addsuffix /clean, $(SUBDIRS)) |
| 195 | recurse-distclean: $(addsuffix /distclean, $(SUBDIRS)) |
| 196 | |
| 197 | ###################################################################### |
| 198 | |
| 199 | clean: recurse-clean |
| 200 | -$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean || : |
| 201 | -$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) clean-ctlist || : |
| 202 | find . \( -name '*.so' -o -name '*.dll' -o \ |
| 203 | -name '*.[oda]' -o -name '*.gcno' \) -type f \ |
| 204 | ! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-aarch64.a \ |
| 205 | ! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-arm.a \ |
| 206 | -exec rm {} + |
| 207 | rm -f TAGS cscope.* *~ */*~ |
| 208 | @$(MAKE) -Ctests/qemu-iotests clean |
| 209 | |
| 210 | VERSION = $(shell cat $(SRC_PATH)/VERSION) |
| 211 | |
| 212 | dist: qemu-$(VERSION).tar.xz |
| 213 | |
| 214 | qemu-%.tar.xz: |
| 215 | $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.xz,%,$@)" |
| 216 | |
| 217 | distclean: clean recurse-distclean |
| 218 | -$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || : |
| 219 | rm -f config-host.mak Makefile.prereqs |
| 220 | rm -f tests/tcg/*/config-target.mak tests/tcg/config-host.mak |
| 221 | rm -f config.status |
| 222 | rm -f roms/seabios/config.mak |
| 223 | rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols |
| 224 | rm -f *-config-target.h *-config-devices.mak *-config-devices.h |
| 225 | rm -rf meson-private meson-logs meson-info compile_commands.json |
| 226 | rm -f Makefile.ninja Makefile.mtest build.ninja.stamp meson.stamp |
| 227 | rm -f config.log |
| 228 | rm -f linux-headers/asm |
| 229 | rm -Rf .sdk qemu-bundle |
| 230 | |
| 231 | find-src-path = find "$(SRC_PATH)" -path "$(SRC_PATH)/meson" -prune -o \ |
| 232 | -path "$(SRC_PATH)/.pc" -prune -o \ |
| 233 | -type l -prune -o \( -name "*.[chsS]" -o -name "*.[ch].inc" \) |
| 234 | |
| 235 | .PHONY: ctags |
| 236 | ctags: |
| 237 | $(call quiet-command, \ |
| 238 | rm -f "$(SRC_PATH)/"tags, \ |
| 239 | "CTAGS", "Remove old tags") |
| 240 | $(call quiet-command, \ |
| 241 | $(find-src-path) -exec ctags \ |
| 242 | -f "$(SRC_PATH)/"tags --append {} +, \ |
| 243 | "CTAGS", "Re-index $(SRC_PATH)") |
| 244 | |
| 245 | .PHONY: gtags |
| 246 | gtags: |
| 247 | $(call quiet-command, \ |
| 248 | rm -f "$(SRC_PATH)/"GTAGS; \ |
| 249 | rm -f "$(SRC_PATH)/"GRTAGS; \ |
| 250 | rm -f "$(SRC_PATH)/"GPATH, \ |
| 251 | "GTAGS", "Remove old $@ files") |
| 252 | $(call quiet-command, \ |
| 253 | (cd $(SRC_PATH) && \ |
| 254 | $(find-src-path) -print | gtags -f -), \ |
| 255 | "GTAGS", "Re-index $(SRC_PATH)") |
| 256 | |
| 257 | .PHONY: TAGS |
| 258 | TAGS: |
| 259 | $(call quiet-command, \ |
| 260 | rm -f "$(SRC_PATH)/"TAGS, \ |
| 261 | "TAGS", "Remove old $@") |
| 262 | $(call quiet-command, \ |
| 263 | $(find-src-path) -exec etags \ |
| 264 | -f "$(SRC_PATH)/"TAGS --append {} +, \ |
| 265 | "TAGS", "Re-index $(SRC_PATH)") |
| 266 | |
| 267 | .PHONY: cscope |
| 268 | cscope: |
| 269 | $(call quiet-command, \ |
| 270 | rm -f "$(SRC_PATH)/"cscope.* , \ |
| 271 | "cscope", "Remove old $@ files") |
| 272 | $(call quiet-command, \ |
| 273 | ($(find-src-path) -print | sed -e 's,^\./,,' \ |
| 274 | > "$(SRC_PATH)/cscope.files"), \ |
| 275 | "cscope", "Create file list") |
| 276 | $(call quiet-command, \ |
| 277 | cscope -b -i"$(SRC_PATH)/cscope.files" \ |
| 278 | -f"$(SRC_PATH)"/cscope.out, \ |
| 279 | "cscope", "Re-index $(SRC_PATH)") |
| 280 | |
| 281 | # Needed by "meson install" |
| 282 | export DESTDIR |
| 283 | |
| 284 | include $(SRC_PATH)/tests/lcitool/Makefile.include |
| 285 | include $(SRC_PATH)/tests/docker/Makefile.include |
| 286 | include $(SRC_PATH)/tests/vm/Makefile.include |
| 287 | |
| 288 | print-help-run = printf " %-30s - %s\\n" "$1" "$2" |
| 289 | print-help = @$(call print-help-run,$1,$2) |
| 290 | |
| 291 | .PHONY: update-linux-vdso |
| 292 | update-linux-vdso: |
| 293 | @for m in $(SRC_PATH)/linux-user/*/Makefile.vdso; do \ |
| 294 | $(MAKE) $(SUBDIR_MAKEFLAGS) -C $$(dirname $$m) -f Makefile.vdso \ |
| 295 | SRC_PATH=$(SRC_PATH) BUILD_DIR=$(BUILD_DIR); \ |
| 296 | done |
| 297 | |
| 298 | .PHONY: help |
| 299 | help: |
| 300 | @echo 'Generic targets:' |
| 301 | $(call print-help,all,Build all) |
| 302 | $(call print-help,dir/file.o,Build specified target only) |
| 303 | $(call print-help,install,Install QEMU, documentation and tools) |
| 304 | $(call print-help,ctags/gtags/TAGS,Generate tags file for editors) |
| 305 | $(call print-help,cscope,Generate cscope index) |
| 306 | $(call print-help,sparse,Run sparse on the QEMU source) |
| 307 | @echo '' |
| 308 | @echo 'Cleaning targets:' |
| 309 | $(call print-help,clean,Remove most generated files but keep the config) |
| 310 | $(call print-help,distclean,Remove all generated files) |
| 311 | $(call print-help,dist,Build a distributable tarball) |
| 312 | @echo '' |
| 313 | @echo 'Linux-user targets:' |
| 314 | $(call print-help,update-linux-vdso,Build linux-user vdso images) |
| 315 | @echo '' |
| 316 | @echo 'Test targets:' |
| 317 | $(call print-help,check,Run all tests (check-help for details)) |
| 318 | $(call print-help,bench,Run all benchmarks) |
| 319 | $(call print-help,lcitool-help,Help about targets for managing build environment manifests) |
| 320 | $(call print-help,docker-help,Help about targets running tests inside containers) |
| 321 | $(call print-help,vm-help,Help about targets running tests inside VM) |
| 322 | @echo '' |
| 323 | @echo 'Documentation targets:' |
| 324 | $(call print-help,html man,Build documentation in specified format) |
| 325 | @echo '' |
| 326 | ifneq ($(filter msi, $(ninja-targets)),) |
| 327 | @echo 'Windows targets:' |
| 328 | $(call print-help,installer,Build NSIS-based installer for QEMU) |
| 329 | $(call print-help,msi,Build MSI-based installer for qemu-ga) |
| 330 | @echo '' |
| 331 | endif |
| 332 | $(call print-help,$(MAKE) [targets],(quiet build, default)) |
| 333 | $(call print-help,$(MAKE) V=1 [targets],(verbose build)) |
| 334 | |
| 335 | # will delete the target of a rule if commands exit with a nonzero exit status |
| 336 | .DELETE_ON_ERROR: |
| 337 | |
| 338 | print-%: |
| 339 | @echo '$*=$($*)' |