X-Git-Url: https://git.ladys.computer/Shushe/blobdiff_plain/44ad50cac2e0fb39ba3cf8b3d5bdf3840e47dc34..884130a52be6bfe21e524498385cb6486495b383:/GNUmakefile diff --git a/GNUmakefile b/GNUmakefile index d91dd30..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' '' '