diff options
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | rules.mak | 36 |
2 files changed, 46 insertions, 7 deletions
@@ -1028,6 +1028,14 @@ build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) \ $(wildcard $(SRC_PATH)/docs/$1/*.rst.inc) \ $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py +# Macro to write out the rule and dependencies for building manpages +# Usage: $(call define-manpage-rule,manualname,manpage1 manpage2...[,extradeps]) +# 'extradeps' is optional, and specifies extra files (eg .hx files) that +# the manual page depends on. +define define-manpage-rule +$(call atomic,$(foreach manpage,$2,$(MANUAL_BUILDDIR)/$1/$(manpage)),$(call manual-deps,$1) $3) + $(call build-manual,$1,man) +endef $(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel) $(call build-manual,devel,html) @@ -1041,14 +1049,9 @@ $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs) $(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system) $(call build-manual,system,html) -$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop) - $(call build-manual,interop,man) - -$(MANUAL_BUILDDIR)/interop/qemu-nbd.8: $(call manual-deps,interop) - $(call build-manual,interop,man) +$(call define-manpage-rule,interop,qemu-ga.8 qemu-nbd.8) -$(MANUAL_BUILDDIR)/system/qemu-block-drivers.7: $(call manual-deps,system) - $(call build-manual,system,man) +$(call define-manpage-rule,system,qemu-block-drivers.7) $(MANUAL_BUILDDIR)/index.html: $(SRC_PATH)/docs/index.html.in qemu-version.h @mkdir -p "$(MANUAL_BUILDDIR)" @@ -399,3 +399,39 @@ GEN_SUBST = $(call quiet-command, \ %.json: %.json.in $(call GEN_SUBST) + +# Support for building multiple output files by atomically executing +# a single rule which depends on several input files (so the rule +# will be executed exactly once, not once per output file, and +# not multiple times in parallel.) For more explanation see: +# https://www.cmcrossroads.com/article/atomic-rules-gnu-make + +# Given a space-separated list of filenames, create the name of +# a 'sentinel' file to use to indicate that they have been built. +# We use fixed text on the end to avoid accidentally triggering +# automatic pattern rules, and . on the start to make the file +# not show up in ls output. +sentinel = .$(subst $(SPACE),_,$(subst /,_,$1)).sentinel. + +# Define an atomic rule that builds multiple outputs from multiple inputs. +# To use: +# $(call atomic,out1 out2 ...,in1 in2 ...) +# <TAB>rule to do the operation +# +# Make 4.3 will have native support for this, and you would be able +# to instead write: +# out1 out2 ... &: in1 in2 ... +# <TAB>rule to do the operation +# +# The way this works is that it creates a make rule +# "out1 out2 ... : sentinel-file ; @:" which says that the sentinel +# depends on the dependencies, and the rule to do that is "do nothing". +# Then we have a rule +# "sentinel-file : in1 in2 ..." +# whose commands start with "touch sentinel-file" and then continue +# with the rule text provided by the user of this 'atomic' function. +# The foreach... is there to delete the sentinel file if any of the +# output files don't exist, so that we correctly rebuild in that situation. +atomic = $(eval $1: $(call sentinel,$1) ; @:) \ + $(call sentinel,$1) : $2 ; @touch $$@ \ + $(foreach t,$1,$(if $(wildcard $t),,$(shell rm -f $(call sentinel,$1)))) |