X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/5e96540e69e1b5bd59753284b26439419745168a..7f3046d260fee68969d6cb750fe066ab10982e59:/GNUmakefile diff --git a/GNUmakefile b/GNUmakefile index f4161de..ba4df95 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -19,6 +19,7 @@ override define makefileinfo ║│ │║ ║│ • awk │║ ║│ • cat │║ +║│ • cd │║ ║│ • cksum │║ ║│ • cp │║ ║│ • date │║ @@ -99,6 +100,7 @@ endef # If these are not installed on your computer, or you need to use a different implementation, you can override the appropriate variable. AWK := awk CAT := cat +CD := cd CKSUM := cksum CP := cp DATE := date @@ -201,12 +203,12 @@ XMLTYPES := application/xml text/xml +xml ifdef GIT ifneq ($(wildcard $(THISDIR)/.git),) # A description of the current git revision of ⛩️📰 书社. -THISREV := $(shell cd $(THISDIR); $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || true) +THISREV := $(shell $(CD) $(THISDIR); $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || :) endif ifneq ($(wildcard .git),) # A description of the current git revision of the working directory. -SRCREV := $(shell $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || true) +SRCREV := $(shell $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || :) endif endif @@ -231,6 +233,12 @@ VERBOSE := # The default target for this makefile. .DEFAULT_GOAL := all +# Flags for use when calling the shell. +# +# `-e` enables early exit from invocations of multiple commands after +# the first failure. +.SHELLFLAGS := -c -e + # ━ § BEGIN SHARED MAKE·FILE CONSTRUCTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # ─ ¶ Non‐Recipe Variable Definitions ───────────────────────────────── @@ -289,7 +297,7 @@ override xpath = $(XMLLINT) --xpath $(call quote,$1) $(call quote,$2) > /dev/nul override extracttext = $(PRINTF) '%s' '' | $(XSLTPROC) --nonet --novalid - $(call quote,$1) # (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); 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 +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)) 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 quote,$2); else $(XMLLINT) --nsclean $(call quote,$1) > $(call quote,$2); fi # ━ § BEGIN DEFAULT MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -304,7 +312,7 @@ ifeq ($(MODE),urn:fdc:ladys.computer:20231231:Shu1She4:mode:default) # Calling this variable is useful when a given target should be updated whenever its list of prerequisites changes in addition to whenever there is a change to one of its prerequisites. # # ☡ This variable creates at least one subshell every time it is computed. -override diffprereqs = $(if $(subst $(shell $(CAT) $(call quote,$(BUILDDIR)/lastprereqs/$1) 2> /dev/null || true),,$2),$2 FORCE$(and $(shell $(call ensuredirectory,$(BUILDDIR)/lastprereqs) && $(PRINTF) '%s\n' $(call quote,$2) > $(BUILDDIR)/lastprereqs/$1),),$2) +override diffprereqs = $(if $(subst $(shell $(CAT) $(call quote,$(BUILDDIR)/lastprereqs/$1) 2> /dev/null || :),,$2),$2 FORCE$(and $(shell $(call ensuredirectory,$(BUILDDIR)/lastprereqs) && $(PRINTF) '%s\n' $(call quote,$2) > $(BUILDDIR)/lastprereqs/$1),),$2) # (callable) Escape special characters for use in sed regular expressions. override sedesc = $(subst /,[/],$(subst $$,\$$,$(subst *,\*,$(subst .,\.,$(subst [,\[,$(subst ^,\^,$(subst \,\\,$1))))))) @@ -390,11 +398,11 @@ override localuri = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%, # (callable) Get the source files for the given local uris. override sourcefile = $(foreach local,$1,$(patsubst %|$(local),%,$(filter %|$(local),$(sourcelocalpair)))) -# Adds a requirement on `$(BUILDDIR)/.update-types´ if the file is present. +# Resolves to the `FORCE´ target if `$(BUILDDIR)/.update-types´ is present. # -# This file is created after a reload due to type changes, and is removed after. -# Requiring it ensures that file classifications are up·to·date immediately after the reload. -override typeupdates := $(wildcard $(BUILDDIR)/.update-types) +# This file is created before a reload due to type changes, and is removed after. +# This ensures that file classifications are up·to·date immediately after the reload. +override typeupdates := $(if $(wildcard $(BUILDDIR)/.update-types),FORCE,) # Pair each source file and include with its parsed location. override sourceparsedpair := $(foreach file,$(sourcefiles) $(sourceincludes),$(file)|$(BUILDDIR)/$(if $(filter $(file),$(sourceincludes)),includes/$(call includepath,$(file)),sources/$(call sourcepath,$(file)))) @@ -517,7 +525,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))))) >&2 && 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 && exit 1 # Add as a prerequisite to treat the target as tho it were phony. FORCE : ; @@ -579,7 +587,7 @@ $(BUILDDIR)/magic.mgc : $(call diffprereqs,magic,$(sort $(call magicfile,$(MAGIC $(foreach outdated,$(filter-out $^,$(wildcard $(BUILDDIR)/magic/*)),$(silent)$(RM) $(call quote,$(outdated))$(newline)) $(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)$(CD) $(call quote,$(BUILDDIR)) && $(FILE) -C -m $(call quote,$(realpath $(BUILDDIR)/magic)) $(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types) # Generate the main parser. @@ -599,7 +607,7 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates) $(call inform,$(PRINTF) '%s\n' $(call quote,Processing `$<´…) >&2) $(silent)$(call ensuredirectory,$(dir $@)) - $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,) > $(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) -) + $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,) > $(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) -) # Generate a catalog of all parsed files, for use when processing includes. # @@ -712,7 +720,7 @@ $(DESTDIR)/% : $(SRC) $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) $(call inform,$(PRINTF) '%s\n' $(call quote,Archiving …) >&2) $(silent)$(call ensuredirectory,$(dir $@)) $(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 + $(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 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━