X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/d6d23cafc104581a82e6818585fcdaa3e3a820a1..884130a52be6bfe21e524498385cb6486495b383:/GNUmakefile
diff --git a/GNUmakefile b/GNUmakefile
index c271318..3d4bf87 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -10,11 +10,10 @@ override define makefileinfo
║╰────────────────────────────╯ ║
╟┬ ¶ Prerequisites ───────────────────────────────────────────┬╢
║│ │║
-║│ Requires G·N·U Make, at least version 3.81, a version of │║
-║│ uuencode with base64 support, and the various programs │║
-║│ offered by libxml2 and libxslt. Beyond this, only programs │║
-║│ required by Posix are required, altho there is a chance of │║
-║│ version incompatibilities. The full list of program │║
+║│ Requires G·N·U Make, at least version 3.81, the Fine Free │║
+║│ File Command, and the various programs packaged with │║
+║│ libxml2 and libxslt. Beyond this, only programs specified │║
+║│ by Posix are required. The full list of program │║
║│ requirements is as follows :— │║
║│ │║
║│ • awk │║
@@ -23,16 +22,17 @@ override define makefileinfo
║│ • cksum │║
║│ • cp │║
║│ • date │║
-║│ • diff │║
-║│ • file │║
+║│ • diff (with -u) │║
+║│ • file (specifically the Fine Free File Command) │║
║│ • find │║
║│ • grep │║
║│ • git (optional) │║
║│ • ln │║
+║│ • make (specifically G·N·U Make, version 3.81 or later) │║
║│ • mkdir │║
║│ • mv │║
║│ • od │║
-║│ • pax (only when generating archives) │║
+║│ • pax (ustar format, when generating archives) │║
║│ • printf │║
║│ • rm │║
║│ • sed │║
@@ -83,7 +83,7 @@ override define makefileinfo
║╰────────────────────────────────────────────────────────────╯║
╟┬ ¶ Copyright & License ─────────────────────────────────────┬╢
║│ │║
-║│ Copyright © 2023–2024 Lady [@ Ladys Computer]. │║
+║│ Copyright © 2023–2024 Lady [@ Ladys Computer]. │║
║│ │║
║│ This Source Code Form is subject to the terms of the │║
║│ Mozilla Public License, v 2.0. If a copy of the M·P·L was │║
@@ -184,12 +184,24 @@ FINDINCLUDERULES := $(FINDRULES)$(if $(EXTRAFINDINCLUDERULES), -a '(' $(EXTRAFIN
EXTRAMAGIC :=
MAGIC := $(sort $(patsubst ./%,%,$(wildcard $(THISDIR)/magic/*)) $(EXTRAMAGIC))
+# The list of depedencies for parsers.
+#
+# When these files change, the assumption is that the result of the parsers will change as well, even if the parsers themselves have not.
+EXTRAPARSERLIBS :=
+PARSERLIBS := $(sort $(THISDIR)/lib/split.xslt $(EXTRAPARSERLIBS))
+
# The list of parsers for plaintext file types.
#
# Which parsers are provided will influence which kinds of files are recognized as plaintext.
EXTRAPARSERS :=
PARSERS := $(sort $(patsubst ./%,%,$(wildcard $(THISDIR)/parsers/*.xslt)) $(EXTRAPARSERS))
+# The list of depedencies for transforms.
+#
+# When these files change, the assumption is that the result of the transforms will change as well, even if the transforms themselves have not.
+EXTRATRANSFORMLIBS :=
+TRANSFORMLIBS := $(sort $(THISDIR)/lib/serialize.xslt $(EXTRATRANSFORMLIBS))
+
# The list of transforms.
EXTRATRANSFORMS :=
TRANSFORMS := $(sort $(patsubst ./%,%,$(wildcard $(THISDIR)/transforms/*.xslt)) $(EXTRATRANSFORMS))
@@ -269,6 +281,9 @@ override space := $(empty) $(empty)
# A variable which contains a single comma.
override comma := ,
+# (callable) Make empty strings non·empty, and non·empty strings empty.
+override not = $(if $1,,1)
+
# (callable) Quote the given string for use within shell calls.
override quote = '$(subst ','"'"',$1)'
@@ -295,7 +310,7 @@ override xargsmultiquote = $(SED) $(call quote,s/'/'"'"'/g;s/^/'/;s/$$/'/)
override xpath = $(XMLLINT) --noent --nonet --xpath $(call quote,$1) $(call quote,$2) >>/dev/null 2>>/dev/null
# (callable) Extract the value of the text nodes in the provided X·M·L document and print them to `stdout´.
-override extracttext = $(PRINTF) '%s' '' | $(XSLTPROC) --nonet --novalid - $(call quote,$1)
+override extracttext = $(PRINTF) '%s' '' | $(XSLTPROC) --nonet --novalid --nomkdir --nowrite - $(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)) 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 $(FINALIZE) $(call quote,$1) >|$(call quote,$2); fi
@@ -306,14 +321,19 @@ ifeq ($(MODE),urn:fdc:ladys.computer:20231231:Shu1She4:mode:default)
# ─ ¶ Non‐Recipe Variable Definitions ─────────────────────────────────
+# Non·empty if `help´ or `clean´, and no targets other than `help´ or `clean´, were specified as goals on the commandline.
+override notbuilding := $(and $(filter help clean,$(MAKECMDGOALS)),$(call not,$(filter-out help clean,$(MAKECMDGOALS))))
+
# (callable) Test to see if the prerequisites provided by the second argument matches the value in the file corresponding to the first argument in `$(BUILDDIR)/lastprereqs´.
# If not, save the new value and then add FORCE.
# Return them regardless.
#
# 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.
#
+# If `$(notbuilding)´ is non·empty, this variable produces no result to avoid unnecessary work.
+#
# ☡ 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 || :),,$2),$2 FORCE$(and $(shell $(call ensuredirectory,$(BUILDDIR)/lastprereqs) && $(PRINTF) '%s\n' $(call quote,$2) >|$(BUILDDIR)/lastprereqs/$1),),$2)
+override diffprereqs = $(if $(notbuilding),,$(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 X·M·L.
override xmlesc = $(subst >,>,$(subst <,<,$(subst &,&,$1)))
@@ -379,7 +399,7 @@ override plaintextfiles := $(filter-out $(xmlfiles),$(call filesoftype,$(plainte
override assetfiles := $(filter-out $(xmlfiles) $(plaintextfiles),$(sourcefiles) $(sourceincludes))
# (callable) Get the types of the given files.
-override typeoffile = $(foreach file,$1,$(or $(patsubst $(file)|%,%,$(filter $(file)|%,$(types))),$(error Unable to get type of file `$(file)´)))
+override typeoffile = $(foreach file,$1,$(or $(patsubst $(file)|%,%,$(filter $(file)|%,$(types))),application/octet-stream))
# Pair each source magic file with its location in the build directory.
override magicpair := $(foreach magicfile,$(MAGIC),$(magicfile)|$(BUILDDIR)/magic/$(call namehash,$(magicfile)))
@@ -414,7 +434,7 @@ override sourcefile = $(foreach local,$1,$(patsubst %|$(local),%,$(filter %|$(lo
#
# 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,)
+override typeupdates := $(and $(wildcard $(BUILDDIR)/.update-types),FORCE)
# Pair each source file and include with its metadata location.
override sourcemetadatapair := $(foreach file,$(sourcefiles) $(sourceincludes),$(file)|$(BUILDDIR)/$(if $(filter $(file),$(sourceincludes)),includes.metadata/$(call includepath,$(file)),sources.metadata/$(call sourcepath,$(file))))
@@ -434,10 +454,10 @@ override parsed = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(
# (callable) Get the source files for the given parsed file.
override unparsed = $(foreach file,$1,$(patsubst %|$(file),%,$(filter %|$(file),$(sourceparsedpair))))
-# Pair each parser, transform, source file, parsed file, or metadata compilation with its file u·r·i.
-override fileuripairs := $(join $(patsubst %,%|,$(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes) $(call parsed,$(sourcefiles) $(sourceincludes)) $(BUILDDIR)/metadata),$(call pathenc,$(foreach uriable,$(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes) $(call parsed,$(sourcefiles) $(sourceincludes)) $(BUILDDIR)/metadata,file://$(abspath $(uriable)))))
+# Pair each build directory, parser, transform, source file, or parsed file with its file u·r·i.
+override fileuripairs := $(join $(patsubst %,%|,$(BUILDDIR) $(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes) $(call parsed,$(sourcefiles) $(sourceincludes))),$(call pathenc,$(foreach uriable,$(BUILDDIR) $(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes) $(call parsed,$(sourcefiles) $(sourceincludes)),file://$(abspath $(uriable)))))
-# (callable) Get the file u·r·is for the given parsers, transforms, parsed files, or metadata compilations.
+# (callable) Get the file u·r·is for the given parsers, transforms, source file or parsed files.
override fileuri = $(foreach file,$1,$(or $(patsubst $(file)|%,%,$(filter $(file)|%,$(fileuripairs))),$(error Unable to get file u·r·i for `$(file)´)))
ifneq ($(wildcard $(BUILDDIR)/dependencies),)
@@ -478,12 +498,13 @@ ifneq ($(wildcard $(BUILDDIR)/destinations),)
override destinations := $(shell $(CAT) $(BUILDDIR)/destinations)
# Pair source files and their destinations.
-override sourcedestinationpair := $(foreach destination,$(destinations),$(call sourcefile,$(firstword $(subst |, ,$(destination))))|$(call perdec,$(subst $(space),|,$(wordlist 2,$(words $(subst |, ,$(destination))),$(subst |, ,$(destination))))))
+override sourcedestinationpair := $(foreach destination,$(destinations),$(call sourcefile,$(firstword $(subst |, ,$(destination))))|$(subst $(space),|,$(wordlist 2,$(words $(subst |, ,$(destination))),$(subst |, ,$(destination)))))
+endif
-# (callable) Get the destination for the given source files, or return `NOTDEF´.
+# (callable) Get the destination for the given source files, or return `.NOTDEF/$1´.
#
-# The fallback here is because destinations are used to generate targets and thus must always be non·empty, even when they haven’t been generated yet.
-override destination = $(foreach file,$1,$(or $(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcedestinationpair))),NOTDEF))
+# The fallback here is because destinations are used to generate targets and thus must always be non·empty and should be unique, even when they haven’t been generated yet.
+override destination = $(foreach file,$1,$(or $(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcedestinationpair))),.NOTDEF/$1))
# Pair each source file with its compiled location.
override sourcecompiledpair := $(foreach file,$(sourcefiles),$(file)|$(BUILDDIR)/results/$(call destination,$(file)))
@@ -502,7 +523,6 @@ override unbuilt = $(foreach file,$1,$(call uncompiled,$(patsubst $(BUILDDIR)/pu
# (callable) Get the installed locations for the given source files.
override installed = $(foreach file,$1,$(DESTDIR)/$(call destination,$(file)))
-endif
# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
@@ -519,6 +539,9 @@ override wrapplaintext = { $(PRINTF) '%s\n%s' '' '