-# SPDX-FileCopyrightText: 2023, 2024, 2025 Lady <https://www.ladys.computer/about/#lady>
+# SPDX-FileCopyrightText: 2023, 2024, 2025, 2026 Lady <https://www.ladys.computer/about/#lady>
# SPDX-License-Identifier: MPL-2.0
SHELL = /bin/sh
╭────────────────────────────╮
╔╡ ⁌ ⛩📰 书社 ∷ GNUmakefile ╞═════════════════════════════════╗
║╰────────────────────────────╯ ║
-╟┬ ¶ Prerequisites ───────────────────────────────────────────┬╢
+╟┬ § Prerequisites ───────────────────────────────────────────┬╢
║│ │║
║│ Requires G·N·U Make, at least version 3.81, the Fine Free │║
║│ File Command, and the various programs packaged with │║
║│ program `program´ by overriding the corresponding variable │║
║│ `PROGRAM´ when calling Make. │║
║╰────────────────────────────────────────────────────────────╯║
-╟┬ ¶ Usage ───────────────────────────────────────────────────┬╢
+╟┬ § Usage ───────────────────────────────────────────────────┬╢
║│ │║
║│ • `make all´ (default): Compile, but do not install, all │║
║│ files. │║
║│ See `README.markdown´ for a more involved description of │║
║│ the capabilities and configuration of this program. │║
║╰────────────────────────────────────────────────────────────╯║
-╟┬ ¶ Copyright & License ─────────────────────────────────────┬╢
+╟┬ § Copyright & License ─────────────────────────────────────┬╢
║│ │║
-║│ Copyright © 2023–2025 Lady [@ Ladys Computer]. │║
+║│ Copyright © 2023–2026 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 │║
# (callable) Get the list of dependency leiris for the given source files.
#
# Recursive dependencies are marked with a leading `-´.
+# Soft dependencies are marked with a leading `?´.
override dependencyuris = $(foreach file,$1,$(subst |, ,$(patsubst $(file)|%,%,$(filter $(file)|%,$(dependenciesforfile)))))
# (callable) Get the list of recursive dependencies for the given source files.
# (callable) Get the list of (nonrecursive) dependencies for the given source files.
#
# If the file cannot have dependencies (e·g is an asset file), the resulting value will be the empty string.
-override dependencies = $(foreach uri,$(filter-out -%,$(call dependencyuris,$1)),$(call sourcefile,$(uri)))
+override dependencies = $(foreach uri,$(filter-out -%,$(call dependencyuris,$1)),$(call sourcefile,$(if $(filter ?%,$(uri)),$(patsubst ?%,%,$(uri)),$(uri))))
endif
# Collect all files with recursive dependencies.
# (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 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))
+override destination = $(foreach file,$1,$(subst ;, ,$(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)))
+override sourcecompiledpair := $(foreach file,$(sourcefiles),$(file)|$(subst $(space),;,$(patsubst %,$(BUILDDIR)/results/%,$(call destination,$(file)))))
# (callable) Get the location of the transformed X·M·L files for the given source files.
-override compiled = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcecompiledpair))))
+override compiled = $(foreach file,$1,$(subst ;, ,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcecompiledpair)))))
# (callable) Get the location of the source files for the given compiled file.
-override uncompiled = $(foreach file,$1,$(patsubst %|$(file),%,$(filter %|$(file),$(sourcecompiledpair))))
+override uncompiled = $(foreach pair,$(sourcecompiledpair),$(foreach src,$(firstword $(subst |, , $(pair))),$(if $(filter $(subst ;, ,$(patsubst $(src)|%,%,$(pair))),$1),$(src),)))
# (callable) Get the location of the final built files for the given source files.
override built = $(foreach file,$1,$(patsubst $(BUILDDIR)/results/%,$(BUILDDIR)/public/%,$(call compiled,$(file))))
override unbuilt = $(foreach file,$1,$(call uncompiled,$(patsubst $(BUILDDIR)/public/%,$(BUILDDIR)/results/%,$(file))))
# (callable) Get the installed locations for the given source files.
-override installed = $(foreach file,$1,$(DESTDIR)/$(call destination,$(file)))
+override installed = $(foreach file,$1,$(patsubst %,$(DESTDIR)/%,$(call destination,$(file))))
# ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
# 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]$(if $(call dependencyuris,$(file)), $(strip $(foreach dep,$(call dependencyuris,$(file)),$(if $(filter -%,$(dep)),\0033[93;41m•|Recursive|Dependency|\0033[39;49m|$(call sourcefile,$(patsubst -%,%,$(dep))),$(if $(filter ?%,$(dep)),\0033[2m•|Soft|Dependency|\0033[22m|$(call sourcefile,$(patsubst ?%,%,$(dep))),\0033[2m•|Dependency|\0033[22m|$(call sourcefile,$(dep)))))))$(if $(filter $(file),$(sourcefiles)), $(foreach dest,$(call destination,$(file)),→|<\0033[4m/$(dest)\0033[24m>),) )) | $(TR) ' |' '\n '
# Lists out the destinations of all resulting files (relative to `DESTDIR´).
listout :
# Collect the metadata into a single file, and generate the dependencies and destinations files as side·effects.
#
# Doing this all in one step reduces the number of calls to `xsltproc´ required, but requires that it be called from the build directory (necessitating a subshell).
-$(BUILDDIR)/dependencies $(BUILDDIR)/destinations $(BUILDDIR)/metadata : $(call diffprereqs,metadatas,$(call metadata,$(sort $(sourcefiles) $(sourceincludes)))) $$(call parseresult,$(sourcefiles) $(sourceincludes)) $(THISDIR)/lib/expandmetadata.xslt
+$(BUILDDIR)/dependencies $(BUILDDIR)/destinations $(BUILDDIR)/metadata : $(call diffprereqs,metadatas,$(call metadata,$(sort $(sourcefiles) $(sourceincludes)))) $(call diffprereqs,parseds,$$(call parsed,$(sort $(sourcefiles) $(sourceincludes)))) $(THISDIR)/lib/expandmetadata.xslt
$(call inform,$(PRINTF) '%s\n' 'Compiling metadata…' >&2)
$(silent){ $(PRINTF) '<?xml version="1.0"?><rdf:RDF 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:"><书社vocab:BuildDirectory nfo:fileUrl="%s"/>' $(call quote,$(call attresc,$(call fileuri,$(BUILDDIR)))); {$(foreach meta,$(call metadata,$(sort $(sourcefiles) $(sourceincludes))), $(CAT) $(call quote,$(meta));) } | $(SED) 's/<?xml version="1.0"?>//g'; $(PRINTF) '%s\n' '</rdf:RDF>'; } | ( $(CD) $(call quote,$(BUILDDIR)); $(XSLTPROC) --nonet --novalid --nomkdir $(call quote,$(abspath $(THISDIR)/lib/expandmetadata.xslt)) - ) | $(XMLLINT) --nonet --nsclean - >|$(call quote,$(BUILDDIR)/metadata)
$(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parseresult,$$(call uncompiled,$$@)) $$(call parseresult,$$(call dependencies,$$(call uncompiled,$$@))) $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt $(TRANSFORMLIBS) $$(call metadata,$$(call dependencies,$$(call uncompiled,$$@)))
$(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,$@)
+ $(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)),) --stringparam DESTINATION $(call quote,$*) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<) >|$(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/% $(THISDIR)/lib/archive2extractor.xslt