summaryrefslogtreecommitdiff
path: root/build-aux/Makefile.once.head
diff options
context:
space:
mode:
Diffstat (limited to 'build-aux/Makefile.once.head')
-rw-r--r--build-aux/Makefile.once.head/00-gitfiles.mk74
-rw-r--r--build-aux/Makefile.once.head/00-quote.mk49
-rw-r--r--build-aux/Makefile.once.head/00-var.mk33
-rw-r--r--build-aux/Makefile.once.head/10-dist.mk79
-rw-r--r--build-aux/Makefile.once.head/10-files.mk87
-rw-r--r--build-aux/Makefile.once.head/10-gnuconf.mk200
-rw-r--r--build-aux/Makefile.once.head/10-lt.mk57
-rw-r--r--build-aux/Makefile.once.head/10-nested.mk45
-rw-r--r--build-aux/Makefile.once.head/10-write-atomic.mk23
-rw-r--r--build-aux/Makefile.once.head/10-write-ifchanged.mk23
-rw-r--r--build-aux/Makefile.once.head/20-amcfg.mk73
-rw-r--r--build-aux/Makefile.once.head/20-sd.mk231
-rw-r--r--build-aux/Makefile.once.head/20-sdman.mk79
-rw-r--r--build-aux/Makefile.once.head/30-am.mk282
-rw-r--r--build-aux/Makefile.once.head/zz-mod.mk59
15 files changed, 1302 insertions, 92 deletions
diff --git a/build-aux/Makefile.once.head/00-gitfiles.mk b/build-aux/Makefile.once.head/00-gitfiles.mk
new file mode 100644
index 0000000000..1214e508c4
--- /dev/null
+++ b/build-aux/Makefile.once.head/00-gitfiles.mk
@@ -0,0 +1,74 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.gitfiles.description = Automatically populate files.src.src from git
+mod.gitfiles.depends += files nested write-ifchanged quote
+mod.gitfiles.files += $(topsrcdir)/$(gitfiles.file)
+define mod.gitfiles.doc
+# Inputs:
+# - Global variable : `gitfiles.file` (Default: gitfiles.mk)
+# - Directory variable : `nested.subdirs`
+# - External : git
+# Outputs:
+# - File : `$(topsrcdir)/$(gitfiles.file)`
+# - Directory variable : `files.src.src`
+# - Directory variable : `files.src.gen` (only in top dir)
+#
+# The `files` module has a variable (`files.src.src`) that you (the
+# developer) set to list "pure" source files; the type of files that you
+# would check into a version control system. Since you are a
+# responsible developer, you use a version control system. Since the
+# computer is already maintaining a list of these files *in the VCS*,
+# why should you--a filthy human--need to also maintain the list? Enter
+# gitfiles, which will talk to git to maintain `files.src.src`, but
+# won't require that the git repository be distributed to
+# installing-users.
+#
+# If `$(topsrcdir)/.git` exists, then it will generate
+# `$(topsrcdir)/$(gitfiles.file)`. Otherwise, it will assume that
+# `$(topsrcdir)/$(gitfiles.file)` already exists.
+#
+# It will use the information in `$(topsrcdir)/$(gitfiles.file)` to
+# append to `files.src.src` in each directory
+#
+# Finally, since the generated `$(topsrcdir)/$(gitfiles.file)` must be
+# distributed to users, it is added to $(topsrcdirs)'s `files.src.gen`.
+#
+# When setting `files.src.src`, it needs to know which files "belong" to
+# the current directory directly, and which "belong" to a further
+# subdirectory. To do this, it uses an expression involving
+# `$(nested.subdirs)`.
+#
+# While gitfiles sets `files.src.src` very early
+# in `each.head`, because `nested.subdirs` might not be set yet, it may
+# or may not be safe to use the value of `$(files.src.src)` in your
+# Makefile, depending on how you set `nested.subdirs`.
+endef
+mod.gitfiles.doc := $(value mod.gitfiles.doc)
+
+gitfiles.file ?= gitfiles.mk
+
+_gitfiles.all =
+-include $(topsrcdir)/$(gitfiles.file)
+
+ifneq ($(wildcard $(topsrcdir)/.git),)
+$(topsrcdir)/$(gitfiles.file): _gitfiles.FORCE
+ @(cd $(@D) && git ls-files -z) | sed -z -e 's/\$$/\$$$$/g' -e 's/\n/$$(at.nl)/g' | xargs -r0 printf '_gitfiles.all+=%s\n' | $(WRITE_IFCHANGED) $@
+.PHONY: _gitfiles.FORCE
+endif
+
+_gitfiles.dir = $(call at.relto,$(topsrcdir),$(srcdir))
+_gitfiles.dir.all = $(patsubst $(_gitfiles.dir)/%,%,$(filter $(_gitfiles.dir)/%,$(_gitfiles.all)))
+_gitfiles.dir.src = $(filter-out $(addsuffix /%,$(nested.subdirs)),$(_gitfiles.dir.all))
diff --git a/build-aux/Makefile.once.head/00-quote.mk b/build-aux/Makefile.once.head/00-quote.mk
new file mode 100644
index 0000000000..94bc943b60
--- /dev/null
+++ b/build-aux/Makefile.once.head/00-quote.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.quote.description = Macros to quote tricky strings
+define mod.quote.doc
+# Inputs:
+# (none)
+# Outputs:
+# - Global variable: `quote.var` : GNU Make variables
+# - Global variable: `quote.pattern` : GNU Make patterns
+# - Global variable: `quote.ere` : POSIX Extended Regular Expressions
+# - Global variable: `quote.bre` : POSIX Basic Regular Expressions
+# - Global variable: `quote.shell` : POSIX sh(1) strings
+# - Global variable: `quote.shell-each`: POSIX sh(1) strings
+#
+# Escaping/quoting things is hard! This module provides a number of
+# functions to escape/quote strings for various contexts.
+#
+# `quote.shell-each` quotes each list-item separately (munging
+# whitespace), while `quote.shell` keeps them as one string (preserving
+# whitespace).
+endef
+mod.quote.doc := $(value mod.quote.doc)
+
+_quote.backslash = $(if $1,$(call _quote.backslash,$(wordlist 2,$(words $1),$1),$(subst $(firstword $1),\$(firstword $1),$2)),$2)
+
+quote.var = $(subst $(at.nl),\$(at.nl),$(subst $$,$$$$,$1))
+quote.pattern = $(call _quote.backslash, \ % ,$1)
+quote.ere = $(call _quote.backslash, \ ^ . [ $$ ( ) | * + ? { ,$1)
+quote.bre = $(call _quote.backslash, \ ^ . [ $$ * ,$1)
+
+quote.shell-each = $(foreach _quote.tmp,$1,$(call quote.shell,$(_quote.tmp)))
+
+# I put this as the last line in the file because it confuses Emacs
+# syntax highlighting and makes the remainder of the file difficult to
+# edit.
+quote.shell = $(subst $(at.nl),'$$'\n'','$(subst ','\'',$1)')
diff --git a/build-aux/Makefile.once.head/00-var.mk b/build-aux/Makefile.once.head/00-var.mk
new file mode 100644
index 0000000000..1f50f21f1a
--- /dev/null
+++ b/build-aux/Makefile.once.head/00-var.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.var.description = Depend on the values of variables
+define mod.var.doc
+# Inputs:
+# (user-defined)
+# Outputs:
+# Target : `$(outdir)/.var.%`
+# Directory variable: `at.targets`
+#
+# It's a well-known secret that many files generated by a Makefile vary with
+# the values of particular variables, but that GNU Make can't track these
+# dependencies. Well, with some cleverness, it actually can!
+#
+# With this module, to depend on the value of a variable, depend on
+# `$(outdir)/.var.VARNAME`.
+endef
+mod.var.doc := $(value mod.var.doc)
+
+.PHONY: _var.FORCE
diff --git a/build-aux/Makefile.once.head/10-dist.mk b/build-aux/Makefile.once.head/10-dist.mk
new file mode 100644
index 0000000000..831ca125f8
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-dist.mk
@@ -0,0 +1,79 @@
+# Copyright (C) 2015-2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.dist.description = `dist` target for distribution tarballs
+define mod.dist.doc
+# User variables:
+# - `CP ?= cp`
+# - `GZIP ?= gzip`
+# - `MKDIR ?= mkdir`
+# - `MKDIR_P ?= mkdir -p`
+# - `MV ?= mv`
+# - `RM ?= rm -f`
+# - `TAR ?= tar`
+# - `GZIPFLAGS ?= $(GZIP_ENV)`
+# - `GZIP_ENV ?= --best` (only used via `GZIPFLAGS`, not directly)
+# Inputs:
+# - Global variable : `dist.exts` (Default: `.tar.gz`)
+# - Global variable : `dist.pkgname` (Default: first of PACKAGE_TARNAME PACKAGE PACKAGE_NAME)
+# - Global variable : `dist.version` (Default: first of PACKAGE_VERSION VERSION)
+# - Directory variable : `files.src`
+# Outputs:
+# - Directory variable : `files.out.int` (only in top dir)
+# - .PHONY Target : `$(outdir)/dist`
+# - Target : `$(topoutdir)/$(dist.pkgname)-$(dist.version)`
+# - Target : `$(topoutdir)/$(dist.pkgname)-$(dist.version).tar`
+# - Target : `$(topoutdir)/$(dist.pkgname)-$(dist.version).tar.gz`
+#
+# Provide the standard `dist` .PHONY target, based on the `files` module
+# information.
+#
+# You may change the default compression target easily via the
+# `dist.exts` variable, but you must define the rule for it manually.
+#
+# Bugs:
+#
+# The tarball isn't reproducible. It uses file-system ordering of
+# files, and includes timestamps.
+endef
+mod.dist.doc := $(value mod.dist.doc)
+
+# Developer configuration
+
+dist.exts ?= .tar.gz
+dist.pkgname ?= $(firstword $(PACKAGE_TARNAME) $(PACKAGE) $(PACKAGE_NAME))
+dist.version ?= $(firstword $(PACKAGE_VERSION) $(VERSION))
+
+ifeq ($(dist.pkgname),)
+$(error Autothing module: dist: dist.pkgname must be set)
+endif
+ifeq ($(dist.version),)
+$(error Autothing module: dist: dist.version must be set)
+endif
+
+_dist.files =
+
+# User configuration
+
+CP ?= cp
+GZIP ?= gzip
+MKDIR ?= mkdir
+MKDIR_P ?= mkdir -p
+MV ?= mv
+RM ?= rm -f
+TAR ?= tar
+
+GZIPFLAGS ?= $(GZIP_ENV)
+GZIP_ENV ?= --best
diff --git a/build-aux/Makefile.once.head/10-files.mk b/build-aux/Makefile.once.head/10-files.mk
new file mode 100644
index 0000000000..f6fcf30c3a
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-files.mk
@@ -0,0 +1,87 @@
+# Copyright (C) 2015-2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.files.description = Keeping track of groups of files
+mod.files.depends += nested
+define mod.files.doc
+# User variables:
+# - `DESTDIR ?=`
+# - `RM ?= rm -f`
+# - `RMDIR_P ?= rmdir -p --ignore-fail-on-non-empty`
+# - `TRUE ?= true`
+# Inputs:
+# - Global variable : `files.groups ?= all`
+# - Global variable : `files.default ?= all`
+# - Global variable : `files.vcsclean ?= files.vcsclean`
+# - Global variable : `files.generate ?= files.generate`
+# - Directory variable : `files.src.src`
+# - Directory variable : `files.src.int`
+# - Directory variable : `files.src.cfg`
+# - Directory variable : `files.src.gen`
+# - Directory variable : `files.out.slow`
+# - Directory variable : `files.out.int`
+# - Directory variable : `files.out.cfg`
+# - Directory variable : `files.out.$(files.groups)` (well, $(addprefix...))
+# - Directory variable : `files.sys.$(files.groups)` (well, $(addprefix...))
+# Outputs:
+# - Global variable : `nested.targets`
+# - Global variable : `at.targets`
+# - Global variable : `.DEFAULT_GOAL = $(files.default)`
+# - Directory variable : `files.src`
+# - Directory variable : `files.out`
+# - Directory variable : `files.sys`
+# - Creative .PHONY targets:
+# - `$(outdir)/$(files.generate))`
+# - `$(outdir)/$(group)` for `group` in `$(files.groups)`
+# - `$(outdir)/install`
+# - `$(outdir)/install-$(group)` for `group` in `$(filter-out $(files.default),$(files.groups))`
+# - `$(outdir)/installdirs`
+# - Destructive .PHONY targets:
+# - `$(outdir)/uninstall`
+# - `$(outdir)/mostlyclean`
+# - `$(outdir)/clean`
+# - `$(outdir)/distclean`
+# - `$(outdir)/maintainer-clean`
+# - `$(outdir)/$(files.vcsclean)`
+#
+# Basic `*` wildcards are supported. Use `*`, not `%`; it will automatically
+# substitute `*`->`%` where appropriate.
+#
+# TODO: prose documentation
+endef
+mod.files.doc := $(value mod.files.doc)
+
+files.groups ?= all
+files.default ?= all
+files.vcsclean ?= files.vcsclean
+files.generate ?= files.generate
+
+.DEFAULT_GOAL = $(files.default)
+
+# Standard creative PHONY targets
+nested.targets += $(files.generate)
+nested.targets += install installdirs
+nested.targets += $(foreach g,$(files.groups),$g)
+nested.targets += $(foreach g,$(filter-out $(files.default),$(files.groups)),install-$g install-$gdirs)
+# Standard destructive PHONY targets
+nested.targets += uninstall mostlyclean clean distclean maintainer-clean
+
+# User configuration
+
+DESTDIR ?=
+
+RM ?= rm -f
+RMDIR_P ?= rmdir -p --ignore-fail-on-non-empty
+TRUE ?= true
diff --git a/build-aux/Makefile.once.head/10-gnuconf.mk b/build-aux/Makefile.once.head/10-gnuconf.mk
new file mode 100644
index 0000000000..a4b76964f4
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-gnuconf.mk
@@ -0,0 +1,200 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.gnuconf.description = GNU standard configuration variables
+define mod.gnuconf.doc
+# Inputs:
+# - Global variable: `gnuconf.pkgname`
+# (Default: `$(firstword $(PACKAGE_TARNAME) $(PACKAGE) $(PACKAGE_NAME))`)
+# Outputs:
+# (see below)
+#
+# This module defines default values (using `?=`) a huge list of
+# variables specified in the GNU Coding Standards that installing-users
+# expect to be able to set.
+#
+# This is based on §7.2 "Makefile Conventions" of the July 25, 2016
+# release of the GNU Coding Standards.
+endef
+mod.gnuconf.doc := $(value mod.gnuconf.doc)
+
+gnuconf.pkgname ?= $(firstword $(PACKAGE_TARNAME) $(PACKAGE) $(PACKAGE_NAME))
+ifeq ($(gnuconf.pkgname),)
+$(error Autothing module: gnuconf: gnuconf.pkgname must be set)
+endif
+
+# 7.2.2: Utilities in Makefiles
+# -----------------------------
+
+# It's ok to hard-code these commands in rules, but who wants to
+# memorize the list of what's ok?
+AWK ?= awk
+CAT ?= cat
+CMP ?= cmp
+CP ?= cp
+DIFF ?= diff
+ECHO ?= echo
+EGREP ?= egrep
+EXPR ?= expr
+FALSE ?= false
+GREP ?= grep
+INSTALL_INFO ?= install-info
+LN ?= ln
+LS ?= ls
+MKDIR ?= mkdir
+MV ?= mv
+PRINTF ?= printf
+PWD ?= pwd
+RM ?= rm
+RMDIR ?= rmdir
+SED ?= sed
+SLEEP ?= sleep
+SORT ?= sort
+TAR ?= tar
+TEST ?= test
+TOUCH ?= touch
+TR ?= tr
+TRUE ?= true
+
+# 7.2.2: Utilities in Makefiles/7.2.3: Variables for Specifying Commands
+# ----------------------------------------------------------------------
+
+# Standard user-configurable programs.
+#
+# The list of programs here is specified in §7.2.2, but the associated FLAGS
+# variables are specified in §7.2.3. I found it cleaner to list them together.
+AR ?= ar
+ARFLAGS ?=
+BISON ?= bison
+BISONFLAGS ?=
+CC ?= cc
+CFLAGS ?= # CFLAGS instead of CCFLAGS
+FLEX ?= flex
+FLEXFLAGS ?=
+INSTALL ?= install
+# There is no INSTALLFLAGS[0]
+LD ?= ld
+LDFLAGS ?=
+LDCONFIG ?= ldconfig # TODO[1]
+LDCONFIGFLAGS ?=
+LEX ?= lex
+LFLAGS ?= # LFLAGS instead of LEXFLAGS
+#MAKE
+MAKEINFO ?= makeinfo
+MAKEINFOFLAGS ?=
+RANLIB ?= ranlib # TODO[1]
+RANLIBFLAGS ?=
+TEXI2DVI ?= texi2dvi
+TEXI2DVIFLAGS ?=
+YACC ?= yacc
+YFLAGS ?= # YFLAGS instead of YACCFLAGS
+
+LN_S ?= ln -s # TODO[2]
+
+CHGRP ?= chgrp
+CHGRPFLAGS ?=
+CHMOD ?= chmod
+CHMODFLAGS ?=
+CHOWN ?= chown
+CHOWNFLAGS ?=
+MKNOD ?= mknod
+MKNODFLAGS ?=
+
+# [0]: There is no INSTALLFLAGS because it would be inconsistent with how the
+# standards otherwise recommend using $(INSTALL); with INSTALL_PROGRAM and
+# INSTALL_DATA; which are specified in a way precluding the use of
+# INSTALLFLAGS. To have the variable, but to ignore it in the common case
+# would be confusing.
+#
+# [1]: The RANLIB and LDCONFIG variables need some extra smarts; §7.2.2 says:
+#
+# > When you use ranlib or ldconfig, you should make sure nothing bad
+# > happens if the system does not have the program in question. Arrange
+# > to ignore an error from that command, and print a message before the
+# > command to tell the user that failure of this command does not mean a
+# > problem. (The Autoconf ‘AC_PROG_RANLIB’ macro can help with this.)
+#
+# [2]: The LN_S variable isn't standard, but we have it here as an (incomplete)
+# stub to help support this bit of §7.2.2:
+#
+# > If you use symbolic links, you should implement a fallback for
+# > systems that don’t have symbolic links.
+
+# 7.2.3: Variables for Specifying Commands
+# ----------------------------------------
+
+INSTALL_PROGRAM ?= $(INSTALL)
+INSTALL_DATA ?= ${INSTALL} -m 644
+
+# 7.2.5: Variables for Installation Directories
+# ---------------------------------------------
+
+# Root for the installation
+prefix ?= /usr/local
+exec_prefix ?= $(prefix)
+# Executable programs
+bindir ?= $(exec_prefix)/bin
+sbindir ?= $(exec_prefix)/sbin
+libexecdir ?= $(exec_prefix)/libexec
+# Data files
+datarootdir ?= $(prefix)/share
+datadir ?= $(datarootdir)
+sysconfdir ?= $(prefix)/etc
+sharedstatedir ?= $(prefix)/com
+localstatedir ?= $(prefix)/var
+runstatedir ?= $(localstatedir)/run
+# Specific types of files
+includedir ?= $(prefix)/include
+oldincludedir ?= /usr/include
+docdir ?= $(datarootdir)/doc/$(gnuconf.pkgname)
+infodir ?= $(datarootdir)/info
+htmldir ?= $(docdir)
+dvidir ?= $(docdir)
+pdfdir ?= $(docdir)
+psdir ?= $(docdir)
+libdir ?= $(exec_prefix)/lib
+lispdir ?= $(datarootdir)/emacs/site-lisp
+localedir ?= $(datarootdir)/locale
+
+mandir ?= $(datarootdir)/man
+man1dir ?= $(mandir)/man1
+man2dir ?= $(mandir)/man2
+man3dir ?= $(mandir)/man3
+man4dir ?= $(mandir)/man4
+man5dir ?= $(mandir)/man5
+man6dir ?= $(mandir)/man6
+man7dir ?= $(mandir)/man7
+man8dir ?= $(mandir)/man8
+
+manext ?= .1
+man1ext ?= .1
+man2ext ?= .2
+man3ext ?= .3
+man4ext ?= .4
+man5ext ?= .5
+man6ext ?= .6
+man7ext ?= .7
+man8ext ?= .8
+
+# 7.2.7: Install Command Categories
+# ---------------------------------
+
+PRE_INSTALL ?=
+POST_INSTALL ?=
+NORMAL_INSTALL ?=
+
+PRE_UNINSTALL ?=
+POST_UNINSTALL ?=
+NORMAL_UNINSTALL ?=
diff --git a/build-aux/Makefile.once.head/10-lt.mk b/build-aux/Makefile.once.head/10-lt.mk
new file mode 100644
index 0000000000..ea7323b647
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-lt.mk
@@ -0,0 +1,57 @@
+mod.lt.description = (systemd) Easy handling of libtool dependencies
+mod.lt.depends += files
+define mod.lt.doc
+# Inputs:
+# - Global variable : `$(.LIBPATTERNS)`
+# - Directory variable : `$(files.sys)`
+# - Target variable : `$@`
+# - Target variable : `$(@F)`
+# - Target variable : `$^`
+# Outputs:
+# - Target variable : `lt.lib.rpath` (`$(@D)`, `$(files.sys)`)
+# - Target variable : `lt.lib.files.all` (`$^`, `$(.LIBPATTERNS)`)
+# - Target variable : `lt.lib.files.ld` (`$(lt.lib.rpath)`, `$(lt.lib.files.all)`)
+# - Target variable : `lt.lib.post` (`$(lt.lib.rpath)`, `$(lt.lib.files.all)`)
+# - Target variable : `lt.exe.files.all` (`$^`, `$(.LIBPATTERNS)`)
+# - Target variable : `lt.exe.files.ld` (an alias for `lt.exe.files.all`)
+#
+# A set of variables to make interacting with libtool a little easier.
+#
+# libtool tries to abstract away the difference between static libraries
+# and dynamic libraries. But, it does a crappy job. If one library
+# depends on another library, you have to care about which of them are
+# static and which are dynamic, or you'll either end up with missing
+# symbols, or duplicate symbols. Either way, it will fail to link your
+# executable.
+#
+# So, our workaround: don't pass any .la libraries to libtool/ld when
+# linking a convenience library, but then run a post-libtool command to
+# insert them into the .la file's dependency_libs. This uses the
+# emptiness of lt.lib.rpath to determine if a library is a static
+# convenience library or not.
+endef
+mod.lt.doc := $(value mod.lt.doc)
+
+_lt.patsubst-all = $(if $1,$(call _lt.patsubst-all,$(wordlist 2,$(words $1),$1),$2,$(patsubst $(firstword $1),$2,$3)),$3)
+_lt.unLIBPATTERNS = $(foreach _lt.tmp,$1,$(if $(filter $(.LIBPATTERNS),$(notdir $(_lt.tmp))),$(call _lt.patsubst-all,$(.LIBPATTERNS),-l%,$(notdir $(_lt.tmp))),$(_lt.tmp)))
+_lt.rest = $(wordlist 2,$(words $1),$1)
+# Usage: $(call _lt.dedup,ITEM1 ITEM2 ITEM3)
+# Removes duplicate items while keeping the order the same (the leftmost of a duplicate is used).
+_lt.dedup = $(if $1,$(if $(filter $(firstword $1),$(call _lt.rest,$1)),,$(firstword $1) )$(call _lt.dedup,$(call _lt.rest,$1)))
+# Usage: $(call _lt.dependency_libs,LIB1.la OBJ.lo LIB2.la)
+# => LIB1.la LIB1.la:dependency_libs OBJ.lo LIB2.la LIB2.la:dependency_libs
+# Insert a .la library's dependency_libs after the library itself in the list.
+_lt.dependency_libs = $(foreach _lt.tmp,$1,$(_lt.tmp)$(if $(filter %.la,$(_lt.tmp)), $(shell . $(_lt.tmp); echo $$dependency_libs)))
+
+ lt.lib.rpath = $(dir $(filter %/$(@F),$(files.sys)))
+ lt.lib.files.all = $(filter %.lo %.la -l%,$(call _lt.unLIBPATTERNS,$^))
+ lt.lib.files.ld = $(strip $(if $(lt.lib.rpath),\
+ $(lt.lib.files.all),\
+ $(filter-out %.la,$(lt.lib.files.all))))
+_lt.lib.files.dep = $(strip $(call _lt.dedup,$(filter %.la -l%,$(call _lt.dependency_libs,$(lt.lib.files.all)))))
+ lt.lib.post = $(strip $(if $(lt.lib.rpath),\
+ true,\
+ sed -i 's|^dependency_libs=.*|dependency_libs='\''$(_lt.lib.files.dep)'\''|' $@))
+
+lt.exe.files.all = $(filter %.o %.la -l%,$(call _lt.unLIBPATTERNS,$^))
+lt.exe.files.ld = $(lt.exe.files.all)
diff --git a/build-aux/Makefile.once.head/10-nested.mk b/build-aux/Makefile.once.head/10-nested.mk
new file mode 100644
index 0000000000..4f181a9290
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-nested.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.nested.description = Easy nested .PHONY targets
+define mod.nested.doc
+# Inputs:
+# - Global variable : `nested.targets`
+# - Directory variable : `nested.subdirs`
+# Outputs:
+# - .PHONY Targets : `$(addprefix $(outdir)/,$(nested.targets))`
+# - Variable : `at.subdirs`
+#
+# The Autothing `at.subdirs` slates a subdirectory's Makefile for inclusion,
+# but doesn't help with recursive targets like `all`, `install`, or `clean`,
+# which one would expect to descend into subdirectories. Enter `nested`:
+# Define a global list of targets that are recursive/nested, and then in each
+# directory define a list of subdirectries that one would expect them to
+# recurse into.
+#
+# Directories added to `nested.subdirs` are automatically added to `at.subdirs`
+# during the each.tail phase.
+#
+# It may help to think of at.subdirs and nested.subdirs in terms of their
+# Automake conterparts:
+#
+# | Autothing | GNU Automake |
+# +----------------+--------------+
+# | at.subdirs | DIST_SUBDIRS |
+# | nested.subdirs | SUBDIRS |
+endef
+mod.nested.doc := $(value mod.nested.doc)
+
+nested.targets ?=
diff --git a/build-aux/Makefile.once.head/10-write-atomic.mk b/build-aux/Makefile.once.head/10-write-atomic.mk
new file mode 100644
index 0000000000..c4aa808c61
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-write-atomic.mk
@@ -0,0 +1,23 @@
+mod.write-atomic.description = `write-atomic` auxiliary build script
+mod.write-atomic.files += $(topsrcdir)/build-aux/write-atomic
+define mod.write-atomic.doc
+# User variables:
+# - `WRITE_ATOMIC ?= $(topsrcdir)/build-aux/write-atomic`
+# Inputs:
+# (none)
+# Outputs:
+# (none)
+#
+# The $(WRITE_ATOMIC) program reads a file from stdin, and writes it to
+# the file named in argv[1], but does so atomically.
+#
+# That is, the following lines are almost equivalient:
+#
+# ... > $@
+# ... | $(WRITE_ATOMIC) $@
+#
+# The are only different in that one is atomic, while the other is not.
+endef
+mod.write-atomic.doc := $(value mod.write-atomic.doc)
+
+WRITE_ATOMIC ?= $(topsrcdir)/build-aux/write-atomic
diff --git a/build-aux/Makefile.once.head/10-write-ifchanged.mk b/build-aux/Makefile.once.head/10-write-ifchanged.mk
new file mode 100644
index 0000000000..649aab9c12
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-write-ifchanged.mk
@@ -0,0 +1,23 @@
+mod.write-ifchanged.description = `write-ifchanged` auxiliary build script
+mod.write-ifchanged.files += $(topsrcdir)/build-aux/write-ifchanged
+define mod.write-ifchanged.doc
+# User variables:
+# - `WRITE_IFCHANGED ?= $(topsrcdir)/build-aux/write-ifchanged`
+# Inputs:
+# (none)
+# Outputs:
+# (none)
+#
+# The $(WRITE_IFCHANGED) program reads a file from stdin, and writes it to the
+# file named in argv[1], but does so atomically, but more importantly, does so
+# in a way that does not bump the file's ctime if the new content is the same
+# as the old content.
+#
+# That is, the following lines are almost equivalient:
+#
+# ... > $@
+# ... | $(WRITE_ATOMIC) $@
+endef
+mod.write-ifchanged.doc := $(value mod.write-ifchanged.doc)
+
+WRITE_IFCHANGED ?= $(topsrcdir)/build-aux/write-ifchanged
diff --git a/build-aux/Makefile.once.head/20-amcfg.mk b/build-aux/Makefile.once.head/20-amcfg.mk
new file mode 100644
index 0000000000..0a16c148a2
--- /dev/null
+++ b/build-aux/Makefile.once.head/20-amcfg.mk
@@ -0,0 +1,73 @@
+mod.amcfg.description = (systemd) Automake-to-Autothing configuration
+mod.amcfg.depends += am
+define mod.amcfg.doc
+# User variables:
+# - `V`
+# - `AM_V_*`
+# - `pamconfdir`
+# - `tmpfilesdir`
+# - `sysusersdir`
+# - `sysctldir`
+# - `bashcompletiondir`
+# - `zshcompletiondir`
+# - `LIBTOOL`
+# - `INSTALL_PROGRAM`
+# - `INSTALL_SCRIPT`
+# - `INSTALL_DATA`
+# Inputs:
+# - Global variable: `sd.ALL_LIBTOOLFLAGS`
+# Outputs:
+# - Global variable: `am.sys2out_*`
+# - Global variable: `am.INSTALL_*`
+endef
+mod.amcfg.doc := $(value mod.amcfg.doc)
+
+am.sys2out_DATA = \
+ $(notdir \
+ $(patsubst $(pamconfdir)/%,%.pam,\
+ $(patsubst $(tmpfilesdir)/%.conf,%.tmpfiles,\
+ $(patsubst $(sysusersdir)/%.conf,%.sysusers,\
+ $(patsubst $(sysctldir)/%.conf,%.sysctl,\
+ $(patsubst $(bashcompletiondir)/%,%.completion.bash,\
+ $(patsubst $(zshcompletiondir)/_%,%.completion.zsh,\
+ $1)))))))
+am.sys2out_HEADERS = $(abspath $(addprefix $(srcdir)/include/,$(notdir $1)))
+
+V ?=
+
+AM_V_PROG ?= $(AM_V_PROG_$(V))
+AM_V_PROG_ ?= $(AM_V_PROG_$(AM_DEFAULT_VERBOSITY))
+AM_V_PROG_0 ?= @echo " PROG " $@;
+AM_V_PROG_1 ?=
+
+AM_V_SCRIPT ?= $(AM_V_SCRIPT_$(V))
+AM_V_SCRIPT_ ?= $(AM_V_SCRIPT_$(AM_DEFAULT_VERBOSITY))
+AM_V_SCRIPT_0 ?= @echo " SCRIPT " $@;
+AM_V_SCRIPT_1 ?=
+
+AM_V_LIB ?= $(AM_V_LIB_$(V))
+AM_V_LIB_ ?= $(AM_V_LIB_$(AM_DEFAULT_VERBOSITY))
+AM_V_LIB_0 ?= @echo " LIB " $@;
+AM_V_LIB_1 ?=
+
+AM_V_DATA ?= $(AM_V_DATA_$(V))
+AM_V_DATA_ ?= $(AM_V_DATA_$(AM_DEFAULT_VERBOSITY))
+AM_V_DATA_0 ?= @echo " DATA " $@;
+AM_V_DATA_1 ?=
+
+AM_V_HEADER ?= $(AM_V_HEADER_$(V))
+AM_V_HEADER_ ?= $(AM_V_HEADER_$(AM_DEFAULT_VERBOSITY))
+AM_V_HEADER_0 ?= @echo " HEADER " $@;
+AM_V_HEADER_1 ?=
+
+AM_V_MAN ?= $(AM_V_MAN_$(V))
+AM_V_MAN_ ?= $(AM_V_MAN_$(AM_DEFAULT_VERBOSITY))
+AM_V_MAN_0 ?= @echo " MAN " $@;
+AM_V_MAN_1 ?=
+
+am.INSTALL_PROGRAMS = $(AM_V_PROG)$(LIBTOOL) $(AM_V_lt) --tag=CC $(sd.ALL_LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $< $@
+am.INSTALL_SCRIPTS = $(AM_V_SCRIPT)$(INSTALL_SCRIPT) $< $@
+am.INSTALL_LTLIBRARIES = $(AM_V_LIB)$(LIBTOOL) $(AM_V_lt) --tag=CC $(sd.ALL_LIBTOOLFLAGS) --mode=install $(INSTALL) $< $@
+am.INSTALL_DATA = $(AM_V_DATA)$(INSTALL_DATA) $< $@
+am.INSTALL_HEADERS = $(AM_V_HEADER)$(INSTALL_DATA) $< $@
+am.INSTALL_MANS = $(AM_V_MAN)$(INSTALL_DATA) $< $@
diff --git a/build-aux/Makefile.once.head/20-sd.mk b/build-aux/Makefile.once.head/20-sd.mk
index 134c2c0ef1..4e44d2f7b3 100644
--- a/build-aux/Makefile.once.head/20-sd.mk
+++ b/build-aux/Makefile.once.head/20-sd.mk
@@ -20,81 +20,173 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
-include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
-include $(topsrcdir)/build-aux/Makefile.head.mk
-ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
-AM_MAKEFLAGS = --no-print-directory
-AUTOMAKE_OPTIONS = color-tests parallel-tests
+mod.sd.description = (systemd) shared build rules
+mod.sd.depends += am
+define mod.sd.doc
+# User variables:
+# (flags)
+# - `CFLAGS`
+# - `CPPFLAGS`
+# - `LDFLAGS`
+# - `LIBTOOLFLAGS`
+# (programs)
+# - `CC`
+# - `CCLD`
+# - `LIBTOOL`
+# - `MKDIR_P`
+# - `SED`
+# (verbosity)
+# - `V`
+# - `AM_V_*`
+# - `INTLTOOL_V_MERGE*`
+# (substitutions)$(foreach v,$(sort $(sd.substitution_keys)),$(at.nl)# - $v)
+# Inputs:
+# - Global variable : `DEPDIR`
+# - Global variable : `ENABLE_TESTS`
+# - Global variable : `ENABLE_UNSAFE_TESTS`
+# - Global variable : `OUR_CFLAGS`
+# - Global variable : `OUR_CPPFLAGS`
+# - Global variable : `OUR_LDFLAGS`
+# - Global variable : `OUR_LIBTOOLFLAGS`
+# (Makefiles)
+# - Directory variable : `sd.CFLAGS`
+# - Directory variable : `sd.CPPFLAGS`
+# - Directory variable : `sd.LDFLAGS`
+# - Directory variable : `sd.LIBTOOLFLAGS`
+# - Directory variable : `sd.sed_files` (default based on `EXTRA_DIST`)
+# (am)
+# - Directory variable : `EXTRA_DIST`
+# - Directory variable : `am.out_PROGRAMS`
+# - Directory variable : `am.CFLAGS`
+# - Directory variable : `am.CPPFLAGS`
+# - Target variable : `am.LDFLAGS`
+# Outputs:
+# - Global variable : `SHELL`
+# - Make setting : `.DELETE_ON_ERROR`
+# - Make setting : `.SECONDARY`
+# - Global variable : `sd.substitutions`
+# - Global variable : `sd.substitution_keys`
+# - Global variable : `sd.sed_process`
+# - Directory variable : `files.out.int`
+# - Target variable : `sd.ALL_CFLAGS`
+# - Target variable : `sd.ALL_CPPFLAGS`
+# - Target variable : `sd.ALL_LDFLAGS`
+# - Target variable : `sd.ALL_LIBTOLFLAGS`
+# - Target variable : `sd.COMPILE`
+# - Target variable : `sd.LTCOMPILE`
+# - Target variable : `sd.LINK`
+# - Target : `$$(outdir)/%.o`
+# - Target : `$$(outdir)/%.lo`
+# - Target : `$$(outdir)/$$(DEPDIR)`
+# - Target : `$$(outdir)/%.la`
+# - Target : `$$(addprefix $$(outdir)/,$$(am.out_PROGRAMS))`
+# - Target : `$$(outdir)/test-lib%-sym.c`
+# - Target : `$$(outdir)/%-from-name.gperf`
+# - Target : `$$(outdir)/%-from-name.h`
+# - Target : `$$(addprefix $$(outdir)/,$$(sd.sed_files))`
+# - Target : `$$(outdir)/%.c: $$(srcdir)/%.gperf`
+# - Target : `$$(outdir)/%: $$(srcdir)/%.m4`
+# ???:
+# - tests
+# - unsafe_tests
+# - TESTS
-GCC_COLORS ?= 'ooh, shiny!'
-export GCC_COLORS
+endef
-SUBDIRS = . po
+tests ?=
+unsafe_tests ?=
+TESTS = $(if $(ENABLE_TESTS),$(tests) \
+ $(if $(ENABLE_UNSAFE_TESTS),$(unsafe_tests)))
-# remove targets if the command fails
-.DELETE_ON_ERROR:
+# Make behavior
+SHELL = bash -o pipefail
-# keep intermediate files
+.DELETE_ON_ERROR:
.SECONDARY:
-# Keep the test-suite.log
-.PRECIOUS: $(TEST_SUITE_LOG) Makefile
+# Autoconf
+OUR_CPPFLAGS += -MT $@ -MD -MP -MF $(@D)/$(DEPDIR)/$(basename $(@F)).P$(patsubst .%,%,$(suffix $(@F)))
+OUR_CPPFLAGS += -include $(topoutdir)/config.h
+OUR_CPPFLAGS += $(sort -I$(@D) $(if $(<D),-I$(<D) -I$(call at.out2src,$(<D))))
+
+sd.ALL_CFLAGS = $(strip $(OUR_CFLAGS) $(am.CFLAGS) $(sd.CFLAGS) $(CFLAGS) )
+sd.ALL_CPPFLAGS = $(strip $(OUR_CPPFLAGS) $(am.CPPFLAGS) $(sd.CPPFLAGS) $(CPPFLAGS) )
+sd.ALL_LDFLAGS = $(strip $(OUR_LDFLAGS) $(am.LDFLAGS) $(sd.LDFLAGS) $(LDFLAGS) )
+sd.ALL_LIBTOOLFLAGS = $(strip $(OUR_LIBTOOLFLAGS) $(sd.LIBTOOLFLAGS) $(LIBTOOLFLAGS) )
+
+sd.COMPILE = $(CC) $(sd.ALL_CPPFLAGS) $(sd.ALL_CFLAGS)
+sd.LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(sd.ALL_LIBTOOLFLAGS) --mode=compile $(CC) $(sd.ALL_CPPFLAGS) $(sd.ALL_CFLAGS)
+sd.LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(sd.ALL_LIBTOOLFLAGS) --mode=link $(CCLD) $(sd.ALL_CFLAGS) $(sd.ALL_LDFLAGS) -o $@
+
+CC ?= c99
+CCLD ?= c99
+LIBTOOL ?= libtool
V ?=
-AM_V_M4 = $(AM_V_M4_$(V))
-AM_V_M4_ = $(AM_V_M4_$(AM_DEFAULT_VERBOSITY))
-AM_V_M4_0 = @echo " M4 " $@;
-AM_V_M4_1 =
-
-AM_V_GPERF = $(AM_V_GPERF_$(V))
-AM_V_GPERF_ = $(AM_V_GPERF_$(AM_DEFAULT_VERBOSITY))
-AM_V_GPERF_0 = @echo " GPERF " $@;
-AM_V_GPERF_1 =
-
-AM_V_RM = $(AM_V_RM_$(V))
-AM_V_RM_ = $(AM_V_RM_$(AM_DEFAULT_VERBOSITY))
-AM_V_RM_0 = @echo " RM " $@;
-AM_V_RM_1 =
-
-AM_V_CC = $(AM_V_CC_$(V))
-AM_V_CC_ = $(AM_V_CC_$(AM_DEFAULT_VERBOSITY))
-AM_V_CC_0 = @echo " CC " $@;
-AM_V_CC_1 =
-
-AM_V_CCLD = $(AM_V_CCLD_$(V))
-AM_V_CCLD_ = $(AM_V_CCLD_$(AM_DEFAULT_VERBOSITY))
-AM_V_CCLD_0 = @echo " CCLD " $@;
-AM_V_CCLD_1 =
-
-AM_V_P = $(AM_V_P_$(V))
-AM_V_P_ = $(AM_V_P_$(AM_DEFAULT_VERBOSITY))
-AM_V_P_0 = false
-AM_V_P_1 = :
-
-AM_V_GEN = $(AM_V_GEN_$(V))
-AM_V_GEN_ = $(AM_V_GEN_$(AM_DEFAULT_VERBOSITY))
-AM_V_GEN_0 = @echo " GEN " $@;
-AM_V_GEN_1 =
-
-AM_V_at = $(AM_V_at_$(V))
-AM_V_at_ = $(AM_V_at_$(AM_DEFAULT_VERBOSITY))
-AM_V_at_0 = @
-AM_V_at_1 =
-
-AM_V_lt = $(AM_V_lt_$(V))
-AM_V_lt_ = $(AM_V_lt_$(AM_DEFAULT_VERBOSITY))
-AM_V_lt_0 = --silent
-AM_V_lt_1 =
-
-INTLTOOL_V_MERGE = $(INTLTOOL_V_MERGE_$(V))
-INTLTOOL_V_MERGE_OPTIONS = $(intltool_v_merge_options_$(V))
-INTLTOOL_V_MERGE_ = $(INTLTOOL_V_MERGE_$(AM_DEFAULT_VERBOSITY))
-INTLTOOL_V_MERGE_0 = @echo " ITMRG " $@;
-INTLTOOL_V_MERGE_1 =
-
-substitutions = \
+AM_V_at ?= $(AM_V_at_$(V))
+AM_V_at_ ?= $(AM_V_at_$(AM_DEFAULT_VERBOSITY))
+AM_V_at_0 ?= @
+AM_V_at_1 ?=
+
+AM_V_M4 ?= $(AM_V_M4_$(V))
+AM_V_M4_ ?= $(AM_V_M4_$(AM_DEFAULT_VERBOSITY))
+AM_V_M4_0 ?= @echo " M4 " $@;
+AM_V_M4_1 ?=
+
+AM_V_GPERF ?= $(AM_V_GPERF_$(V))
+AM_V_GPERF_ ?= $(AM_V_GPERF_$(AM_DEFAULT_VERBOSITY))
+AM_V_GPERF_0 ?= @echo " GPERF " $@;
+AM_V_GPERF_1 ?=
+
+AM_V_RM ?= $(AM_V_RM_$(V))
+AM_V_RM_ ?= $(AM_V_RM_$(AM_DEFAULT_VERBOSITY))
+AM_V_RM_0 ?= @echo " RM " $@;
+AM_V_RM_1 ?=
+
+AM_V_CC ?= $(AM_V_CC_$(V))
+AM_V_CC_ ?= $(AM_V_CC_$(AM_DEFAULT_VERBOSITY))
+AM_V_CC_0 ?= @echo " CC " $@;
+AM_V_CC_1 ?=
+
+AM_V_CCLD ?= $(AM_V_CCLD_$(V))
+AM_V_CCLD_ ?= $(AM_V_CCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CCLD_0 ?= @echo " CCLD " $@;
+AM_V_CCLD_1 ?=
+
+AM_V_EFI_CC ?= $(AM_V_EFI_CC_$(V))
+AM_V_EFI_CC_ ?= $(AM_V_EFI_CC_$(AM_DEFAULT_VERBOSITY))
+AM_V_EFI_CC_0 ?= @echo " EFI_CC " $@;
+AM_V_EFI_CC_1 ?=
+
+AM_V_EFI_CCLD ?= $(AM_V_EFI_CCLD_$(V))
+AM_V_EFI_CCLD_ ?= $(AM_V_EFI_CCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_EFI_CCLD_0 ?= @echo " EFI_CCLD" $@;
+AM_V_EFI_CCLD_1 ?=
+
+AM_V_P ?= $(AM_V_P_$(V))
+AM_V_P_ ?= $(AM_V_P_$(AM_DEFAULT_VERBOSITY))
+AM_V_P_0 ?= false
+AM_V_P_1 ?= :
+
+AM_V_GEN ?= $(AM_V_GEN_$(V))
+AM_V_GEN_ ?= $(AM_V_GEN_$(AM_DEFAULT_VERBOSITY))
+AM_V_GEN_0 ?= @echo " GEN " $@;
+AM_V_GEN_1 ?=
+
+AM_V_lt ?= $(AM_V_lt_$(V))
+AM_V_lt_ ?= $(AM_V_lt_$(AM_DEFAULT_VERBOSITY))
+AM_V_lt_0 ?= --silent
+AM_V_lt_1 ?=
+
+INTLTOOL_V_MERGE ?= $(INTLTOOL_V_MERGE_$(V))
+INTLTOOL_V_MERGE_OPTIONS ?= $(intltool_v_merge_options_$(V))
+INTLTOOL_V_MERGE_ ?= $(INTLTOOL_V_MERGE_$(AM_DEFAULT_VERBOSITY))
+INTLTOOL_V_MERGE_0 ?= @echo " ITMRG " $@;
+INTLTOOL_V_MERGE_1 ?=
+
+sd.substitutions = \
'|rootlibexecdir=$(rootlibexecdir)|' \
'|rootbindir=$(rootbindir)|' \
'|bindir=$(bindir)|' \
@@ -156,10 +248,9 @@ substitutions = \
'|binfmtdir=$(binfmtdir)|' \
'|modulesloaddir=$(modulesloaddir)|'
-SED_PROCESS = \
+sd.substitution_keys := $(subst |,,$(shell printf '%s\n' $(sd.substitutions) | cut -d= -f1))
+
+sd.SED_PROCESS = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
- $(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(substitutions)))) \
+ $(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(sd.substitutions)))) \
< $< > $@
-
-
-include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/build-aux/Makefile.once.head/20-sdman.mk b/build-aux/Makefile.once.head/20-sdman.mk
index 3fb076febe..558c60531d 100644
--- a/build-aux/Makefile.once.head/20-sdman.mk
+++ b/build-aux/Makefile.once.head/20-sdman.mk
@@ -20,20 +20,59 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
-include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
-include $(topsrcdir)/build-aux/Makefile.head.mk
-AM_V_XSLT = $(AM_V_XSLT_$(V))
-AM_V_XSLT_ = $(AM_V_XSLT_$(AM_DEFAULT_VERBOSITY))
-AM_V_XSLT_0 = @echo " XSLT " $@;
-AM_V_XSLT_1 =
+mod.sdman.description = (systemd) manpages
+mod.sdman.depends += am files write-atomic
+define mod.sdman.doc
+# User variables:
+# - `V`
+# - `AM_V_LN*`
+# - `AM_V_XSLT*`
+# - `LN_S`
+# - `XSLTPROC`
+# Inputs:
+# - Global variable : `ENABLE_MANPAGES`
+# - Global variable : `VERSION`
+# - Directory variable : `files.src.src`
+# Outputs:
+# - File : `$(srcdir)/Makefile-man.mk`
+# - Directory variable : `at.subdirs`
+# - Directory variable : `files.src.gen`
+# - Directory variable : `man_MANS`
+# - Directory variable : `noinst_DATA` (HTML)
+# - Target : `$(outdir)/%.1`
+# - Target : `$(outdir)/%.3`
+# - Target : `$(outdir)/%.5`
+# - Target : `$(outdir)/%.7`
+# - Target : `$(outdir)/%.8`
+# - Target : `$(outdir)/%.html`
+#
+# sdman -> Makefile-man.mk:
+# - Global variable : `sdman.html-alias`
+# Makefile-man.mk -> sdman:
+# - Directory variable : `sdman.MANPAGES`
+# - Directory variable : `sdman.MANPAGES_ALIAS`
+#
+# The `sdman.*` variables are the interface by which the module
+# communicates with the genrated Makefile-man.mk file. They should not
+# be used outside of the `sdman` module.
+endef
+mod.sdman.doc := $(value mod.sdman.doc)
+
+V ?=
+LN_S ?= ln -s
-AM_V_LN = $(AM_V_LN_$(V))
-AM_V_LN_ = $(AM_V_LN_$(AM_DEFAULT_VERBOSITY))
-AM_V_LN_0 = @echo " LN " $@;
-AM_V_LN_1 =
+AM_V_LN ?= $(AM_V_LN_$(V))
+AM_V_LN_ ?= $(AM_V_LN_$(AM_DEFAULT_VERBOSITY))
+AM_V_LN_0 ?= @echo " LN " $@;
+AM_V_LN_1 ?=
-XSLTPROC_FLAGS = \
+AM_V_XSLT ?= $(AM_V_XSLT_$(V))
+AM_V_XSLT_ ?= $(AM_V_XSLT_$(AM_DEFAULT_VERBOSITY))
+AM_V_XSLT_0 ?= @echo " XSLT " $@;
+AM_V_XSLT_1 ?=
+
+_sdman.XSLTPROC_FLAGS = \
--nonet \
--xinclude \
--stringparam man.output.quietly 1 \
@@ -41,18 +80,14 @@ XSLTPROC_FLAGS = \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0 \
--stringparam systemd.version $(VERSION) \
- --path '$(builddir)/man:$(srcdir)/man'
+ --path '$(outdir):$(srcdir):$(topoutdir)/man:$(topsrcdir)/man'
-XSLT = $(if $(XSLTPROC), $(XSLTPROC), xsltproc)
-XSLTPROC_PROCESS_MAN = \
- $(AM_V_XSLT)$(XSLT) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-man.xsl $<
+_sdman.XSLT = $(if $(XSLTPROC), $(XSLTPROC), xsltproc)
+_sdman.XSLTPROC_PROCESS_MAN = \
+ $(AM_V_XSLT)$(_sdman.XSLT) -o $@ $(_sdman.XSLTPROC_FLAGS) $(srcdir)/man/custom-man.xsl $<
-XSLTPROC_PROCESS_HTML = \
- $(AM_V_XSLT)$(XSLT) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $<
+_sdman.XSLTPROC_PROCESS_HTML = \
+ $(AM_V_XSLT)$(_sdman.XSLT) -o $@ $(_sdman.XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $<
-define html-alias
+sdman.html-alias = \
$(AM_V_LN)$(LN_S) -f $(notdir $<) $@
-endef
-
-
-include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/build-aux/Makefile.once.head/30-am.mk b/build-aux/Makefile.once.head/30-am.mk
new file mode 100644
index 0000000000..5427e8004d
--- /dev/null
+++ b/build-aux/Makefile.once.head/30-am.mk
@@ -0,0 +1,282 @@
+mod.am.description = (systemd) Automake-to-Autothing magic
+mod.am.depends += gnuconf
+define mod.am.doc
+# Because many of the inputs/outpus are repetative, they are defined
+# here in terms of $$(primary), which may be any of the supported
+# Automake primaries (see below for a table).
+#
+# | Automake 1.15 primaries |
+# +-------------------------+
+# | name | supported |
+# +-------------+-----------+
+# | PROGRAMS | yes |
+# | LIBRARIES | no |
+# | LTLIBRARIES | yes |
+# | LISP | no |
+# | PYTHON | no |
+# | JAVA | no |
+# | SCRIPTS | yes |
+# | DATA | yes |
+# | HEADERS | yes |
+# | MANS | yes |
+# | TEXINFOS | no |
+#
+# Further, there is also $$(dirname), which could be anything; and is
+# detected at runtime by inspecting $$(.VARIABLES) to find every possible
+# matching value. See `_am.primary2dirs` for how this is done.
+#
+# Some inputs are "erased" after the pass they are used in. This means
+# that they are `undefine`ed.
+#
+$(value _am.pass0.doc)
+#
+$(value _am.pass1.doc)
+#
+$(value _am.pass2.doc)
+#
+$(value _am.pass3.doc)
+#
+$(value _am.pass4.doc)
+#
+$(value _am.pass5.doc)
+endef
+
+_am.primaries =
+_am.primaries += PROGRAMS
+#_am.primaries += LIBRARIES
+_am.primaries += LTLIBRARIES
+#_am.primaries += LISP
+#_am.primaries += PYTHON
+#_am.primaries += JAVA
+_am.primaries += SCRIPTS
+_am.primaries += DATA
+_am.primaries += HEADERS
+_am.primaries += MANS
+#_am.primaries += TEXINFOS
+
+# Used by the per_PROGRAM and per_LTLIBRARY passes
+_am.file2var = $(subst -,_,$(subst .,_,$1))
+_am.file2sources = $(addprefix $(srcdir)/,$(notdir $($(_am.file2var)_SOURCES)))
+_am.file2sources += $(addprefix $(outdir)/,$(notdir $(nodist_$(_am.file2var)_SOURCES)))
+_am.file2.o = $(patsubst $(srcdir)/%,$(outdir)/%,$(patsubst %.c,%.o ,$(filter %.c,$(_am.file2sources))))
+_am.file2.lo = $(patsubst %.o,%.lo,$(_am.file2.o))
+_am.file2lib = $(foreach l, $($(_am.file2var)_$2),$(if $(filter lib%.la,$l), $($(l:.la=).DEPENDS) , $l ))
+_am.file2cpp = $(foreach l,$1 $($(_am.file2var)_$2),$(if $(filter lib%.la,$l), $($(l:.la=).CPPFLAGS) , ))
+
+define _am.pass0.doc
+# == Pass 0: man_MANS ==
+# Erased inputs:
+# - Directory variable: `man_MANS`
+# Outputs:
+# - Directory variable: `man$n_MANS` for $n in `{0..9} n l`
+#
+# Split man_MANS into man$n_MANS
+endef
+define _am.pass0
+man_MANS ?=
+_am.man_MANS := $(man_MANS)
+undefine man_MANS
+man0_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .0,$(suffix $(_am.tmp))),$(_am.tmp)))
+man1_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .1,$(suffix $(_am.tmp))),$(_am.tmp)))
+man2_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .2,$(suffix $(_am.tmp))),$(_am.tmp)))
+man3_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .3,$(suffix $(_am.tmp))),$(_am.tmp)))
+man4_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .4,$(suffix $(_am.tmp))),$(_am.tmp)))
+man5_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .5,$(suffix $(_am.tmp))),$(_am.tmp)))
+man6_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .6,$(suffix $(_am.tmp))),$(_am.tmp)))
+man7_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .7,$(suffix $(_am.tmp))),$(_am.tmp)))
+man8_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .8,$(suffix $(_am.tmp))),$(_am.tmp)))
+man9_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .9,$(suffix $(_am.tmp))),$(_am.tmp)))
+manl_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .l,$(suffix $(_am.tmp))),$(_am.tmp)))
+mann_MANS += $(foreach _am.tmp,$(_am.man_MANS),$(if $(findstring .n,$(suffix $(_am.tmp))),$(_am.tmp)))
+endef
+
+define _am.pass1.doc
+# == Pass 1: _am.per_primary ==
+# Inputs:
+# - Global variable : `am.INSTALL_$(primary)`
+# - Global variable : `am.sys2out_$(primary)`
+# - Global variable : `$(dirname)dir`
+# Erased inputs:
+# - Directory variable : `$(dirname)_$(primary)` [1] [2]
+# - Directory variable : `dist_$(dirname)_$(primary)` [1] [2]
+# - Directory variable : `nodist_$(dirname)_$(primary)` [1] [2]
+# - Directory variable : `noinst_$(primary)` [2]
+# - Directory variable : `check_$(primary)` [2]
+# Outputs:
+# - Directory variable : `am.sys_$(primary)`
+# - Directory variable : `am.out_$(primary)`
+# - Directory variable : `am.check_$(primary)`
+# - Target variable : `am.INSTALL`
+#
+# [1]: HACK: Each of these is first passed through `$(dir ...)`.
+#
+# [2]: HACK: For `am.out_*` each of these are turned into
+# $(DESTDIR)-relative paths (ie, as if for `am.sys_*`), then turned
+# back into $(outdir)-relative paths with `$(call
+# am.sys2out_$(primary),...)`.
+endef
+
+# Default values
+am.INSTALL_PROGRAMS ?= $(INSTALL_PROGRAM) $< $@
+am.INSTALL_SCRIPTS ?= $(INSTALL) $< $@
+am.INSTALL_LTLIBRARIES ?= $(INSTALL) $< $@
+am.INSTALL_DATA ?= $(INSTALL_DATA) $< $@
+am.INSTALL_HEADERS ?= $(INSTALL_DATA) $< $@
+am.INSTALL_MANS ?= $(INSTALL_DATA) $< $@
+$(eval $(foreach p,$(_am.primaries),am.sys2out_$p ?= $$(notdir $$1)$(at.nl)))
+
+# Utility functions
+_am.primary2dirs = $(filter $(patsubst %dir,%,$(filter %dir,$(.VARIABLES))),\
+ $(patsubst nodist_%,%,$(patsubst dist_%,%,$(patsubst %_$1,%,$(filter %_$1,$(.VARIABLES))))))
+
+_am.pass1 = $(eval $(foreach p,$(_am.primaries) ,$(call _am.per_primary,$p)$(at.nl)))
+define _am.per_primary
+# Initialize input variables
+$(foreach d,$(call _am.primary2dirs,$1),\
+ $d_$1 ?=$(at.nl)\
+ dist_$d_$1 ?=$(at.nl)\
+ nodist_$d_$1 ?=$(at.nl))
+noinst_$1 ?=
+check_$1 ?=
+
+# Directory variable outputs
+am.check_$1 := $$(check_$1)
+am.sys_$1 := $(foreach d,$(call _am.primary2dirs,$1),$$(addprefix $$($ddir)/,$$(notdir $$($d_$1) $$(dist_$d_$1) $$(nodist_$d_$1))))
+am.out_$1 := $$(call am.sys2out_$1,$(foreach d,$(call _am.primary2dirs,$1),$$(addprefix $$($ddir)/,$$(notdir $$($d_$1) $$(nodist_$d_$1)))) $$(noinst_$1))
+# ^^^ ^
+# notdir-'|| |
+# addprefix--'| |
+# foreach d---' |
+# am.sys2out------------------'
+
+# Erase appropriate inputs
+$(foreach d,$(call _am.primary2dirs,$1),undefine $d_$1$(at.nl)undefine dist_$d_$1$(at.nl)undefine nodist_$d_$1$(at.nl))
+undefine noinst_$1
+undefine check_$1
+
+# Target variable outputs
+$$(addprefix $$(DESTDIR),$$(am.sys_$1)): private am.INSTALL = $$(am.INSTALL_$1)
+endef
+
+define _am.pass2.doc
+# == Pass 2: _am.per_PROGRAM ==
+# Inputs:
+# - Directory variable : `am.out_PROGRAMS`
+# Erased inputs:
+# - Directory variable : `$(program)_SOURCES`
+# - Directory variable : `nodist_$(program)_SOURCES`
+# - Directory variable : `$(program)_CFLAGS`
+# - Directory variable : `$(program)_CPPFLAGS`
+# - Directory variable : `$(program)_LDFLAGS`
+# - Directory variable : `$(program)_LDADD`
+# Outputs:
+# - Directory variable : `am.CPPFLAGS`
+# - Directory variable : `am.CFLAGS`
+# - Target dependencies: `$(outdir)/$(program)`
+# - Target variable : `$(outdir)/$(program): am.LDFLAGS`
+# - Directory variable : `am.subdirs`
+#
+# TODO: I'm not in love with how it figures out `am.subdirs`.
+endef
+_am.pass2 = $(eval $(foreach f,$(am.out_PROGRAMS) ,$(call _am.per_PROGRAM,$f,$(call _am.file2var,$f))$(at.nl)))
+_am.var_PROGRAMS = $1_SOURCES nodist_$1_SOURCES $1_CFLAGS $1_CPPFLAGS $1_LDFLAGS $1_LDADD
+# $1 = filename
+# $2 = varname
+define _am.per_PROGRAM
+$(foreach var,_am.depends $(call _am.var_PROGRAMS,$2),$(var) ?=$(at.nl))
+_am.depends += $$(call at.path,$$(call _am.file2.o,$1) $$(call _am.file2lib,$1,LDADD))
+am.CPPFLAGS += $$($2_CPPFLAGS) $$(call _am.file2cpp,$1,LDADD)
+am.CFLAGS += $$($2_CFLAGS)
+$$(outdir)/$1: private am.LDFLAGS := $$($2_LDFLAGS)
+$$(outdir)/$1: $$(_am.depends)
+am.subdirs := $$(sort $$(am.subdirs)\
+ $$(filter-out $$(abspath $$(srcdir)),\
+ $$(abspath $$(dir $$(filter-out -l% /%,$$(_am.depends))))))
+am.CPPFLAGS := $$(am.CPPFLAGS)
+am.CFLAGS := $$(am.CFLAGS)
+$(foreach var,_am.depends $(call _am.var_PROGRAMS,$2),undefine $(var)$(at.nl))
+endef
+
+define _am.pass3.doc
+# == Pass 3: _am.per_LTLIBRARY ==
+# Inputs:
+# - Directory variable : `am.out_LTLIBRARIES`
+# Erased inputs:
+# - Directory variable : `$(library)_SOURCES`
+# - Directory variable : `nodist_$(library)_SOURCES`
+# - Directory variable : `$(library)_CFLAGS`
+# - Directory variable : `$(library)_CPPFLAGS`
+# - Directory variable : `$(library)_LDFLAGS`
+# - Directory variable : `$(library)_LIBADD`
+# Outputs:
+# - Directory variable : `am.CPPFLAGS`
+# - Directory variable : `am.CFLAGS`
+# - Target dependencies: `$(outdir)/$(library)`
+# - Target variable : `$(outdir)/$(library): am.LDFLAGS`
+# - Directory variable : `am.subdirs`
+#
+# TODO: I'm not in love with how it figures out `am.subdirs`.
+endef
+_am.pass3 = $(eval $(foreach f,$(am.out_LTLIBRARIES),$(call _am.per_LTLIBRARY,$f,$(call _am.file2var,$f))$(at.nl)))
+_am.var_LTLIBRARIES = $1_SOURCES nodist_$1_SOURCES $1_CFLAGS $1_CPPFLAGS $1_LDFLAGS $1_LIBADD
+# $1 = filename
+# $2 = varname
+define _am.per_LTLIBRARY
+$(foreach var,_am.depends $(call _am.var_LTLIBRARIES,$2),$(var) ?=$(at.nl))
+_am.depends += $$(call at.path,$$(call _am.file2.lo,$1) $$(call _am.file2lib,$1,LIBADD))
+am.CPPFLAGS += $$($2_CPPFLAGS) $$(call _am.file2cpp,$1,LIBADD)
+am.CFLAGS += $$($2_CFLAGS)
+$$(outdir)/$1: private am.LDFLAGS := $$($2_LDFLAGS)
+$$(outdir)/$1: $$(_am.depends)
+am.subdirs := $$(sort $$(am.subdirs)\
+ $$(filter-out $$(abspath $$(srcdir)),\
+ $$(abspath $$(dir $$(filter-out -l% /%,$$(_am.depends))))))
+am.CPPFLAGS := $$(am.CPPFLAGS)
+am.CFLAGS := $$(am.CFLAGS)
+$(foreach var,_am.depends $(call _am.var_LTLIBRARIES,$2),undefine $(var)$(at.nl))
+endef
+
+define _am.pass4.doc
+# == Pass 4: Install rules / _am.per_directory ==
+# Inputs:
+# - Directory variable : `am.sys_$(primary)`
+# Outputs:
+# - Target : `$(DESTDIR)/$($(dirname)dir)/%`
+#
+# Creates simple `install` rules. You will need to define your own rules if
+# `am.sys2out_$(primary)` changed the notdir part of the filename.
+endef
+
+# Utility functions
+_am.sys2dirs = $(sort $(patsubst %/,%,$(dir $(foreach p,$(_am.primaries),$(am.sys_$p)))))
+
+_am.pass4 = $(eval $(foreach d,$(_am.sys2dirs) ,$(call _am.per_directory,$d)$(at.nl)))
+define _am.per_directory
+$$(DESTDIR)$1/%: $$(outdir)/%
+ @$$(NORMAL_INSTALL)
+ $$(am.INSTALL)
+$$(DESTDIR)$1/%: $$(srcdir)/%
+ @$$(NORMAL_INSTALL)
+ $$(am.INSTALL)
+endef
+
+mod.am.depends += files
+define _am.pass5.doc
+# == Pass 5: export ==
+# Inputs:
+# - Directory variable : `am.subdirs`
+# - Directory variable : `am.sys_$(primary)`
+# - Directory variable : `am.out_$(primary)`
+# - Directory variable : `am.check_$(primary)`
+# Outputs:
+# - Directory variable : `at.subdirs`
+# - Directory variable : `files.sys.all`
+# - Directory variable : `files.out.all`
+# - Directory variable : `files.out.check`
+endef
+define _am.pass5
+at.subdirs += $(am.subdirs)
+files.sys.all += $(foreach p,$(_am.primaries),$(am.sys_$p))
+files.out.all += $(foreach p,$(_am.primaries),$(am.out_$p))
+files.out.check += $(foreach p,$(_am.primaries),$(am.check_$p))
+endef
diff --git a/build-aux/Makefile.once.head/zz-mod.mk b/build-aux/Makefile.once.head/zz-mod.mk
new file mode 100644
index 0000000000..95d251d37c
--- /dev/null
+++ b/build-aux/Makefile.once.head/zz-mod.mk
@@ -0,0 +1,59 @@
+# Copyright (C) 2016 Luke Shumaker
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+mod.mod.description = Display information about Autothing modules
+mod.mod.depends += quote
+define mod.mod.doc
+# Inputs:
+# - Files : `$(topsrcdir)/build-aux/Makefile.*/??-*.mk`
+# - Global variable : `mod.*.description`
+# - Global variable : `mod.*.depends`
+# - Global variable : `mod.*.files`
+# - Global variable : `mod.*.doc`
+# Outputs:
+# - Directory variable : `at.targets`
+# - .PHONY Target : `$(outdir)/at-variables-local`
+# - .PHONY Target : `$(outdir)/at-variables-global`
+# - .PHONY Target : `$(outdir)/at-variables`
+# - .PHONY Target : `$(outdir)/at-variables/%`
+# - .PHONY Target : `$(outdir)/at-values`
+# - .PHONY Target : `$(outdir)/at-values/%`
+# - .PHONY Target : `$(outdir)/at-modules`
+# - .PHONY Target : `$(outdir)/at-modules/%`
+# - .PHONY Target : `$(outdir)/at-noop`
+#
+# TODO: prose documentation
+endef
+mod.mod.doc := $(value mod.mod.doc)
+
+# The trickery that is _mod.empty/_mod.space is from §6.2 of the GNU Make
+# manual, "The Two Flavors of Variables".
+_mod.empty :=
+_mod.space := $(_mod.empty) #
+undefine _mod.empty
+# _mod.rest is equivalent to GMSL rest.
+_mod.rest = $(wordlist 2,$(words $1),$1)
+
+_mod.file2mod = $(foreach _mod.tmp,$(patsubst %.mk,%,$(notdir $1)),$(subst $(_mod.space),-,$(call _mod.rest,$(subst -, ,$(_mod.tmp)))))
+
+_mod.modules := $(sort $(call _mod.file2mod,$(wildcard $(topsrcdir)/build-aux/Makefile.*/??-*.mk)))
+undefine _mod.rest
+undefine _mod.file2mod
+
+$(eval $(foreach _mod.tmp,$(_mod.modules),\
+ mod.$(_mod.tmp).description ?=$(at.nl)\
+ mod.$(_mod.tmp).depends ?=$(at.nl)\
+ mod.$(_mod.tmp).files ?=$(at.nl)\
+ mod.$(_mod.tmp).doc ?=$(at.nl)))