]> Lady’s Gitweb - Shushe/blob - GNUmakefile
8ce3537b3e72e32152a33b3938fa847ddae01d7a
[Shushe] / GNUmakefile
1 SHELL = /bin/sh
2
3 # ━ § BASIC INFORMATION ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4 override define makefileinfo
5 ╭────────────────────────────╮
6 ╔╡ ⁌ ⛩️📰 书社 ∷ GNUmakefile ╞════════════════════════════════╗
7 ║╰────────────────────────────╯ ║
8 ╟┬ ¶ Prerequisites ───────────────────────────────────────────┬╢
9 ║│ │║
10 ║│ Requires G·N·U Make, at least version 3.81, a version of │║
11 ║│ uuencode with base64 support, and the various programs │║
12 ║│ offered by libxml2 and libxslt. Beyond this, only programs │║
13 ║│ required by Posix are required, altho there is a chance of │║
14 ║│ version incompatibilities. The full list of program │║
15 ║│ requirements is as follows :— │║
16 ║│ │║
17 ║│ • awk │║
18 ║│ • cat │║
19 ║│ • cp │║
20 ║│ • date │║
21 ║│ • echo │║
22 ║│ • file │║
23 ║│ • find │║
24 ║│ • git (optional) │║
25 ║│ • mkdir (requires support for `-p´) │║
26 ║│ • mv │║
27 ║│ • od (requires support for `-t x1´) │║
28 ║│ • printf │║
29 ║│ • rm │║
30 ║│ • sed │║
31 ║│ • sleep │║
32 ║│ • stat │║
33 ║│ • test │║
34 ║│ • touch │║
35 ║│ • tr (requires support for `-d´) │║
36 ║│ • uuencode (requires support for `-m´ and `-r´) │║
37 ║│ • xargs (requires support for `-0´) │║
38 ║│ • xmlcatalog (provided by libxml2) │║
39 ║│ • xmllint (provided by libxml2) │║
40 ║│ • xsltproc (provided by libxslt) │║
41 ║│ │║
42 ║│ In all cases, you can supply your own version of any │║
43 ║│ program `program´ by overriding the corresponding variable │║
44 ║│ `PROGRAM´ when calling Make. │║
45 ║╰────────────────────────────────────────────────────────────╯║
46 ╟┬ ¶ Usage ───────────────────────────────────────────────────┬╢
47 ║│ │║
48 ║│ • `make all´: Compile, but do not install, all files. │║
49 ║│ │║
50 ║│ • `make clean´: Remove `BUILDDIR´. │║
51 ║│ │║
52 ║│ • `make gone´: Remove installed files. │║
53 ║│ │║
54 ║│ • `make help´ (default): Print this message. │║
55 ║│ │║
56 ║│ • `make install´: Compile all files and install in │║
57 ║│ `DESTDIR´. │║
58 ║│ │║
59 ║│ • `make list´: List all recognized source files and their │║
60 ║│ classification (including media type and dependencies). │║
61 ║│ │║
62 ║│ Set `VERBOSE=1´ to see the text of commands as they are │║
63 ║│ executed. │║
64 ║│ │║
65 ║│ See `README.markdown´ for a more involved description of │║
66 ║│ the capabilities and configuration of this program. │║
67 ║╰────────────────────────────────────────────────────────────╯║
68 ╟┬ ¶ Copyright & License ─────────────────────────────────────┬╢
69 ║│ │║
70 ║│ Copyright © 2023–2024 Lady [@ Lady’s Computer]. │║
71 ║│ │║
72 ║│ This Source Code Form is subject to the terms of the │║
73 ║│ Mozilla Public License, v 2.0. If a copy of the M·P·L was │║
74 ║│ not distributed with this file, You can obtain one at │║
75 ║│ <http://mozilla.org/MPL/2.0/>. │║
76 ║╰────────────────────────────────────────────────────────────╯║
77 ╚══════════════════════════════════════════════════════════════╝
78 endef
79
80 # ━ § MAKE·FILE SETUP ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
81
82 # Programs needed to run this make·file.
83 #
84 # If these are not installed on your computer, or you need to use a different implementation, you can override the appropriate variable.
85 AWK := awk
86 CAT := cat
87 CP := cp
88 DATE := date
89 ECHO := echo
90 FILE := file
91 FIND := find
92 GIT := git
93 MKDIR := mkdir
94 MV := mv
95 OD := od
96 PRINTF := printf
97 RM := rm
98 SED := sed
99 SLEEP := sleep
100 STAT := stat
101 TEST := test
102 TOUCH := touch
103 TR := tr
104 UUENCODE := uuencode
105 XARGS := xargs
106 XMLCATALOG := xmlcatalog
107 XMLLINT := xmllint
108 XSLTPROC := xsltproc
109
110 # The directory which contains the source files.
111 #
112 # Multiple directories can be given so long as files with the same name do not exist in each.
113 SRCDIR := sources
114
115 # The directory which contains “includes”:
116 # Files which may be included in other files but for which no final output will be generated.
117 #
118 # Multiple directories can be given so long as files with the same name do not exist in each.
119 #
120 # These can be inside of `SRCDIR´ directories if desired.
121 INCLUDEDIR := sources/includes
122
123 # The directory in which to generate temporary buildfiles.
124 BUILDDIR := build
125
126 # The directory into which to output files on `make install´.
127 DESTDIR := public
128
129 # The location of this Makefile (and related ⛩️📰 书社 files), relative to the current working directory.
130 #
131 # By default, this is inferred from the variable `MAKEFILE_LIST´.
132 THISDIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
133
134 # The location of the magic files to use when determining media types.
135 #
136 # One is provided as part of this repository, but you can override it if you need different media type detection.
137 #
138 # Your computer probably has a more comprehensive one installed at `/usr/share/file/magic´, but it is not recommended that you use this directly.
139 # Instead, link or copy just the files you expect to need for your project.
140 MAGICDIR := $(patsubst ./%,%,$(THISDIR)/magic)
141
142 # Configuration of `find´.
143 #
144 # By default, `find´ will ignore hidden files, those which begin with a period, and those which are likely to cause problems for `make´.
145 FINDRULES := -flags -nohidden -and ! '(' '(' -name '[.-]*' -or -name '*[][*?:|$$%\#;]*' ')' -and -prune ')'
146 FINDINCLUDERULES := $(FINDRULES)
147
148 # The list of parsers for plaintext file types.
149 #
150 # Which parsers are provided will influence which kinds of files are recognized as plaintext.
151 PARSERS := $(patsubst ./%,%,$(wildcard $(THISDIR)/parsers/*.xslt))
152
153 # The list of transforms.
154 TRANSFORMS := $(patsubst ./%,%,$(wildcard $(THISDIR)/transforms/*.xslt))
155
156 # List of types which should be treated as X·M·L.
157 XMLTYPES := application/xml text/xml
158
159 # Set to a non·empty value to print all commands as they run.
160 VERBOSE :=
161
162 # The default target for this makefile.
163 #
164 # Print help and exit.
165 .DEFAULT_GOAL := help
166
167 # ━ § BEGIN MAKE·FILE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
168
169 # ─ ¶ Non‐Recipe Variable Definitions ─────────────────────────────────
170
171 # A variable with no value, usable when assigning values which contain whitespace.
172 override empty :=
173
174 # A variable which contains a newline, to allow the generation of multiline strings in function calls.
175 override define newline
176
177
178 endef
179
180 # A variable which contains a single space.
181 override space := $(empty) $(empty)
182
183 # A variable which contains a single comma.
184 override comma := ,
185
186 # (callable) Quote the given string for use within shell calls.
187 override quote = '$(subst ','"'"',$1)'
188
189 # Outputs an `@´ to silence rules, unless `VERBOSE´ is nonempty.
190 override silent := $(if $(VERBOSE),,@)
191
192 # (callable) Escape special characters for use in sed regular expressions.
193 override sedesc = $(subst /,[/],$(subst $$,\$$,$(subst *,\*,$(subst .,\.,$(subst [,\[,$(subst ^,\^,$(subst \,\\,$1)))))))
194
195 # (callable) Percent‐decode the given strings.
196 override perdec = $(foreach encoded,$1,$(shell $(PRINTF) '%s\n' $(call quote,$(encoded)) | $(SED) 's/|/%7C/g;s/[\]/%5C/g;s/%[0-9A-Fa-f]\{2\}/|&|/g' | $(TR) '|' '\n' | $(SED) '/^%[0-9A-Fa-f]\{2\}$$/!s/%/|%25|/' | $(TR) '|' '\n' | $(AWK) '$$0!~/%/{printf("%s",$$0)}/%/{sub("%","0x");printf("\\%04o",$$0)}' | $(XARGS) -0 $(PRINTF) '%b'))
197
198 # (callable) Percent‐encode the given strings.
199 #
200 # This singly‐encodes u·r·i characters and doubly‐encodes other characters, then calls `perdec´ to decode back to a single encoding.
201 # The encoding assumes the input is a “u·r·i component”; e·g that the resulting string should only contain `pchar´ (but can contain any `sub-delim´).
202 override perenc = $(foreach unencoded,$1,$(call perdec,$(shell $(PRINTF) '%s' $(call quote,$(unencoded)) | $(OD) -t x1 | $(SED) 's/^[0-9]*//;s/2[146-9A-Ea-e]/%&/g;s/3[0-9AaBbDd]/%&/g;s/40/%&/g;s/[46][1-9A-Fa-f]/%&/g;s/[57][0-9Aa]/%&/g;s/5[Ff]/%&/g;s/7[Ee]/%&/g;s/[ ][0-9A-Fa-f]\{2\}/%25&/g' | $(TR) -d ' \n' | $(TR) 'abcdef' 'ABCDEF')))
203
204 # (callable) Percent‐encode each component in the given paths.
205 #
206 # ☡ This will remove leading and trailing slashes.
207 override pathenc = $(foreach path,$1,$(subst $(space),/,$(call perenc,$(subst /, ,$(path)))))
208
209 # (overridable) Collect all of the applicable includes from the includes directory.
210 sourceincludes := $(shell $(FIND) $(foreach dir,$(INCLUDEDIR),$(call quote,$(dir))) -type f '(' $(FINDRULES) ')')
211
212 # (overridable) Collect all of the applicable source files from the source directory, removing any which are also includes.
213 sourcefiles := $(filter-out $(sourceincludes),$(shell $(FIND) $(foreach dir,$(SRCDIR),$(call quote,$(dir))) -type f '(' $(FINDRULES) ')'))
214
215 ifdef GIT
216 ifneq ($(wildcard $(THISDIR)/.git),)
217 # (overridable) The name of the current revision of ⛩️📰 书社, or its hash if the current revision is not a tag.
218 thisrev = $(shell cd $(THISDIR); $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || true)
219 endif
220
221 ifneq ($(wildcard .git),)
222 # (overridable) The name of the current revision of the working directory, or its hash if the current revision is not a tag.
223 srcrev = $(shell $(GIT) describe 2> /dev/null || $(GIT) rev-parse HEAD 2> /dev/null || true)
224 endif
225 endif
226
227 # Figure out the file type of each source file and source include.
228 ifneq ($(wildcard $(BUILDDIR)/magic.mgc),)
229 override types := $(shell $(SED) 's/^ *//;s/ *$$//;s/ {2,}/ /g' <<< $(call quote,$(sourcefiles) $(sourceincludes)) | $(TR) ' ' '\n' | $(FILE) -m $(call quote,$(BUILDDIR)/magic.mgc) --mime-type --separator '|' --files-from - | $(SED) 's/| */|/g')
230 endif
231
232 # Get the list of supported plaintext file types from the parser.
233 ifneq ($(wildcard $(BUILDDIR)/parser.xslt),)
234 override plaintexttypes := $(filter-out $(XMLTYPES),$(shell $(XMLLINT) --xpath '/*/*[@name="书社:parsers"]//*[namespace-uri()="http://www.w3.org/1999/xhtml" and local-name()="dd"]/text()' $(call quote,$(BUILDDIR)/parser.xslt)))
235 endif
236
237 # (callable) Get all of the files (source and includes) which have the given types.
238 override filesoftype = $(foreach type,$1,$(patsubst %|$(type),%,$(filter %|$(type),$(types))))
239
240 # Build up collections of various file types.
241 override xmlfiles := $(call filesoftype,$(XMLTYPES))
242 override plaintextfiles := $(filter-out $(xmlfiles),$(call filesoftype,$(plaintexttypes)))
243 override assetfiles := $(filter-out $(xmlfiles) $(plaintextfiles),$(sourcefiles) $(sourceincludes))
244
245 # (callable) Get the types of the given files.
246 override typeoffile = $(patsubst $(foreach file,$1,$(file)|%),%,$(filter $(foreach file,$1,$(file)|%),$(types)))
247
248 # (callable) Get the identifier for the given parser or transform.
249 override id = $(or $(shell $(XMLLINT) --xpath '/*/*[local-name()="id" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"]/text()[1]' $1 2> /dev/null),about:shushe?$(or $2,unknown)=$(call pathenc,$(basename $(notdir $1))))
250
251 # (callable) Get the local path for the given source file.
252 override sourcepath = $(firstword $(foreach directory,$(SRCDIR),$(if $(filter $(directory)/%,$1),$(patsubst $(directory)/%,%,$1),)))
253
254 # (callable) Get the local path for the given include.
255 override includepath = $(firstword $(foreach directory,$(INCLUDEDIR),$(if $(filter $(directory)/%,$1),$(patsubst $(directory)/%,%,$1),)))
256
257 # (callable) Get base64 data u·r·i’s for the given files.
258 override datauri = $(foreach file,$1,data:$(call typeoffile,$(file));base64,$(shell $(UUENCODE) -m -r $(call quote,$(file)) _ | tr -d ' \n'))
259
260 # Pair each source file and include with its local u·r·i.
261 override sourcelocalpair := $(foreach file,$(sourcefiles) $(sourceincludes),$(file)|about:shushe?$(if $(filter $(file),$(sourceincludes)),include=$(call pathenc,$(call includepath,$(file))),source=$(call pathenc,$(call sourcepath,$(file)))))
262
263 # (callable) Get local uris for the given files.
264 override localuri = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcelocalpair))))
265
266 # (callable) Get the source files for the given local uris.
267 override sourcefile = $(foreach local,$1,$(patsubst %|$(local),%,$(filter %|$(local),$(sourcelocalpair))))
268
269 # Adds a requirement on `$(BUILDDIR)/.update-types´ if the file is present.
270 #
271 # This file is created after a reload due to type changes, and is removed after.
272 # Requiring it ensures that file classifications are up·to·date immediately after the reload.
273 override typeupdates := $(wildcard $(BUILDDIR)/.update-types)
274
275 # Pair each source file and include with its parsed location.
276 override sourceparsedpair := $(foreach file,$(sourcefiles) $(sourceincludes),$(file)|$(BUILDDIR)/$(if $(filter $(file),$(sourceincludes)),includes/$(call includepath,$(file)),sources/$(call sourcepath,$(file))))
277
278 # (callable) Get the location of the transformed X·M·L files for the given source files.
279 override parsed = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourceparsedpair))))
280
281 # (callable) Get the source files for the given parsed file.
282 override unparsed = $(foreach file,$1,$(patsubst %|$(file),%,$(filter %|$(file),$(sourceparsedpair))))
283
284 ifneq ($(wildcard $(BUILDDIR)/dependencies),)
285 # Pair each file with a list of dependencies for it.
286 override dependenciesforfile := $(foreach file,$(sourcefiles),$(file)|$(subst $(space),|,$(shell $(CAT) $(call quote,$(BUILDDIR)/dependencies) | $(SED) $(call quote,/^$(call sedesc,$(call localuri,$(file)))$$/$(comma)/^[^ ]/!d;/^ /!d;s/^ //))))
287
288 # (callable) Get the list of dependency leiris for the given source files.
289 #
290 # Recursive dependencies are marked with a leading `-´.
291 override dependencyuris = $(foreach file,$1,$(subst |, ,$(patsubst $(file)|%,%,$(filter $(file)|%,$(dependenciesforfile)))))
292
293 # (callable) Get the list of recursive dependencies for the given source files.
294 override recursives = $(foreach uri,$(filter -%,$(call dependencyuris,$1)),$(call sourcefile,$(patsubst -%,%,$(uri))))
295
296 # (callable) Get the list of (nonrecursive) dependencies for the given source files.
297 override dependencies = $(foreach uri,$(filter-out -%,$(call dependencyuris,$1)),$(call sourcefile,$(uri)))
298 endif
299
300 # Collect all files with recursive dependencies.
301 override recursivefiles := $(foreach file,$(filter-out $(assetfiles),$(sourcefiles)),$(if $(call recursives,$(file)),$(file),))
302
303 # Collect all files which should be compiled.
304 #
305 # This is all of the non·asset, nonrecursive files.
306 override compilablefiles := $(filter-out $(assetfiles) $(recursivefiles),$(sourcefiles))
307
308 ifneq ($(wildcard $(BUILDDIR)/destinations),)
309 # Get the output of the destination transform.
310 override destinations := $(shell $(CAT) $(BUILDDIR)/destinations)
311
312 # Pair source files and their destinations.
313 override sourcedestinationpair := $(foreach destination,$(destinations),$(call sourcefile,$(firstword $(subst |, ,$(destination))))|$(call perdec,$(subst $(space),|,$(wordlist 2,$(words $(subst |, ,$(destination))),$(subst |, ,$(destination))))))
314
315 # (callable) Get the destination for the given source files.
316 override destination = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcedestinationpair))))
317
318 # Pair each source file with its compiled location.
319 override sourcecompiledpair := $(foreach file,$(sourcefiles),$(file)|$(BUILDDIR)/public/$(call destination,$(file)))
320
321 # (callable) Get the location of the transformed X·M·L files for the given source files.
322 override compiled = $(foreach file,$1,$(patsubst $(file)|%,%,$(filter $(file)|%,$(sourcecompiledpair))))
323
324 # (callable) Get the source files for the given compiled file.
325 override uncompiled = $(foreach file,$1,$(patsubst %|$(file),%,$(filter %|$(file),$(sourcecompiledpair))))
326
327 # (callable) Get the installed locations for the given source files.
328 override installed = $(foreach file,$1,$(DESTDIR)/$(call destination,$(file)))
329 endif
330
331 # ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
332
333 # (callable) Check to see if the given directory exists and create it if not.
334 override ensuredirectory = if $(TEST) ! -d $(call quote,$1); then $(MKDIR) -p $(call quote,$1); fi
335
336 # (callable) Sanitize and wrap the provided plaintext file in X·M·L, printing to `stdout´.
337 override wrapplaintext = $(PRINTF) '%s\n' "$$($(PRINTF) '%b' '<?xml version=\042\061.0\042?>\n<script xmlns=\042http://www.w3.org/1999/xhtml\042 type=\042$(call typeoffile,$1)\042><![CDATA['; $(CAT) $(call quote,$1) | $(TR) '\000\013\014' '\032\011\012' | $(SED) $$($(PRINTF) '%s%b' 's/]]>/]]]]><!\[CDATA\[>/g;s/\xEF\xBF\xBE/�/g;s/\xEF\xBF\xBF/�/g;$$!s/\r$$//g;s/\r/\n/g;$$!s/\xC2\x85$$//g;s/\xC2\x85/\n/g;s/\xE2\x80\xA8/\n/g;' 's/[\0001-\0010]/�/g;s/[\0016-\0037]/�/g'); $(PRINTF) '%s' ']]></script>')"
338
339 # ─ ¶ Phony Targets ───────────────────────────────────────────────────
340
341 # Provide help.
342 help:
343 @$(PRINTF) '%b' '$(subst $(newline),\n,$(makefileinfo))'
344
345 # Compile all files, or error if any are recursive.
346 all: $(call compiled,$(recursivefiles) $(compilablefiles) $(filter $(sourcefiles),$(assetfiles)));
347
348 # Destroy buildfiles.
349 clean:
350 $(silent)$(RM) -rf $(BUILDDIR)/
351
352 # Destroy buildfiles and the install directory.
353 gone:
354 $(silent)$(RM) -rf $(BUILDDIR)/ $(call compiled,$(recursivefiles) $(compilablefiles))
355
356 # Install the compiled files into `DESTDIR´.
357 install: $(call installed,$(recursivefiles) $(compilablefiles) $(filter $(sourcefiles),$(assetfiles)));
358
359 # List all source files and includes and their computed types.
360 list:
361 @$(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 '
362
363 # Raise an error when attempting to build any files with recursive dependencies.
364 $(call compiled,$(recursivefiles)):
365 @$(PRINTF) '%b\n' $(call quote,\0033[93;41mError:\0033[39;49m `$(call uncompiled,$@)´ has recursive dependencies:\n$(subst |, ,$(subst $(space),$(newline),$(foreach recursive,$(call recursives,$(call uncompiled,$@)),•|$(recursive))))) && false
366
367 # ─ ¶ Special Targets ─────────────────────────────────────────────────
368
369 # Perform secondary expansion; this enables pattern rules to determine their prerequisites based on the matched pattern.
370 .SECONDEXPANSION: ;
371
372 # Don’t use any implicit rules.
373 .SUFFIXES: ;
374
375 # Phony rules; always consider these out‐of‐date.
376 .PHONY: all default clean gone info install list $(call compiled,$(recursivefiles));
377
378 ifneq ($(wildcard $(BUILDDIR)/.update-types)$(wildcard $(BUILDDIR)/dependencies),)
379 # Reload this make·file if the dependency graph has changed.
380 #
381 # The dependency graph and output destinations are used to set the values of variables in this make·file, so it’s important to ensure that they are actually up·to·date prior to executing any later rules.
382 #
383 # This recipe only exists after types have been updated or when the dependency graph already exists.
384 $(THISDIR)/GNUmakefile:: $(BUILDDIR)/dependencies $(BUILDDIR)/destinations
385 $(silent)$(TOUCH) $(THISDIR)/GNUmakefile
386 $(silent)$(RM) -f $(BUILDDIR)/.update-types
387 @$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m'
388 endif
389
390 ifeq ($(wildcard $(BUILDDIR)/.update-types),)
391 # Reload this make·file if any of the magic files or parsers have changed.
392 #
393 # These are used to classify source files, so if they have changed then the make·file must be reloaded.
394 #
395 # This recipe sleeps for one second to ensure that files built after the restart have a more current time·stamp.
396 $(THISDIR)/GNUmakefile:: $(BUILDDIR)/magic.mgc $(BUILDDIR)/parser.xslt
397 $(silent)$(TOUCH) $(THISDIR)/GNUmakefile
398 $(silent)$(RM) -f $(call quote,$(BUILDDIR)/dependencies)
399 @$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m'
400 $(silent)$(SLEEP) 1
401 $(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types)
402 endif
403
404 # ─ ¶ Build Targets ───────────────────────────────────────────────────
405
406 # Generate the compiled magic file from its sources.
407 #
408 # It must be updated if any of the files in the magic directory change.
409 # It ⁜also⁜ should be updated if any of the files in the magic directory are deleted, but this isn’t tracked presently.
410 $(BUILDDIR)/magic.mgc: $(wildcard $(MAGICDIR)/*)
411 @$(ECHO) "Compiling new magic…"
412 $(silent)$(call ensuredirectory,$(dir $@))
413 $(silent)cd $(call quote,$(BUILDDIR)) && $(FILE) -C -m $(call quote,$(realpath $(MAGICDIR)))
414
415 # Generate the main parser.
416 $(BUILDDIR)/parser.catalog: $(PARSERS)
417 @$(ECHO) "Generating catalog of parsers…"
418 $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
419 $(foreach parser,$(PARSERS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call id,$(parser),parser)) $(call quote,file:///$(call pathenc,$(abspath $(parser)))) --noout $(call quote,$@)$(newline))
420 $(BUILDDIR)/parser.xslt: $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2parser.xslt
421 @$(ECHO) "Generating main parser…"
422 $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2parser.xslt) $(call quote,$<)
423
424 # Parse the files.
425 #
426 # Even plain X·M·L files are parsed, because they may contain X·H·T·M·L `<script>´ elements which contain other kinds of data.
427 # Asset files are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s.
428 $(call parsed,$(sourcefiles) $(sourceincludes)): %: $$(call unparsed,$$@) $(typeupdates)
429 @$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
430 $(silent)$(call ensuredirectory,$(dir $@))
431 $(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$<)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(CAT) $(call quote,$<)) | $(XSLTPROC) -o $(call quote,$@) --stringparam BUILDTIME '$(shell TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ')' --stringparam SRCTIME '$(shell TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call unparsed,$@)))'$(if $(thisrev), --stringparam VERSION $(call quote,$(thisrev)),)$(if $(srcrev), --stringparam SRCREV $(call quote,$(srcrev)),) $(call quote,$(BUILDDIR)/parser.xslt) -)
432
433 # Generate a catalog of all parsed files, for use when processing includes.
434 #
435 # This does not depend on actually transforming the files.
436 $(BUILDDIR)/catalog: $(sourcefiles) $(sourceincludes) $(typeupdates)
437 @$(ECHO) "Generating catalog of parsed files…"
438 $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
439 $(foreach source,$(sourcefiles) $(sourceincludes),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call localuri,$(source))) $(call quote,file:///$(call pathenc,$(abspath $(call parsed,$(source))))#$(if $(filter $(source),$(assetfiles)),asset,xml)) --noout $(call quote,$@)$(newline))
440
441 # Build a list of dependencies for each parsed file.
442 $(BUILDDIR)/dependencies: $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $(xmlfiles)) $(THISDIR)/lib/catalog2dependencies.xslt
443 @$(ECHO) "Identifying dependencies…"
444 $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2dependencies.xslt) $(call quote,$<)
445
446 # Generate a catalog of destinations for files.
447 #
448 # This depends on parsing non·asset source files, but not assets or includes.
449 # It does not require knowing the dependencies.
450 $(BUILDDIR)/destinations: $(BUILDDIR)/catalog $(call parsed,$(filter-out $(assetfiles),$(sourcefiles))) $(THISDIR)/lib/catalog2destinations.xslt
451 @$(ECHO) "Identifying output destinations…"
452 $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2destinations.xslt) $(call quote,$<)
453
454 # Generate the main transform.
455 $(BUILDDIR)/transform.catalog: $(TRANSFORMS)
456 @$(ECHO) "Generating catalog of transforms…"
457 $(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
458 $(foreach transform,$(TRANSFORMS),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call id,$(transform),transform)) $(call quote,file:///$(call pathenc,$(abspath $(transform)))) --noout $(call quote,$@)$(newline))
459 $(BUILDDIR)/transform.xslt: $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt
460 @$(ECHO) "Generating main transform…"
461 $(silent)$(XSLTPROC) -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
462
463 # Generate the output files using the dependencies as necessary.
464 $(call compiled,$(compilablefiles)): $(BUILDDIR)/public/%: $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@)))
465 $(silent)$(call ensuredirectory,$(dir $@))
466 @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
467 $(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME '$(shell TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ')' --stringparam SRCTIME '$(shell TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call uncompiled,$@)))' --stringparam PATH $(call quote,/$*)$(if $(thisrev), --stringparam VERSION $(call quote,$(thisrev)),)$(if $(srcrev), --stringparam SRCREV $(call quote,$(srcrev)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
468 $(call compiled,$(filter $(assetfiles),$(sourcefiles))): $(BUILDDIR)/public/%: $$(call uncompiled,$$@)
469 @$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
470 $(silent)$(call ensuredirectory,$(dir $@))
471 $(silent)$(CP) $(call quote,$<) $(call quote,$@)
472
473 # Install compiled files (or error in the case of recursive ones).
474 $(call installed,$(filter $(assetfiles),$(sourcefiles)) $(recursivefiles) $(compilablefiles)): $(DESTDIR)/%: $(BUILDDIR)/public/%
475 @$(PRINTF) '%s\n' $(call quote,Installing </$*>…)
476 $(silent)$(call ensuredirectory,$(dir $@))
477 $(silent)$(CP) $(call quote,$<) $(call quote,$@)
This page took 0.06832 seconds and 3 git commands to generate.