X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/991cf40919b58de83c8695ef344a1cefa4a8ccbb..6d78d92dfa675156640925421f33aa0535f6f46f:/GNUmakefile diff --git a/GNUmakefile b/GNUmakefile index 6eece6b..2c77723 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -36,7 +36,6 @@ override define makefileinfo ║│ • rm │║ ║│ • sed │║ ║│ • sleep │║ -║│ • stat │║ ║│ • test │║ ║│ • touch │║ ║│ • tr │║ @@ -117,7 +116,6 @@ PRINTF := printf RM := rm SED := sed SLEEP := sleep -STAT := stat TEST := test TOUCH := touch TR := tr @@ -173,7 +171,7 @@ THISDIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) # By default, `find´ will ignore files which begin with a period and those which are likely to cause problems for `make´. EXTRAFINDRULES := EXTRAFINDINCLUDERULES := -FINDRULES := ! '(' '(' -name '[.-]*' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*"{*' -o -name '*}"*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a $(EXTRAFINDRULES),) +FINDRULES := ! '(' '(' -name '[.-]*' -o -name '*[][*?:|$$%\#\\; ]*' -o -name '*[)]' ')' -a -prune ')'$(if $(EXTRAFINDRULES), -a $(EXTRAFINDRULES),) FINDINCLUDERULES := $(FINDRULES)$(if $(EXTRAFINDINCLUDERULES), -a $(EXTRAFINDINCLUDERULES),) # The list of magic files to use when determining media types. @@ -195,7 +193,10 @@ EXTRATRANSFORMS := TRANSFORMS := $(sort $(patsubst ./%,%,$(wildcard $(THISDIR)/transforms/*.xslt)) $(EXTRATRANSFORMS)) # List of types which should be treated as X·M·L. -XMLTYPES := application/xml text/xml +# +# Types which start with a `+´ are suffixes and match any type which +# ends accordingly. +XMLTYPES := application/xml text/xml +xml ifdef GIT ifneq ($(wildcard $(THISDIR)/.git),) @@ -219,11 +220,11 @@ endif # # • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive ›: # Generates archive files from parse results. -# -# • ‹ urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged ›: -# Generates paginated files from parse results. MODE := urn:fdc:ladys.computer:20231231:Shu1She4:mode:default +# Set to a non·empty value to silence informative messages. +QUIET := + # Set to a non·empty value to print all commands as they run. VERBOSE := @@ -252,18 +253,28 @@ override comma := , # (callable) Quote the given string for use within shell calls. override quote = '$(subst ','"'"',$1)' -# Outputs an `@´ to silence rules, unless `VERBOSE´ is nonempty. -override silent := $(if $(VERBOSE),,@) - # (callable) Get the modified time of the provided file. # -# This is messy; there is no portable way of using `stat´. +# Only the date·time information available via `ls -l´ is supported; that is, only minute precision for files newer than six months, and only day precision for files which are older. +# This is, unfortunately, the best that can be done in pure Posix as of now. +# +# There is an easier implementation which provides the full date·time by archiving an empty file and then reading it back out of the archive :— +# +# $(shell LC_TIME=POSIX TZ=UTC0 $(TOUCH) -m -r $(callquote,$1) $(BUILDDIR)/.mtime && $(PAX) -w -x ustar $(BUILDDIR)/.mtime | $(PAX) -v -o 'listopt=%(mtime=%Y-%m-%dT%H:%M:%SZ)T') +# +# However, it depends on the `listopt´ option in `pax´, which (despite being specified in Posix) no implementations actually support. # # ☡ This variable creates a subshell every time it is computed. -override modtime = $(shell if $(STAT) --version 2> /dev/null | $(GREP) -q GNU; then $(DATE) -u -d "@$$(TZ= $(STAT) -c '%Y' $(call quote,$1))" '+%Y-%m-%dT%H:%M:%SZ'; else TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$1); fi) +override modtime = $(shell { $(DATE) -u '+%Y-%m'; LC_TIME=POSIX TZ=UTC0 ls -q -A -l $(call quote,$1) | $(SED) 's/\([^ ]* \{1,\}\)\{5\}\(\([^ ]* \{1,\}\)\{3\}\).*/\2/;s/ \([0123456789]\) / 0\1 /;s/Jan/01/;s/Feb/02/;s/Mar/03/;s/Apr/04/;s/May/05/;s/Jun/06/;s/Jul/07/;s/Aug/08/;s/Sep/09/;s/Oct/10/;s/Nov/11/;s/Dec/12/;s/\([0123456789]\{2\}\) *\([0123456789]\{2\}\) *\([0123456789]\{4\}\)/\3-\1-\2T00:00:00Z/;s/\([0123456789]\{2\}\) *\([0123456789]\{2\}\) *\([0123456789:]\{5\}\)/XXXX-\1-\2T\3:00Z/'; } | $(TR) -d ' ' | $(AWK) -F '-' 'NR==1{year=$$1;month=$$2}$$1=="XXXX"&&$$2<=month{print year"-"$$2"-"$$3}$$1=="XXXX"&&$$2>month{print year-1"-"$$2"-"$$3}NR>1&&$$1!="XXXX"') # ─ ¶ Recipe Variable Definitions ───────────────────────────────────── +# Outputs an `@´ to silence rules, unless `VERBOSE´ is non·empty. +override silent := $(if $(VERBOSE),,@) + +# (callable) Only perform the rule if `QUIET` is not set. +override inform = $(if $(QUIET),,@$1) + # (callable) Check to see if the given directory exists and create it if not. override ensuredirectory = if $(TEST) ! -d $(call quote,$1); then $(MKDIR) -p $(call quote,$1); fi @@ -281,14 +292,8 @@ override xpath = $(XMLLINT) --xpath $(call quote,$1) $(call quote,$2) > /dev/nul # (callable) Extract the value of the text nodes in the provided X·M·L document and print them to `stdout´. override extracttext = $(PRINTF) '%s' '<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"><output method="text" encoding="UTF-8"/></transform>' | $(XSLTPROC) --nonet --novalid - $(call quote,$1) -# (callable) List the files in the provided directory which are associated with the provided filename, one per line. -override associatedfiles = $(LS) -1 $(call quote,$1) | $(SED) '/.*"{.*}".*/!d;s/^\(.*\)"{.*}"\(.*\)$$/\1\2|&/' | $(GREP) -F -e $(call quote,$2|) | $(SED) 's/^.*|//' - -# (callable) Remove files associated with the provided file. -override removeassociatedfiles = ASSOCIATED="$$($(call associatedfiles,$(dir $1),$(notdir $1)) | $(TR) '\n' ' ')"; if $(TEST) -n "$$ASSOCIATED"; then cd $(call quote,$(dir $1)) && $(PRINTF) '%s\n' "$$ASSOCIATED" | $(SED) 's/ \{2,\}/ /g;s/^ //;s/ $$//' | $(TR) ' ' '\n' | $(xargsmultiquote) | $(XARGS) -E '' $(RM); fi - # (callable) Process the provided transformation result and output the result to the provided location, given the provided relative path. -override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then { $(PRINTF) '%s\n' 'begin-base64 644 -'; $(call extracttext,$1) | $(TR) -d '\t\n\f\r '; $(PRINTF) '%s\n' '===='; } | $(UUDECODE) -o /dev/stdout > $(call quote,$2); $(call removeassociatedfiles,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; $(call removeassociatedfiles,$2); elif $(call xpath,//*[local-name()="page" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/paged/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged'; else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); $(call removeassociatedfiles,$2); fi +override processresultto = if $(call xpath,/*[local-name()="raw-text" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(call extracttext,$1) > $(call quote,$2); elif $(call xpath,/*[local-name()="base64-binary" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then { $(PRINTF) '%s\n' 'begin-base64 644 -'; $(call extracttext,$1) | $(TR) -d '\t\n\f\r '; $(PRINTF) '\n%s\n' '===='; } | $(UUDECODE) -o /dev/stdout > $(call quote,$2); elif $(call xpath,/*[local-name()="archive" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$1); then $(MAKE) -f $(call quote,$(abspath $(THISDIR)/GNUmakefile)) $(call quote,$2) NAME=$(call quote,$3) SRC=$(call quote,$1) BUILDDIR=$(call quote,$(BUILDDIR)/archive/$3) DESTDIR=$(call quote,$(patsubst %/,%,$(dir $2))) MODE='urn:fdc:ladys.computer:20231231:Shu1She4:mode:archive'; else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); fi # ━ § BEGIN DEFAULT MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -347,8 +352,10 @@ ifneq ($(wildcard $(BUILDDIR)/parser.xslt),) override plaintexttypes := $(filter-out $(XMLTYPES),$(shell $(XMLLINT) --xpath '/*/*[@name="书社:parsers"]//*[namespace-uri()="http://www.w3.org/1999/xhtml" and local-name()="dd"]/text()' $(call quote,$(BUILDDIR)/parser.xslt))) endif -# (callable) Get all of the files (source and includes) which have the given types. -override filesoftype = $(foreach type,$1,$(patsubst %|$(type),%,$(filter %|$(type),$(types)))) +# (callable) Get all of the files (source and includes) which have the provided types. +# +# If a provided type begins with a `+´, it is analysed as a suffix, and all matching types will be used. +override filesoftype = $(foreach typeorsuffix,$1,$(foreach type,$(if $(filter +%,$(typeorsuffix)),$(sort $(foreach suffixedtype,$(filter %$(typeorsuffix),$(types)),$(lastword $(subst |, ,$(suffixedtype))))),$(typeorsuffix)),$(patsubst %|$(type),%,$(filter %|$(type),$(types))))) # Build up collections of various file types. override xmlfiles := $(call filesoftype,$(XMLTYPES)) @@ -502,11 +509,11 @@ install : $(call installed,$(recursivefiles) $(installablefiles)) ; # List all source files and includes and their computed types. list : - @$(PRINTF) '%b' $(call quote,$(foreach file,$(sort $(sourcefiles)) $(sort $(sourceincludes)),\0033[1m$(file)\0033[22m|$(call typeoffile,$(file))|[\0033[3m$(if $(filter $(file),$(xmlfiles)),xml,$(if $(filter $(file),$(plaintextfiles)),text,asset))$(if $(filter $(file),$(sourceincludes)),|include,)\0033[23m]$(if $(call dependencies,$(file))$(call recursives,$(file)), $(strip $(foreach recursive,$(call recursives,$(file)),\0033[93;41m•|Recursive|Dependency|\0033[39;49m|$(recursive)) $(foreach dependency,$(call dependencies,$(file)),\0033[2m•|Dependency|\0033[22m|$(dependency))))$(if $(filter $(file),$(sourcefiles)), →|<\0033[4m/$(call destination,$(file))\0033[24m>,) )) | $(TR) ' |' '\n ' + @$(PRINTF) '%b' $(call quote,$(foreach file,$(sort $(sourcefiles)) $(sort $(sourceincludes)),\0033[1m$(file)\0033[22m|$(call typeoffile,$(file))|[\0033[3m$(if $(filter $(file),$(xmlfiles)),xml,$(if $(filter $(file),$(plaintextfiles)),text,asset))$(if $(filter $(file),$(sourceincludes)),|include,)\0033[23m] Modified:|$(call modtime,$(file))$(if $(call dependencies,$(file))$(call recursives,$(file)), $(strip $(foreach recursive,$(call recursives,$(file)),\0033[93;41m•|Recursive|Dependency|\0033[39;49m|$(recursive)) $(foreach dependency,$(call dependencies,$(file)),\0033[2m•|Dependency|\0033[22m|$(dependency))))$(if $(filter $(file),$(sourcefiles)), →|<\0033[4m/$(call destination,$(file))\0033[24m>,) )) | $(TR) ' |' '\n ' # Lists out the destinations of all resulting files (relative to `DESTDIR´). listout : - @$(PRINTF) '⛩️📰 书社 Output: %s\n' $(call quote,$(foreach file,$(sort $(sourcefiles)),$(call destination,$(file)))) + @$(PRINTF) '%s\n' $(call quote,$(foreach file,$(sort $(sourcefiles)),$(call destination,$(file)))) # Destroy installed files. uninstall : @@ -514,7 +521,7 @@ uninstall : # Raise an error when attempting to build any files with recursive dependencies. $(call built,$(recursivefiles)) : - @$(PRINTF) '%b\n' $(call quote,\0033[93;41mError:\0033[39;49m `$(call unbuilt,$@)´ has recursive dependencies:\n$(subst |, ,$(subst $(space),$(newline),$(foreach recursive,$(call recursives,$(call unbuilt,$@)),•|$(recursive))))) && false + @$(PRINTF) '%b\n' $(call quote,\0033[93;41mError:\0033[39;49m `$(call unbuilt,$@)´ has recursive dependencies:\n$(subst |, ,$(subst $(space),$(newline),$(foreach recursive,$(call recursives,$(call unbuilt,$@)),•|$(recursive))))) >&2 && false # Add as a prerequisite to treat the target as tho it were phony. FORCE : ; @@ -541,10 +548,10 @@ ifneq ($(typeupdates)$(wildcard $(BUILDDIR)/dependencies)$(wildcard $(BUILDDIR)/ $(THISDIR)/GNUmakefile :: $(BUILDDIR)/dependencies $(BUILDDIR)/destinations $(silent)$(TOUCH) $(THISDIR)/GNUmakefile ifeq ($(typeupdates),) - @if $(TEST) ! -f $(call quote,$(BUILDDIR)/.update-types); then $(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m'; fi + $(call inform,if $(TEST) ! -f $(call quote,$(BUILDDIR)/.update-types); then $(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' >&2; fi) else $(silent)$(RM) $(call quote,$(BUILDDIR)/.update-types) - @$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' + $(call inform,$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' >&2) endif endif @@ -557,7 +564,7 @@ ifeq ($(typeupdates),) $(THISDIR)/GNUmakefile :: $(BUILDDIR)/magic.mgc $(BUILDDIR)/parser.xslt $(silent)$(TOUCH) $(THISDIR)/GNUmakefile $(silent)$(RM) -f $(call quote,$(BUILDDIR)/dependencies) $(call quote,$(BUILDDIR)/destinations) - @$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m' + $(call inform,$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m' >&2) $(silent)$(SLEEP) 1 $(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types) endif @@ -574,18 +581,18 @@ $(call magicfile,$(MAGIC)) : $(BUILDDIR)/magic/% : $$(call magicsource,$$@) # It must be updated if any of the files in the magic directory change. $(BUILDDIR)/magic.mgc : $(call diffprereqs,magic,$(sort $(call magicfile,$(MAGIC)))) $(foreach outdated,$(filter-out $^,$(wildcard $(BUILDDIR)/magic/*)),$(silent)$(RM) $(call quote,$(outdated))$(newline)) - @$(PRINTF) '%s\n' 'Compiling new magic…' + $(call inform,$(PRINTF) '%s\n' 'Compiling new magic…' >&2) $(silent)$(call ensuredirectory,$(dir $@)) $(silent)cd $(call quote,$(BUILDDIR)) && $(FILE) -C -m $(call quote,$(realpath $(BUILDDIR)/magic)) $(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types) # Generate the main parser. $(BUILDDIR)/parser.catalog : $(call diffprereqs,parsers,$(sort $(PARSERS))) - @$(PRINTF) '%s\n' 'Generating catalog of parsers…' + $(call inform,$(PRINTF) '%s\n' 'Generating catalog of parsers…' >&2) $(silent)$(XMLCATALOG) --create --noout $(call quote,$@) $(foreach parser,$(PARSERS),$(silent){ $(call id,$(parser)); $(PRINTF) '%s\n' $(call quote,$(call fileuri,$(parser))) '--noout' $(call quote,$@); } | $(xargsmultiquote) | $(XARGS) -E '' $(XMLCATALOG) --add uri$(newline)) $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2parser.xslt - @$(PRINTF) '%s\n' 'Generating main parser…' + $(call inform,$(PRINTF) '%s\n' 'Generating main parser…' >&2) $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2parser.xslt) $(call quote,$<) $(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types) @@ -594,7 +601,7 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars # Even plain X·M·L files are parsed, because they may contain X·H·T·M·L `<script>´ elements which contain other kinds of data. # Asset files are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s. $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates) - @$(PRINTF) '%s\n' $(call quote,Processing `$<´…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Processing `$<´…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$<)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(call serializexml,$<)) | $(XSLTPROC) --nonet --novalid -o $(call quote,$@) --stringparam BUILDTIME $$($(DATE) -u '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$<)) --stringparam SRCTIME '$(call modtime,$<)' --stringparam CKSUM $$($(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/parser.xslt) -) @@ -602,13 +609,13 @@ $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BU # # This does not depend on actually transforming the files. $(BUILDDIR)/catalog : $(call diffprereqs,sources,$(sort $(sourcefiles) $(sourceincludes))) $(typeupdates) - @$(PRINTF) '%s\n' 'Generating catalog of parsed files…' + $(call inform,$(PRINTF) '%s\n' 'Generating catalog of parsed files…' >&2) $(silent)$(XMLCATALOG) --create --noout $(call quote,$@) $(foreach source,$(sourcefiles) $(sourceincludes),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call localuri,$(source))) $(call quote,$(call fileuri,$(call parsed,$(source)))#$(if $(filter $(source),$(assetfiles)),asset,xml)) --noout $(call quote,$@)$(newline)) # Build a list of dependencies for each parsed file. $(BUILDDIR)/dependencies : $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $(xmlfiles)) $(THISDIR)/lib/catalog2dependencies.xslt - @$(PRINTF) '%s\n' 'Identifying dependencies…' + $(call inform,$(PRINTF) '%s\n' 'Identifying dependencies…' >&2) $(silent)$(TOUCH) $(call quote,$@) $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2dependencies.xslt) $(call quote,$<) @@ -617,41 +624,43 @@ $(BUILDDIR)/dependencies : $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $ # This depends on parsing non·asset source files, but not assets or includes. # It does not require knowing the dependencies. $(BUILDDIR)/destinations : $(BUILDDIR)/catalog $(call parsed,$(filter-out $(assetfiles),$(sourcefiles))) $(THISDIR)/lib/catalog2destinations.xslt - @$(PRINTF) '%s\n' 'Identifying output destinations…' + $(call inform,$(PRINTF) '%s\n' 'Identifying output destinations…' >&2) $(silent)$(TOUCH) $(call quote,$@) $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2destinations.xslt) $(call quote,$<) # Generate the main transform. $(BUILDDIR)/transform.catalog : $(call diffprereqs,transforms,$(sort $(TRANSFORMS))) - @$(PRINTF) '%s\n' 'Generating catalog of transforms…' + $(call inform,$(PRINTF) '%s\n' 'Generating catalog of transforms…' >&2) $(silent)$(XMLCATALOG) --create --noout $(call quote,$@) $(foreach transform,$(TRANSFORMS),$(silent){ $(call id,$(transform)); $(PRINTF) '%s\n' $(call quote,$(call fileuri,$(transform))) '--noout' $(call quote,$@); } | $(xargsmultiquote) | $(XARGS) -E '' $(XMLCATALOG) --add uri$(newline)) $(BUILDDIR)/transform.xslt : $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt - @$(PRINTF) '%s\n' 'Generating main transform…' + $(call inform,$(PRINTF) '%s\n' 'Generating main transform…' >&2) $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<) # Compile the result files using the dependencies as necessary. $(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@))) - @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Compiling </$*>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME $$($(DATE) -u '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME '$(call modtime,$(call uncompiled,$@))' --stringparam IDENTIFIER $(call quote,$(call localuri,$(call uncompiled,$@))) --stringparam PATH $(call quote,/$*) --stringparam CKSUM $$($(CKSUM) $(call quote,$(call uncompiled,$@)) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<) # Create the final files from the compiled results (or error in the case of recursive ones). $(call built,$(compilablefiles)) : $(BUILDDIR)/public/% : $(BUILDDIR)/results/% - @$(PRINTF) '%s\n' $(call quote,Building </$*>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Building </$*>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) + $(silent)$(RM) -f -R $(call quote,$@) $(silent)$(call processresultto,$<,$@,$*) $(call built,$(filter $(assetfiles),$(sourcefiles))) : $(BUILDDIR)/public/% : $$(call unbuilt,$$@) - @$(PRINTF) '%s\n' $(call quote,Building </$*>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Building </$*>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) + $(silent)$(RM) -f -R $(call quote,$@) $(silent)$(CP) $(call quote,$<) $(call quote,$@) # Install compiled files (or error in the case of recursive ones). $(call installed,$(recursivefiles) $(installablefiles)) : $(DESTDIR)/% : $(BUILDDIR)/public/% - @$(PRINTF) '%s\n' $(call quote,Installing </$*>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Installing </$*>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)if $(TEST) -d $(call quote,$<); then $(RM) -f -R $(call quote,$@); $(CP) -R $(call quote,$<) $(call quote,$@); else $(CP) $(call quote,$<) $(call quote,$@); fi - $(silent)for associated in $$($(call associatedfiles,$(dir $<),$(notdir $<))); do $(PRINTF) '%s\n' "$$associated" | $(SED) 's/^\(.*\)"{\(.*\)}"\(.*\)$$/\1\2\3/' | $(xargsquote) | $(XARGS) -E '' $(PRINTF) '%s%s\n' $(call quote,$(dir $@)) | $(xargsquote) | $(XARGS) -E '' $(CP) $(call quote,$(dir $<))"$$associated"; done + $(silent)$(RM) -f -R $(call quote,$@) + $(silent)$(CP) -R $(call quote,$<) $(call quote,$@) # ━ § BEGIN ARCHIVE MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -673,7 +682,7 @@ endif # Reload this make·file if the archive components have changed. $(THISDIR)/GNUmakefile : $(BUILDDIR)/index $(silent)$(TOUCH) $(THISDIR)/GNUmakefile - @$(PRINTF) '%b\n' $(call quote,\0033[1mArchive components for </$(NAME)> updated. Restarting…\0033[22m) + $(call inform,$(PRINTF) '%b\n' $(call quote,\0033[1mArchive components for </$(NAME)> updated. Restarting…\0033[22m) >&2) # ─ ¶ Build Targets ─────────────────────────────────────────────────── @@ -686,7 +695,7 @@ $(BUILDDIR)/extractor.xslt : $(SRC) $(THISDIR)/lib/archive2extractor.xslt # # This target sleeps for 1 second to ensure the resulting index will always be newer than this make·file. $(BUILDDIR)/index : $(BUILDDIR)/extractor.xslt $(SRC) - @$(PRINTF) '%s\n' $(call quote,Extracting components for </$(NAME)>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Extracting components for </$(NAME)>…) >&2) $(silent)$(SLEEP) 1 $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --writesubtree $(call quote,$(dir $@)) $(call quote,$<) $(call quote,$(SRC)) @@ -695,72 +704,19 @@ $(foreach file,$(archivefiles),$(BUILDDIR)/extracted/$(file)) : $(BUILDDIR)/inde # Process each extractor component into its final form. $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) : $(BUILDDIR)/files/% : $(BUILDDIR)/extracted/% - @$(PRINTF) '%s\n' $(call quote,Building </$(NAME)/$*>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Building </$(NAME)/$*>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) + $(silent)$(RM) -f -R $(call quote,$@) $(silent)$(call processresultto,$<,$@,$*) # Archive all components in the file to the destination. # # This is a match‐anything target, with the assumption that this make·file is being called recursively from the default mode. $(DESTDIR)/% : $(SRC) $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) - @$(PRINTF) '%s\n' $(call quote,Archiving </$(NAME)>…) - $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)cd $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(RM) -f -R $(call quote,$(abspath $@)); $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar > $(call quote,$(abspath $@)); fi - -# ━ § BEGIN PAGED MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -else ifeq ($(MODE),urn:fdc:ladys.computer:20231231:Shu1She4:mode:paged) - -# ─ ¶ Non‐Recipe Variable Definitions ───────────────────────────────── - -# Get the list of pages. -ifneq ($(wildcard $(BUILDDIR)/index),) -override pagefiles := $(patsubst ./pages/%,%,$(shell $(CAT) $(call quote,$(BUILDDIR)/index))) -endif - -# ─ ¶ Recipe Variable Definitions ───────────────────────────────────── - -# ─ ¶ Phony Targets ─────────────────────────────────────────────────── - -# ─ ¶ Special Targets ───────────────────────────────────────────────── - -# Reload this make·file if the pages have changed. -$(THISDIR)/GNUmakefile : $(BUILDDIR)/index - $(silent)$(TOUCH) $(THISDIR)/GNUmakefile - @$(PRINTF) '%b\n' $(call quote,\0033[1mPages for </$(NAME)> updated. Restarting…\0033[22m) - -# ─ ¶ Build Targets ─────────────────────────────────────────────────── - -# Build the extractor transform for extracting the pages of the paged source file. -$(BUILDDIR)/extractor.xslt : $(SRC) $(THISDIR)/lib/paged2extractor.xslt - $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --stringparam NAME $(call quote,$(call notdir,$<)) $(call quote,$(THISDIR)/lib/paged2extractor.xslt) $(call quote,$<) - -# Use the extractor transform to extract the paged source file out into its pages. -# -# This target sleeps for 1 second to ensure the resulting index will always be newer than this make·file. -$(BUILDDIR)/index : $(BUILDDIR)/extractor.xslt $(SRC) - @$(PRINTF) '%s\n' $(call quote,Extracting pages for </$(NAME)>…) - $(silent)$(SLEEP) 1 - $(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --writesubtree $(call quote,$(dir $@)) $(call quote,$<) $(call quote,$(SRC)) - -# All other pages are extracted alongside the base. -$(foreach file,$(pagefiles),$(BUILDDIR)/pages/$(file)) : $(BUILDDIR)/index ; - -# Process each page into its final form. -$(foreach file,$(pagefiles),$(BUILDDIR)/public/$(file)) : $(BUILDDIR)/public/% : $(BUILDDIR)/pages/% - @$(PRINTF) '%s\n' $(call quote,Building page `$(subst }",,$(subst "{,,$*))´ of </$(NAME)>…) - $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)$(call processresultto,$<,$@,$*) - -# Archive all components in the file to the destination. -# -# This is a match‐anything target, with the assumption that this make·file is being called recursively from the default mode. -$(DESTDIR)/% : $(foreach file,$(pagefiles),$(BUILDDIR)/public/$(file)) - @$(PRINTF) '%s\n' $(call quote,Collecting pages for </$(NAME)>…) + $(call inform,$(PRINTF) '%s\n' $(call quote,Archiving </$(NAME)>…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)$(call removeassociatedfiles,$@) - $(silent)cp $(foreach file,$(pagefiles),$(call quote,$(BUILDDIR)/public/$(file))) $(DESTDIR) + $(silent)$(RM) -f -R $(call quote,$@) + $(silent)cd $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar > $(call quote,$(abspath $@)); fi # ━ § END DEFINED MAKE·FILE MODES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━