Skip to content

Commit

Permalink
Makefile: construct the full dependency tree instead of pattern matching
Browse files Browse the repository at this point in the history
Currently, the Makefile assumes that each document can be
independently transformed and thus exposes a flat dependency
hierarchy. This is incorrect because of the way table of contents
(TOC) is generated. When a page is added or removed, its immediate
parent and all of the parent's parents, all the way up to the root
node, need to be recompiled in a bottom-up fashion to regenerate the
TOC in each page.

Use black magic to automatically generate build rules with proper
prerequisites during runtime. The idea is to mirror the hierarchy in the
document: every section has a dependency to its subsections. The rules
are generated by iterating through each directory in the entire file
system tree.

Signed-off-by: Göktürk Yüksek <gokturk@binghamton.edu>
  • Loading branch information
gktrk authored and ulm committed Apr 2, 2016
1 parent 7f647d3 commit 7977d86
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
text_files := $(shell find -name "text.xml" | sed -e "s/text.xml$$/index.html/")
ALL_DIRS := $(shell find -name "text.xml" -exec dirname {} +)
text_files := $(addsuffix /index.html,$(ALL_DIRS))
image_files := $(shell find -name "*.svg" | sed -e "s/svg$$/png/")

all: prereq $(text_files) $(image_files)
Expand All @@ -7,17 +8,33 @@ prereq:
@type -p convert &>/dev/null || { echo "media-gfx/imagemagick with corefonts, svg and truetype required" >&2; exit 1; }; \
type -p xsltproc &>/dev/null || { echo "dev-libs/libxslt is required" >&2; exit 1; }

%index.html : %text.xml devbook.xsl
xsltproc devbook.xsl $< > $@

# Someone should figure out a way to put this to the pattern
index.html : text.xml devbook.xsl
xsltproc devbook.xsl $< > $@

%.png : %.svg
convert $< $@

clean:
@find . -name "*.png" -a \! -path "./icons/*" -exec rm -v {} +
@find . -name "index.html" -exec rm -v {} +

# Given a directory with text.xml in it, return its immediate children as prerequisites
# Hypothetical example:
# INPUT: "./archs" "./archs/amd64 ./archs/x86 ./ebuild-writing ./appendices"
# OUTPUT: ./archs/amd64/index.html ./archs/amd64/index.html
define get_prerequisites =
$(addsuffix /index.html,$(foreach subdir,$(2),$(if $(subst $(1)/,,$(dir $(subdir))),,$(subdir))))
endef

# Given a directory with text.xml in it, genereate a complete build rule with prerequisites
# Hypothetical example:
# INPUT: "./archs" "./archs/amd64 ./archs/x86 ./ebuild-writing ./appendices"
# OUTPUT ./archs/index.html: ./archs/text.xml devbook.xsl ./archs/amd64/index.html ./archs/x86/index.html
# xsltproc devbook.xsl ./archs/text.xml > ./archs/index.html
define generate_rule =
$(1)/index.html: $(1)/text.xml devbook.xsl $(call get_prerequisites,$(1),$(2))
xsltproc devbook.xsl $$< > $$@
endef

# This generates individual build rules for all the text files by
# iterating over all the directories in the file system tree
$(foreach dir,$(ALL_DIRS),$(eval $(call generate_rule,$(dir),$(filter-out $(dir),$(ALL_DIRS)))))

.PHONY: all prereq clean

0 comments on commit 7977d86

Please sign in to comment.