summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-aux/Makefile.each.head/00-dist.mk5
-rw-r--r--build-aux/Makefile.each.head/00-files.mk29
-rw-r--r--build-aux/Makefile.each.head/00-nested.mk16
-rw-r--r--build-aux/Makefile.each.head/zz-mod.mk1
-rw-r--r--build-aux/Makefile.each.tail/10-files.mk55
-rw-r--r--build-aux/Makefile.each.tail/10-nested.mk19
-rw-r--r--build-aux/Makefile.each.tail/10-std.mk46
-rw-r--r--build-aux/Makefile.each.tail/30-directory-info.mk4
-rw-r--r--build-aux/Makefile.head.mk101
-rw-r--r--build-aux/Makefile.once.head/00-write-ifchanged.mk1
-rw-r--r--build-aux/Makefile.once.head/10-dist.mk (renamed from build-aux/Makefile.once.head/00-dist.mk)10
-rw-r--r--build-aux/Makefile.once.head/10-files.mk (renamed from build-aux/Makefile.once.head/10-std.mk)26
-rw-r--r--build-aux/Makefile.once.head/10-gnuconf.mk (renamed from build-aux/Makefile.once.head/00-gnuconf.mk)56
-rw-r--r--build-aux/Makefile.once.head/10-lt.mk12
-rw-r--r--build-aux/Makefile.once.head/10-nested.mk18
-rw-r--r--build-aux/Makefile.once.head/10-write-ifchanged.mk3
-rw-r--r--build-aux/Makefile.once.head/zz-mod.mk24
-rw-r--r--build-aux/Makefile.once.tail/00-dist.mk12
-rw-r--r--build-aux/Makefile.once.tail/00-mod.mk32
-rw-r--r--build-aux/Makefile.once.tail/00-noop.mk2
-rw-r--r--build-aux/Makefile.tail.mk40
-rw-r--r--build-aux/no-builtin-variables.mk15
22 files changed, 366 insertions, 161 deletions
diff --git a/build-aux/Makefile.each.head/00-dist.mk b/build-aux/Makefile.each.head/00-dist.mk
index a094305..924d79a 100644
--- a/build-aux/Makefile.each.head/00-dist.mk
+++ b/build-aux/Makefile.each.head/00-dist.mk
@@ -13,8 +13,11 @@
# 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.depends += files
+
ifeq ($(outdir),$(topoutdir))
-std.clean_files += $(addprefix $(dist.pkgname)-*,$(dist.exts) .tar /)
+files.out.int += $(addprefix $(dist.pkgname)-*,$(dist.exts) .tar /) .tmp.$(dist.pkgname)-*/
endif
$(outdir)/dist: $(addprefix $(topoutdir)/$(dist.pkgname)-$(dist.version),$(dist.exts))
+.PHONY: $(outdir)/dist
diff --git a/build-aux/Makefile.each.head/00-files.mk b/build-aux/Makefile.each.head/00-files.mk
new file mode 100644
index 0000000..7bf323e
--- /dev/null
+++ b/build-aux/Makefile.each.head/00-files.mk
@@ -0,0 +1,29 @@
+# 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/>.
+
+files.src.src ?=
+files.src.int ?=
+files.src.cfg ?=
+files.src.gen ?=
+files.src = $(sort $(foreach _files.v,$(filter files.src.%,$(.VARIABLES)),$($(_files.v))))
+
+files.out.slow ?=
+files.out.int ?=
+files.out.cfg ?=
+$(foreach t,$(files.groups),$(eval files.out.$t ?=))
+files.out = $(sort $(foreach _files.v,$(filter files.out.%,$(.VARIABLES)),$($(_files.v))))
+
+$(foreach t,$(files.groups),$(eval files.sys.$t ?=))
+files.sys = $(sort $(foreach _files.v,$(filter files.sys.%,$(.VARIABLES)),$($(_files.v))))
diff --git a/build-aux/Makefile.each.head/00-nested.mk b/build-aux/Makefile.each.head/00-nested.mk
new file mode 100644
index 0000000..4325825
--- /dev/null
+++ b/build-aux/Makefile.each.head/00-nested.mk
@@ -0,0 +1,16 @@
+# 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/>.
+
+nested.subdirs ?=
diff --git a/build-aux/Makefile.each.head/zz-mod.mk b/build-aux/Makefile.each.head/zz-mod.mk
new file mode 100644
index 0000000..b83c223
--- /dev/null
+++ b/build-aux/Makefile.each.head/zz-mod.mk
@@ -0,0 +1 @@
+_mod.each := $(sort $(_mod.each) $(filter-out $(_mod.once),$(_mod.vars)))
diff --git a/build-aux/Makefile.each.tail/10-files.mk b/build-aux/Makefile.each.tail/10-files.mk
new file mode 100644
index 0000000..4607c43
--- /dev/null
+++ b/build-aux/Makefile.each.tail/10-files.mk
@@ -0,0 +1,55 @@
+# 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/>.
+# Add some more defaults to the *_files variables
+
+$(foreach _files.var,$(patsubst files.%,%,files.src $(filter files.src.%,$(.VARIABLES))),\
+ $(eval _files.$(_files.var) = $$(call at.addprefix,$$(srcdir),$$(files.$(_files.var)))))
+$(foreach _files.var,$(patsubst files.%,%,files.out $(filter files.out.%,$(.VARIABLES))),\
+ $(eval _files.$(_files.var) = $$(call at.addprefix,$$(outdir),$$(files.$(_files.var)))))
+$(foreach _files.var,$(patsubst files.%,%,files.sys $(filter files.sys.%,$(.VARIABLES))),\
+ $(eval _files.$(_files.var) = $$(addprefix $$(DESTDIR),$$(files.$(_files.var)))))
+
+_files.all = $(_files.src) $(_files.out) $(_files.sys)
+
+at.targets += $(subst *,%,$(_files.all))
+
+# Creative targets
+$(outdir)/$(files.generate): $(_files.src.gen) $(_files.src.cfg)
+$(outdir)/install: $(_files.sys.$(files.default))
+$(outdir)/installdirs: $(sort $(dir $(_files.sys)))
+$(foreach _files.g,$(files.groups),\
+ $(eval $$(outdir)/$(_files.g): $$(_files.out.$(_files.g))))
+$(foreach _files.g,$(filter-out $(files.default),$(files.groups)),\
+ $(eval $$(outdir)/install-$(_files.g): $$(_files.sys.$(_files.g))))
+
+# Destructive targets
+_files.uninstall = $(_files.sys)
+_files.mostlyclean = $(filter-out $(_files.out.slow) $(_files.out.cfg),$(_files.out))
+_files.clean = $(filter-out $(_files.out.cfg),$(_files.out))
+_files.distclean = $(_files.out)
+$(addprefix $(outdir)/,uninstall mostlyclean clean distclean): %: %-hook
+ $(RM) -- $(sort $(filter-out %/,$(_files.$(@F))))
+ $(RM) -r -- $(sort $(filter %/,$(_files.$(@F))))
+ $(RMDIR_P) -- $(sort $(dir $(_files.$(@F))))
+_files.maintainer-clean = $(filter-out $(_files.src.cfg) $(_files.src.src),$(_files.src))
+_files.$(files.vcsclean) = $(filter-out $(_files.src.src),$(_files.src))
+$(addprefix $(outdir)/,maintainer-clean $(files.vcsclean)): $(outdir)/%: $(outdir)/distclean $(outdir)/%-hook
+ @echo 'This command is intended for maintainers to use; it'
+ @echo 'deletes files that may need special tools to rebuild.'
+ $(RM) -- $(sort $(filter-out %/,$(_files.$(@F))))
+ $(RM) -r -- $(sort $(filter %/,$(_files.$(@F))))
+ $(RMDIR_P) -- $(sort $(dir $(_files.$(@F))))
+$(foreach t,uninstall mostlyclean clean distclean maintainer-clean $(files.vcsclean), $(outdir)/$t-hook)::
+.PHONY: $(foreach t,uninstall mostlyclean clean distclean maintainer-clean $(files.vcsclean), $(outdir)/$t-hook)
diff --git a/build-aux/Makefile.each.tail/10-nested.mk b/build-aux/Makefile.each.tail/10-nested.mk
new file mode 100644
index 0000000..e9d02ca
--- /dev/null
+++ b/build-aux/Makefile.each.tail/10-nested.mk
@@ -0,0 +1,19 @@
+# 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/>.
+
+$(addprefix $(outdir)/,$(nested.targets)): $(outdir)/%: $(addsuffix /%,$(call at.addprefix,$(outdir),$(nested.subdirs)))
+.PHONY: $(addprefix $(outdir)/,$(nested.targets))
+
+at.subdirs += $(nested.subdirs)
diff --git a/build-aux/Makefile.each.tail/10-std.mk b/build-aux/Makefile.each.tail/10-std.mk
deleted file mode 100644
index ca78f3c..0000000
--- a/build-aux/Makefile.each.tail/10-std.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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/>.
-# Add some more defaults to the *_files variables
-std.clean_files += $(std.gen_files) $(std.cfg_files) $(std.out_files)
-
-# Fix each variable at its current value to avoid any weirdness
-$(foreach c,src gen cfg out sys clean slow,$(eval std.$c_files := $$(std.$c_files)))
-
-# Make each of the standard variables relative to the correct directory
-std.src_files := $(call at.addprefix,$(srcdir)/,$(std.src_files))
-std.gen_files := $(call at.addprefix,$(srcdir)/,$(std.gen_files))
-std.cfg_files := $(call at.addprefix,$(outdir)/,$(std.cfg_files))
-std.out_files := $(call at.addprefix,$(outdir)/,$(std.out_files))
-std.sys_files := $(addprefix $(DESTDIR),$(std.sys_files))
-std.clean_files := $(call at.addprefix,$(outdir)/,$(std.clean_files))
-std.slow_files := $(call at.addprefix,$(outdir)/,$(std.slow_files))
-
-# Creative targets
-$(outdir)/build : $(std.out_files)
-$(outdir)/install : $(std.sys_files)
-$(outdir)/installdirs: $(sort $(dir $(std.sys_files)))
-
-# Destructive targets
-_std.uninstall/$(outdir) := $(std.sys_files)
-_std.mostlyclean/$(outdir) := $(filter-out $(std.slow_files) $(std.cfg_files) $(std.gen_files) $(std.src_files),$(std.clean_files))
-_std.clean/$(outdir) := $(filter-out $(std.cfg_files) $(std.gen_files) $(std.src_files),$(std.clean_files))
-_std.distclean/$(outdir) := $(filter-out $(std.gen_files) $(std.src_files),$(std.clean_files))
-_std.maintainer-clean/$(outdir) := $(filter-out $(std.src_files),$(std.clean_files))
-$(addprefix $(outdir)/,uninstall mostlyclean clean distclean maintainer-clean): %: %-hook
- $(RM) -- $(sort $(filter-out %/,$(_std.$(@F)/$(@D))))
- $(RM) -r -- $(sort $(filter %/,$(_std.$(@F)/$(@D))))
- $(RMDIR_P) $(sort $(dir $(_std.$(@F)/$(@D)))) 2>/dev/null || $(TRUE)
-$(foreach t,uninstall mostlyclean clean distclean maintainer-clean, $(outdir)/$t-hook)::
-.PHONY: $(foreach t,uninstall mostlyclean clean distclean maintainer-clean, $(outdir)/$t-hook)
diff --git a/build-aux/Makefile.each.tail/30-directory-info.mk b/build-aux/Makefile.each.tail/30-directory-info.mk
deleted file mode 100644
index 80f5e68..0000000
--- a/build-aux/Makefile.each.tail/30-directory-info.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-dir_variables = $(foreach v,$(filter-out _%,$(patsubst %/$(@D),%,$(filter %/$(@D),$(.VARIABLES)))),$(if $(findstring /,$v),, $v))
-$(outdir)/directory-info:
- $(AM_V_at)printf '%s = «%s»\n' $(foreach v,$(dir_variables),$(if $($v/$(@D)),'$v' '$($v/$(@D))')) | sort | column -s= -o= -t
-.PHONY: $(outdir)/module-info
diff --git a/build-aux/Makefile.head.mk b/build-aux/Makefile.head.mk
index 36c2c0a..8213043 100644
--- a/build-aux/Makefile.head.mk
+++ b/build-aux/Makefile.head.mk
@@ -12,60 +12,103 @@
#
# 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/>.
+
+_at.MAKEFILE_LIST ?=
+_at.MAKEFILE_LIST := $(strip $(_at.MAKEFILE_LIST) $(abspath $(lastword $(filter-out %.mk,$(MAKEFILE_LIST)))))
# This bit only gets evaluated once, at the very beginning
ifeq ($(origin _at.NO_ONCE),undefined)
+# Internal functions ###################################################
+
+# These 4 functions are all $(call _at.func,parent,child)
+_at.is_strict_subdir = $(filter $(abspath $1)/%,$(abspath $2))
+_at.is_subdir = $(filter $(abspath $1)/%,$(abspath $2)/.)
+_at.relbase = $(strip \
+ $(if $(call _at.is_subdir,$1,$2), \
+ $(patsubst $(abspath $1)/%,%,$(abspath $2)/.), \
+ $(abspath $2)))
+_at.relto = $(strip \
+ $(if $(call _at.is_subdir,$1,$2), \
+ $(patsubst $(abspath $1)/%,%,$(abspath $2)/.), \
+ ../$(call _at.relto,$(dir $1),$2)))
+
+# These 3 functions only take one operand; we define public multi-operand
+# versions below.
+_at.path = $(strip \
+ $(if $(call _at.is_subdir,$(topoutdir),$1), \
+ $(patsubst %/.,%,$(topoutdir)/$(call _at.relto,.,$1)), \
+ $(if $(call _at.is_subdir,$(topsrcdir),$1), \
+ $(patsubst %/.,%,$(topsrcdir)/$(call _at.relto,$(topsrcdir),$1)), \
+ $(abspath $1))))
+_at.out2src = $(call _at.path,$(if $(call _at.is_subdir,$(topoutdir),$1),$(topsrcdir)/$(call _at.path,$1),$1))
+_at.addprefix = $(call _at.path,$(if $(filter-out /%,$2),$1/$2,$2))
+
+_at.rest = $(wordlist 2,$(words $1),$1)
+_at.reverse = $(if $1,$(call _at.reverse,$(_at.rest))) $(firstword $1)
+
+# Sanity checking ######################################################
+ifeq ($(filter undefine,$(.FEATURES)),)
+$(error Autothing: We need a version of Make that supports 'undefine')
+endif
ifeq ($(topsrcdir),)
-$(error topsrcdir must be set before including Makefile.head.mk)
+$(error Autothing: topsrcdir must be set (and non-empty) before including Makefile.head.mk)
endif
ifeq ($(topoutdir),)
-$(error topoutdir must be set before including Makefile.head.mk)
+$(error Autothing: topoutdir must be set (and non-empty) before including Makefile.head.mk)
endif
+ifneq ($(call _at.is_strict_subdir,$(topoutdir),$(topsrcdir)),)
+$(error Autothing: topsrcdir=$(topsrcdir) must not be a subdirectory of topoutdir=$(topoutdir))
+endif
+
+# Internal setup #######################################################
-_at.noslash = $(patsubst %/.,%,$(patsubst %/,%,$1))
-# These are all $(call _at.func,parent,child)
-#at.relto = $(if $2,$(shell realpath -sm --relative-to='$1' $2))
-_at.is_subdir = $(filter $(abspath $1)/%,$(abspath $2)/.)
-_at.relto_helper = $(if $(call _at.is_subdir,$1,$2),$(patsubst $1/%,%,$(addsuffix /.,$2)),$(addprefix ../,$(call _at.relto_helper,$(patsubst %/,%,$(dir $1)),$2)))
-_at.relto = $(call _at.noslash,$(call _at.relto_helper,$(call _at.noslash,$(abspath $1)),$(call _at.noslash,$(abspath $2))))
-at.relto = $(foreach p,$2,$(call _at.relto,$1,$p))
-# Note that _at.is_subdir says that a directory is a subdirectory of
-# itself.
-at.path = $(call at.relto,.,$1)
+# External provisions ##################################################
-_at.addprefix = $(if $(filter /%,$2),$2,$1/$2)
-at.addprefix = $(foreach f,$2, $(addsuffix $(if $(filter %/,$f),/),$(call at.path,$(call _at.addprefix,$1,$f)) ))
+# These 4 functions are all $(call _at.func,parent,child)
+at.is_subdir = $(_at.is_subdir)
+at.is_strict_subdir = $(_at.is_strict_subdir)
+#at.relbase = $(if $2,$(shell realpath -sm --relative-base=$1 -- $2))
+at.relbase = $(foreach _at.tmp,$2,$(call _at.relbase,$1,$(_at.tmp)))
+#at.relto = $(if $2,$(shell realpath -sm --relative-to=$1 -- $2))
+at.relto = $(foreach _at.tmp,$2,$(call _at.relto,$1,$(_at.tmp)))
+
+at.path = $(foreach _at.tmp,$1,$(call _at.path,$(_at.tmp)))
+at.out2src = $(foreach _at.tmp,$1,$(call _at.out2src,$(_at.tmp)))
+at.addprefix = $(foreach _at.tmp,$2,$(call _at.addprefix,$1,$(_at.tmp)))
define at.nl
endef
+# External configuration ###############################################
at.Makefile ?= Makefile
-_at.rest = $(wordlist 2,$(words $1),$1)
-_at.reverse = $(if $1,$(call _at.reverse,$(_at.rest))) $(firstword $1)
-
-at.dirlocal += at.subdirs
-at.dirlocal += at.depdirs
-
-_at.outdirs ?=
-_at.included_makefiles ?=
-
+# Include modules ######################################################
include $(sort $(wildcard $(topsrcdir)/build-aux/Makefile.once.head/*.mk))
+_at.tmp_targets =
+_at.tmp_subdirs =
+_at.VARIABLES =
+_at.VARIABLES := $(.VARIABLES)
endif # _at.NO_ONCE
# This bit gets evaluated for each Makefile
-## Set outdir and srcdir (assumes that topoutdir and topsrcdir are
-## already set)
-outdir := $(call at.path,$(dir $(lastword $(filter-out %.mk,$(MAKEFILE_LIST)))))
-srcdir := $(call at.path,$(topsrcdir)/$(call _at.relto,$(topoutdir),$(outdir)))
+outdir := $(call _at.path,$(dir $(lastword $(_at.MAKEFILE_LIST))))
+ifeq ($(call _at.is_subdir,$(topoutdir),$(outdir)),)
+$(error Autothing: not a subdirectory of topoutdir=$(topoutdir): $(outdir))
+endif
-_at.included_makefiles := $(_at.included_makefiles) $(call at.path,$(outdir)/$(at.Makefile))
+# Don't use at.out2src because we *know* that $(outdir) is inside $(topoutdir),
+# and has already had $(_at.path) called on it.
+srcdir := $(call _at.path,$(topsrcdir)/$(outdir))
+ifeq ($(call _at.is_subdir,$(topsrcdir),$(srcdir)),)
+$(error Autothing: not a subdirectory of topsrcdir=$(topsrcdir): $(srcdir))
+endif
-$(foreach v,$(at.dirlocal),$(eval $v=))
+at.subdirs =
+at.targets =
include $(sort $(wildcard $(topsrcdir)/build-aux/Makefile.each.head/*.mk))
diff --git a/build-aux/Makefile.once.head/00-write-ifchanged.mk b/build-aux/Makefile.once.head/00-write-ifchanged.mk
deleted file mode 100644
index 79ef1c4..0000000
--- a/build-aux/Makefile.once.head/00-write-ifchanged.mk
+++ /dev/null
@@ -1 +0,0 @@
-WRITE_IFCHANGED = $(topsrcdir)/build-aux/write-ifchanged
diff --git a/build-aux/Makefile.once.head/00-dist.mk b/build-aux/Makefile.once.head/10-dist.mk
index 4326cde..0e13ea2 100644
--- a/build-aux/Makefile.once.head/00-dist.mk
+++ b/build-aux/Makefile.once.head/10-dist.mk
@@ -13,6 +13,8 @@
# 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 = Make distribution tarballs
+
# Developer configuration
dist.exts ?= .tar.gz
@@ -20,10 +22,10 @@ dist.pkgname ?= $(firstword $(PACKAGE_TARNAME) $(PACKAGE) $(PACKAGE_NAME))
dist.version ?= $(firstword $(PACKAGE_VERSION) $(VERSION))
ifeq ($(dist.pkgname),)
-$(error dist.pkgname must be set)
+$(error Autothing module: dist: dist.pkgname must be set)
endif
ifeq ($(dist.version),)
-$(error dist.version must be set)
+$(error Autothing module: dist: dist.version must be set)
endif
# User configuration
@@ -38,7 +40,3 @@ TAR ?= tar
GZIPFLAGS ?= $(GZIP_ENV)
GZIP_ENV ?= --best
-
-# Implementation
-
-at.phony += dist
diff --git a/build-aux/Makefile.once.head/10-std.mk b/build-aux/Makefile.once.head/10-files.mk
index 3e058ec..56e06ac 100644
--- a/build-aux/Makefile.once.head/10-std.mk
+++ b/build-aux/Makefile.once.head/10-files.mk
@@ -13,27 +13,25 @@
# 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/>.
-# Declare the default target
-all: build
-.PHONY: all noop
+mod.files.description = Keeping track of groups of files
+mod.files.depends += nested
+
+files.groups ?= all
+files.default ?= all
+files.vcsclean ?= files.vcsclean
+files.generate ?= files.generate
+
+.DEFAULT_GOAL = $(files.default_group)
# Standard creative PHONY targets
-at.phony += build install installdirs
+nested.targets += $(foreach g,$(files.groups), $g install-$g install-$gdirs)
# Standard destructive PHONY targets
-at.phony += uninstall mostlyclean clean distclean maintainer-clean
-
-at.dirlocal += std.src_files
-at.dirlocal += std.gen_files
-at.dirlocal += std.cfg_files
-at.dirlocal += std.out_files
-at.dirlocal += std.sys_files
-at.dirlocal += std.clean_files
-at.dirlocal += std.slow_files
+nested.targets += uninstall mostlyclean clean distclean maintainer-clean
# User configuration
DESTDIR ?=
RM ?= rm -f
-RMDIR_P ?= rmdir -p
+RMDIR_P ?= rmdir -p --ignore-fail-on-non-empty
TRUE ?= true
diff --git a/build-aux/Makefile.once.head/00-gnuconf.mk b/build-aux/Makefile.once.head/10-gnuconf.mk
index 83cb110..c07cfb5 100644
--- a/build-aux/Makefile.once.head/00-gnuconf.mk
+++ b/build-aux/Makefile.once.head/10-gnuconf.mk
@@ -14,11 +14,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file is based on §7.2 "Makefile Conventions" of the release of
-# the GNU Coding Standards dated April 13, 2016.
+# the GNU Coding Standards dated July 25, 2016.
+
+mod.gnuconf.description = GNU standard configuration variables
gnuconf.pkgname ?= $(firstword $(PACKAGE_TARNAME) $(PACKAGE) $(PACKAGE_NAME))
ifeq ($(gnuconf.pkgname),)
-$(error gnuconf.pkgname must be set)
+$(error Autothing module: gnuconf: gnuconf.pkgname must be set)
endif
# 7.2.2: Utilities in Makefiles
@@ -54,43 +56,69 @@ TOUCH ?= touch
TR ?= tr
TRUE ?= true
-# These must be user-configurable
+# 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
-CCFLAGS ?= $(CFLAGS)
+CFLAGS ?= # CFLAGS instead of CCFLAGS
FLEX ?= flex
FLEXFLAGS ?=
INSTALL ?= install
-#INSTALLFLAGS ?=
+# There is no INSTALLFLAGS[0]
LD ?= ld
LDFLAGS ?=
-LDCONFIG ?= ldconfig #TODO
+LDCONFIG ?= ldconfig # TODO[1]
LDCONFIGFLAGS ?=
LEX ?= lex
-LEXFLAGS ?= $(LFLAGS)
+LFLAGS ?= # LFLAGS instead of LEXFLAGS
#MAKE
MAKEINFO ?= makeinfo
MAKEINFOFLAGS ?=
-RANLIB ?= ranlib #TODO
+RANLIB ?= ranlib # TODO[1]
RANLIBFLAGS ?=
TEXI2DVI ?= texi2dvi
TEXI2DVIFLAGS ?=
YACC ?= yacc
-YACCFLAGS ?= $(YFLAGS)
+YFLAGS ?= # YFLAGS instead of YACCFLAGS
-CFLAGS ?=
-LFLAGS ?=
-YFLAGS ?=
-
-LN_S ?= ln -s #TODO
+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
# ----------------------------------------
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 0000000..c8410d4
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-lt.mk
@@ -0,0 +1,12 @@
+mod.lt.description = Easy handling of libtool dependencies
+mod.lt.deps += files
+
+_lt.dups = $(sort $(foreach l,$1,$(if $(filter-out 1,$(words $(filter $l,$1))),$l)))
+_lt.patsubst-all = $(if $1,$(call _sd.patsubst-all,$(wordlist 2,$(words $1),$1),$2,$(patsubst $(firstword $1),$2,$3)),$3)
+_lt.unLIBPATTERNS = $(foreach _lt.tmp,$1,$(if $(filter $(.LIBPATTERNS),$(_lt.tmp)),$(call _lt.patsubst-all,$(.LIBPATTERNS),-l%,$(_lt.tmp)),$(_lt.tmp)))
+
+# The semantics for the de-dup bit are a bit weird. My head hurts thinking
+# about them. TODO: clarify/simplify/something
+lt.rpath = $(dir $(patsubst $(DESTDIR)%,%,$(filter %/$(@F),$(files.sys))))
+_lt.link_files = $(filter %.o %.lo %.la -l%,$(call _lt.unLIBPATTERNS$,$^))
+lt.link_files = $(filter-out $(call _lt.dups,$(_lt.link_files)),$(_lt.link_files))
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 0000000..af9fdf7
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-nested.mk
@@ -0,0 +1,18 @@
+# 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
+
+nested.targets ?=
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 0000000..7917201
--- /dev/null
+++ b/build-aux/Makefile.once.head/10-write-ifchanged.mk
@@ -0,0 +1,3 @@
+mod.write-ifchanged.description = build-aux/write-ifchanged helper script
+
+WRITE_IFCHANGED ?= $(topsrcdir)/build-aux/write-ifchanged
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 0000000..3bf6398
--- /dev/null
+++ b/build-aux/Makefile.once.head/zz-mod.mk
@@ -0,0 +1,24 @@
+# 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 = Print information about Autothing modules
+
+_mod.target = at-mod-info
+_mod.modules := $(sort $(patsubst %.mk,%,$(filter %.mk,$(subst -, ,$(notdir $(wildcard $(topsrcdir)/build-aux/Makefile.*/??-*.mk))))))
+_mod.quote = '$(subst ','\'',$1)'
+
+_mod.vars = $(filter $(addsuffix .%,$(_mod.modules)),$(.VARIABLES))
+_mod.once := $(_mod.vars)
+_mod.each :=
diff --git a/build-aux/Makefile.once.tail/00-dist.mk b/build-aux/Makefile.once.tail/00-dist.mk
index b8b7733..6c6aaed 100644
--- a/build-aux/Makefile.once.tail/00-dist.mk
+++ b/build-aux/Makefile.once.tail/00-dist.mk
@@ -16,12 +16,12 @@
_dist.copyfile = $(MKDIR_P) $(dir $2) && $(CP) -T $1 $2
_dist.addfile = $(call _dist.copyfile,$3,$2/$(call at.relto,$1,$3))
$(topoutdir)/$(dist.pkgname)-$(dist.version): $(foreach v,$(filter std.src_files/% std.gen_files/%,$(.VARIABLES)),$($v))
- $(RM) -r $@ $(@D)/tmp.$(@F)
- $(MKDIR) $(@D)/tmp.$(@F)
- $(foreach f,$^,$(call _dist.addfile,$(topsrcdir),$(@D)/tmp.$(@F),$f)$(at.nl))
- $(MV) $(@D)/tmp.$(@F) $@ || $(RM) -r $(@D)/tmp.$(@F)
+ $(RM) -r $@ $(@D)/.tmp.$(@F)
+ $(MKDIR) $(@D)/.tmp.$(@F)
+ $(foreach f,$^,$(call _dist.addfile,$(topsrcdir),$(@D)/.tmp.$(@F),$f)$(at.nl))
+ $(MV) $(@D)/.tmp.$(@F) $@ || $(RM) -r $(@D)/.tmp.$(@F)
-$(topoutdir)/$(dist.pkgname)-$(dist.version).tar: $(topoutdir)/$(dist.pkgname)-$(dist.version)
+$(topoutdir)/$(dist.pkgname)-$(dist.version).tar: %.tar: %
$(TAR) cf $@ -C $(<D) $(<F)
-$(topoutdir)/$(dist.pkgname)-$(dist.version).tar.gz: $(topoutdir)/$(dist.pkgname)-$(dist.version).tar
+$(topoutdir)/$(dist.pkgname)-$(dist.version).tar.gz: %.gz: %
$(GZIP) $(GZIPFLAGS) < $< > $@
diff --git a/build-aux/Makefile.once.tail/00-mod.mk b/build-aux/Makefile.once.tail/00-mod.mk
new file mode 100644
index 0000000..68350f0
--- /dev/null
+++ b/build-aux/Makefile.once.tail/00-mod.mk
@@ -0,0 +1,32 @@
+# 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.target):
+ @printf 'Autothing modules used in this project:\n'
+ @printf ' - %s\n' $(foreach _mod.tmp,$(_mod.modules),$(call _mod.quote,$(_mod.tmp)))
+$(addprefix $(_mod.target)/,$(_mod.modules)): $(_mod.target)/%:
+ @printf 'Module : %s ' $(call _mod.quote,$*)
+ @$(if $(at.mod.$*.description),printf ' - %s' $(call _mod.quote,mod.$*.description))
+ @echo
+ @echo Depends on : $(mod.$*.depends)
+ @echo User configuration:
+ @egrep '^\s*[^:#]+\s*\?=' $(topsrcdir)/build-aux/Makefile.once.head/??-$*.mk 2>/dev/null | sed 's|^\s*||;s|?=|:' | grep -v -e ^'_' -e ^'$*' | column -t -s: |sed 's|^| |'
+ @echo Developer global inputs:
+ @egrep '^\s*[^:#]+\s*\?=' $(topsrcdir)/build-aux/Makefile.once.head/??-$*.mk 2>/dev/null | sed 's|^\s*||;s|?=|:' | grep ^'$*\.' | column -t -s: |sed 's|^| |'
+ @echo Developer per-directory inputs:
+ @egrep '^\s*[^:#]+\s*\?=' $(topsrcdir)/build-aux/Makefile.each.head/??-$*.mk 2>/dev/null | sed 's|^\s*||;s|?=|:' | grep ^'$*\.' | column -t -s: |sed 's|^| |'
+ @echo Developer outputs:
+ @egrep '^\s*[^:#]+\s*(|:|::)=' $(topsrcdir)/build-aux/Makefile.once.head/??-$*.mk 2>/dev/null | sed 's|^\s*||;s|?=|:' | grep ^'$*\.' | column -t -s: |sed 's|^| |'
+.PHONY: $(addprefix mod/,$(_mod.modules))
diff --git a/build-aux/Makefile.once.tail/00-noop.mk b/build-aux/Makefile.once.tail/00-noop.mk
new file mode 100644
index 0000000..bac2ec1
--- /dev/null
+++ b/build-aux/Makefile.once.tail/00-noop.mk
@@ -0,0 +1,2 @@
+noop:
+.PHONY: noop
diff --git a/build-aux/Makefile.tail.mk b/build-aux/Makefile.tail.mk
index a8b3d89..136e483 100644
--- a/build-aux/Makefile.tail.mk
+++ b/build-aux/Makefile.tail.mk
@@ -17,36 +17,26 @@
include $(call _at.reverse,$(sort $(wildcard $(topsrcdir)/build-aux/Makefile.each.tail/*.mk)))
-# Move all of the dirlocal variables to their namespaced version
-$(foreach v,$(at.dirlocal),$(eval $v/$(outdir) := $$($v)))
-$(foreach v,$(at.dirlocal),$(eval undefine $v))
-
-# Adjust subdirs and depdirs to be relative to $(outdir)
-at.subdirs/$(outdir) := $(sort $(patsubst %/,%,$(call at.addprefix,$(outdir)/,$(at.subdirs/$(outdir)))))
-at.depdirs/$(outdir) := $(sort $(patsubst %/,%,$(call at.addprefix,$(outdir)/,$(at.depdirs/$(outdir)))))
-
-# Remember that this is a directory that we've visited
-_at.outdirs := $(_at.outdirs) $(outdir)
-
-# Generic phony target declarations:
-# mark them phony
-.PHONY: $(addprefix $(outdir)/,$(at.phony))
-# have them depend on subdirs
-$(foreach t,$(at.phony),$(eval $(outdir)/$t: $(addsuffix /$t,$(at.subdirs/$(outdir)))))
-
-# Include Makefiles from other directories
+_at.tmp_targets := $(at.targets)
+_at.tmp_subdirs := $(call at.addprefix,$(outdir),$(at.subdirs))
+
+# Clean the environment
+$(foreach _at.tmp_variable,$(filter-out _at.tmp_variable $(_at.VARIABLES),$(.VARIABLES)), \
+ $(foreach _at.tmp_target,$(_at.tmp_targets), \
+ $(if $(filter recursive,$(flavor $(_at.tmp_variable))), \
+ $(eval $(_at.tmp_target): private $(_at.tmp_variable) = $(subst $(at.nl),$$(at.nl),$(value $(_at.tmp_variable)))), \
+ $(eval $(_at.tmp_target): private $(_at.tmp_variable) := $$($(_at.tmp_variable))))) \
+ $(eval undefine $(_at.tmp_variable)))
+
+# Recurse
$(foreach _at.NO_ONCE,y,\
- $(foreach makefile,$(call at.path,$(addsuffix /$(at.Makefile),$(at.subdirs/$(outdir)) $(at.depdirs/$(outdir)))),\
- $(eval include $(filter-out $(_at.included_makefiles),$(makefile)))))
+ $(foreach _at.tmp,$(call at.path,$(addsuffix /$(at.Makefile),$(_at.tmp_subdirs))),\
+ $(if $(filter-out $(_at.MAKEFILE_LIST),$(abspath $(_at.tmp))),\
+ $(eval include $(_at.tmp)))))
# This bit only gets evaluated once, after all of the other Makefiles are read
ifeq ($(origin _at.NO_ONCE),undefined)
-outdir = /bogus
-srcdir = /bogus
-
-$(foreach v,$(at.dirlocal),$(eval $v=))
-
include $(call _at.reverse,$(sort $(wildcard $(topsrcdir)/build-aux/Makefile.once.tail/*.mk)))
endif # _at.NO_ONCE
diff --git a/build-aux/no-builtin-variables.mk b/build-aux/no-builtin-variables.mk
deleted file mode 100644
index c3aef58..0000000
--- a/build-aux/no-builtin-variables.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-MAKEFLAGS += --no-builtin-variables
-
-# This version is more correct, but is slower:
-# $(foreach v,$(shell bash -c 'comm -23 <(env -i $(MAKE) -f - <<<"\$$(info \$$(.VARIABLES))all:"|sed "s/ /\n/g"|sort) <(env -i $(MAKE) -R -f - <<<"\$$(info \$$(.VARIABLES))all:"|sed "s/ /\n/g"|sort)'),
-# $(if $(filter default,$(origin $v)),$(eval undefine $v)))
-
-_default_variables = $(foreach v,$(.VARIABLES),$(if $(filter default,$(origin $v)),$v))
-$(foreach v,$(filter-out .% MAKE% SUFFIXES,$(_default_variables))\
- $(filter .LIBPATTERNS MAKEINFO,$(_default_variables)),\
- $(eval undefine $v))
-undefine _default_variables
-
-# Because Make uses .LIBPATTERNS internally, it should always be
-# defined in case --warn-undefined-variables
-.LIBPATTERNS ?=