X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/bc83928663f56508f210ce19a607aa9a52f32983..884130a52be6bfe21e524498385cb6486495b383:/GNUmakefile?ds=sidebyside
diff --git a/GNUmakefile b/GNUmakefile
index 78f9a41..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))
@@ -309,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)))
@@ -437,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 build directory, parser, transform, or source file with its file u·r·i.
-override fileuripairs := $(join $(patsubst %,%|,$(BUILDDIR) $(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes)),$(call pathenc,$(foreach uriable,$(BUILDDIR) $(PARSERS) $(TRANSFORMS) $(sourcefiles) $(sourceincludes),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),)
@@ -577,12 +594,14 @@ FORCE : ;
# Phony rules; always consider these out·of·date.
.PHONY : FORCE all default clean gone info install list listout uninstall $(call built,$(recursivefiles)) ;
+ifeq ($(notbuilding),)
# Reload this make·file if the magic file, parser, dependencies, or destinations have changed.
#
# If the magic file or parser changed, then another restart will be required, as the dependencies and destinations will need to be regenerated.
$(THISDIR)/GNUmakefile : $(BUILDDIR)/magic.mgc $(BUILDDIR)/parser.xslt $(BUILDDIR)/dependencies $(BUILDDIR)/destinations
$(silent)$(TOUCH) $(THISDIR)/GNUmakefile
$(if $(filter $(BUILDDIR)/magic.mgc $(BUILDDIR)/parser.xslt,$?),$(call inform,$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m' >&2)$(newline)$(silent)$(SLEEP) 1,$(if $(typeupdates),$(silent)$(RM) $(call quote,$(BUILDDIR)/.update-types)$(newline),)$(call inform,$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' >&2))
+endif
# ─ ¶ Build Targets ───────────────────────────────────────────────────
@@ -613,12 +632,10 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars
# Generate R·D·F metadata for files.
#
-# This “depends” on `$(THISDIR)/lib/expandmetadata.xslt´ not because it is an actual dependency, but because a change to that file strongly suggests a change to these rules has occurred as well.
-#
# If the types have been updated but `typeupdates´ is not active, this recipe is skipped because a restart is forthcoming.
-$(call metadata,$(sourcefiles) $(sourceincludes)) : % : $$(call datadata,$$@) $(THISDIR)/lib/expandmetadata.xslt $(typeupdates)
+$(call metadata,$(sourcefiles) $(sourceincludes)) : % : $$(call datadata,$$@) $(THISDIR)/.metadata-format-changed-since $(typeupdates)
$(call inform,$(call unlesstypeswillupdate,$(PRINTF) '%s\n' $(call quote,Generating metadata for `$<´…) >&2))
- $(silent)$(call unlesstypeswillupdate,$(call ensuredirectory,$(dir $@)); { if $(TEST) ! -f $(call quote,$(BUILDDIR)/.mtime); then $(PRINTF) '%b' '\n' >|$(call quote,$(BUILDDIR)/.mtime); fi; $(TOUCH) -r $(call quote,$<) $(call quote,$(BUILDDIR)/.mtime); $(DIFF) -u $(call quote,$(BUILDDIR)/.mtime) /dev/null | $(SED) '1!d;s/.* \([^ ]*\) \([^ ]*\).*$$/\1T\2Z/'; $(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//'; } | $(xargsmultiquote) | $(XARGS) -E '' $(PRINTF) '<书社vocab:$(if $(filter $<,$(sourceincludes)),IncludeFile,SourceFile) xmlns:nie="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#" xmlns:nfo="http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:书社vocab="urn:fdc:ladys.computer:20231231:Shu1She4:vocab:" rdf:about="%s" 书社vocab:path="%s">$(if $(filter $<,$(assetfiles)),,)%s书社vocab:$(if $(filter $<,$(sourceincludes)),IncludeFile,SourceFile)>' $(call quote,$(call attresc,$(call localuri,$<))) $(call quote,$(call attresc,$(if $(filter $<,$(sourceincludes)),$(call includepath,$<),$(call sourcepath,$<)))) $(call quote,$(call attresc,$(call typeoffile,$<))) >|$(call quote,$@))
+ $(silent)$(call unlesstypeswillupdate,$(call ensuredirectory,$(dir $@)); { if $(TEST) ! -f $(call quote,$(BUILDDIR)/.mtime); then $(PRINTF) '%b' '\n' >|$(call quote,$(BUILDDIR)/.mtime); fi; $(TOUCH) -r $(call quote,$<) $(call quote,$(BUILDDIR)/.mtime); $(DIFF) -u $(call quote,$(BUILDDIR)/.mtime) /dev/null | $(SED) '1!d;s/.* \([^ ]*\) \([^ ]*\).*$$/\1T\2Z/'; $(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//'; } | $(xargsmultiquote) | $(XARGS) -E '' $(PRINTF) '<书社vocab:$(if $(filter $<,$(sourceincludes)),IncludeFile,SourceFile) xmlns:nie="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#" xmlns:nfo="http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:书社vocab="urn:fdc:ladys.computer:20231231:Shu1She4:vocab:" rdf:about="%s" 书社vocab:path="%s" nfo:fileUrl="%s">$(if $(filter $<,$(assetfiles)),,)<书社vocab:hasParsedFile nfo:fileUrl="%s"/>%s书社vocab:$(if $(filter $<,$(sourceincludes)),IncludeFile,SourceFile)>' $(call quote,$(call attresc,$(call localuri,$<))) $(call quote,$(call attresc,$(if $(filter $<,$(sourceincludes)),$(call includepath,$<),$(call sourcepath,$<)))) $(call quote,$(call attresc,$(call fileuri,$<))) $(call quote,$(call attresc,$(call typeoffile,$<))) $(call quote,$(call attresc,$(call fileuri,$(call parsed,$<)))) >|$(call quote,$@))
# Parse the files.
#
@@ -626,7 +643,7 @@ $(call metadata,$(sourcefiles) $(sourceincludes)) : % : $$(call datadata,$$@) $(
# Asset files are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s.
#
# If the types have been updated but `typeupdates´ is not active, this recipe is skipped because a restart is forthcoming.
-$(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates)
+$(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(PARSERLIBS) $(typeupdates)
$(call inform,$(call unlesstypeswillupdate,$(PRINTF) '%s\n' $(call quote,Processing `$<´…) >&2))
$(silent)$(call unlesstypeswillupdate,$(call ensuredirectory,$(dir $@)); $(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,) >|$(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(call serializexml,$<)) | $(XSLTPROC) --nonet --novalid --nomkdir --nowrite --stringparam BUILDTIME $$($(DATE) -u '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$<))$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/parser.xslt) - >|$(call quote,$@)))
@@ -644,12 +661,12 @@ $(BUILDDIR)/transform.catalog : $(call diffprereqs,transforms,$(sort $(TRANSFORM
$(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 $(BUILDDIR)/metadata $(THISDIR)/lib/catalog2transform.xslt
+$(BUILDDIR)/transform.xslt : $(BUILDDIR)/transform.catalog $(BUILDDIR)/metadata $(THISDIR)/lib/literally.xslt $(THISDIR)/lib/catalog2transform.xslt
$(call inform,$(PRINTF) '%s\n' 'Generating main transform…' >&2)
$(silent)$(XSLTPROC) --nonet --novalid --nomkdir --nowrite --stringparam METADATA $(call quote,$(call fileuri,$(BUILDDIR))/metadata) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<) >|$(call quote,$@)
# Compile the result files using the dependencies as necessary.
-$(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(call uncompiled,$$@)) $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@))) $(BUILDDIR)/transform.xslt $(BUILDDIR)/metadata
+$(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(call uncompiled,$$@)) $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@))) $(BUILDDIR)/transform.xslt $(TRANSFORMLIBS) $(BUILDDIR)/metadata
$(call inform,$(PRINTF) '%s\n' $(call quote,Compiling $*>…) >&2)
$(silent)$(call ensuredirectory,$(dir $@))
$(silent)$(XSLTPROC) --nonet --novalid --nomkdir --nowrite --stringparam METADATA 'metadata' --stringparam BUILDTIME $$($(DATE) -u '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$(call uncompiled,$@)))$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<) >|$(call quote,$@)