1# Maintainer makefile rules for Automake.
2#
3# Copyright (C) 1995-2021 Free Software Foundation, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2, or (at your option)
8# any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18# Avoid CDPATH issues.
19unexport CDPATH
20
21# Program to use to fetch files from the Net.
22WGET = wget
23
24# --------------------------------------------------------- #
25#  Automatic generation of the ChangeLog from git history.  #
26# --------------------------------------------------------- #
27
28gitlog_to_changelog_command = $(PERL) $(srcdir)/lib/gitlog-to-changelog
29gitlog_to_changelog_fixes = $(srcdir)/.git-log-fix
30gitlog_to_changelog_options = --amend=$(gitlog_to_changelog_fixes) \
31                              --since='2011-12-28 00:00:00' \
32                              --no-cluster --format '%s%n%n%b'
33
34EXTRA_DIST += lib/gitlog-to-changelog
35EXTRA_DIST += $(gitlog_to_changelog_fixes)
36
37# When executed from a git checkout, generate the ChangeLog from the git
38# history.  When executed from an extracted distribution tarball, just
39# copy the distributed ChangeLog in the build directory (and if this
40# fails, or if no distributed ChangeLog file is present, complain and
41# give an error).
42#
43# The ChangeLog should be regenerated unconditionally when working from
44# checked-out sources; otherwise, if we're working from a distribution
45# tarball, we expect the ChangeLog to be distributed, so check that it
46# is indeed present in the source directory.
47ChangeLog:
48	$(AM_V_GEN)set -e; set -u; \
49	if test -d $(srcdir)/.git; then \
50	  rm -f $@-t \
51	    && $(gitlog_to_changelog_command) \
52	       $(gitlog_to_changelog_options) >$@-t \
53	    && chmod a-w $@-t \
54	    && mv -f $@-t $@ \
55	    || exit 1; \
56	elif test ! -f $(srcdir)/$@; then \
57	  echo "Source tree is not a git checkout, and no pre-existent" \
58	       "$@ file has been found there" >&2; \
59	  exit 1; \
60	fi
61.PHONY: ChangeLog
62
63
64# --------------------------- #
65#  Perl coverage statistics.  #
66# --------------------------- #
67
68PERL_COVERAGE_DB = $(abs_top_builddir)/cover_db
69PERL_COVERAGE_FLAGS = -MDevel::Cover=-db,$(PERL_COVERAGE_DB),-silent,on,-summary,off
70PERL_COVER = cover
71
72check-coverage-run recheck-coverage-run: %-coverage-run: all
73	$(MKDIR_P) $(PERL_COVERAGE_DB)
74	PERL5OPT="$$PERL5OPT $(PERL_COVERAGE_FLAGS)"; export PERL5OPT; \
75	WANT_NO_THREADS=yes; export WANT_NO_THREADS; unset AUTOMAKE_JOBS; \
76	$(MAKE) $*
77
78check-coverage-report:
79	@if test ! -d "$(PERL_COVERAGE_DB)"; then \
80	  echo "No coverage database found in '$(PERL_COVERAGE_DB)'." >&2; \
81	  echo "Please run \"make check-coverage\" first" >&2; \
82	  exit 1; \
83	fi
84	$(PERL_COVER) $(PERL_COVER_FLAGS) "$(PERL_COVERAGE_DB)"
85
86# We don't use direct dependencies here because we'd like to be able
87# to invoke the report even after interrupted check-coverage.
88check-coverage: check-coverage-run
89	$(MAKE) check-coverage-report
90
91recheck-coverage: recheck-coverage-run
92	$(MAKE) check-coverage-report
93
94clean-coverage:
95	rm -rf "$(PERL_COVERAGE_DB)"
96clean-local: clean-coverage
97
98.PHONY: check-coverage recheck-coverage check-coverage-run \
99	recheck-coverage-run check-coverage-report clean-coverage
100
101
102# ---------------------------------------------------- #
103#  Tagging and/or uploading stable and beta releases.  #
104# ---------------------------------------------------- #
105
106GIT = git
107
108EXTRA_DIST += lib/gnupload
109
110# First component of a version number (mandatory).
111rx-0 = ^[1-9][0-9]*
112# Later components of a version number (optional).
113rx-1 = \.[0-9][0-9]*
114# Used in recipes to decide which kind of release we are.
115stable_major_version_rx = $(rx-0)\.0$$
116stable_minor_version_rx = $(rx-0)$(rx-1)$$
117stable_micro_version_rx = $(rx-0)$(rx-1)$(rx-1)$$
118beta_version_rx = $(rx-0)($(rx-1)){1,2}[bdfhjlnprtvxz]$$
119alpha_version_rx  = $(rx-0)($(rx-1)){1,2}[acegikmoqsuwy]$$
120match_version = echo "$(VERSION)" | $(EGREP) >/dev/null
121
122# Check that we don't have uncommitted or unstaged changes.
123# TODO: Maybe the git suite already offers a shortcut to verify if the
124# TODO: working directory is "clean" or not?  If yes, use that instead
125# TODO: of duplicating the logic here.
126git_must_have_clean_workdir = \
127  $(GIT) rev-parse --verify HEAD >/dev/null \
128    && $(GIT) update-index -q --refresh \
129    && $(GIT) diff-files --quiet \
130    && $(GIT) diff-index --quiet --cached HEAD \
131    || { echo "$@: you have uncommitted or unstaged changes" >&2; exit 1; }
132
133determine_release_type = \
134  if $(match_version) '$(stable_major_version_rx)'; then \
135    release_type='Major release'; \
136    announcement_type='major release'; \
137    dest=ftp; \
138  elif $(match_version) '$(stable_minor_version_rx)'; then \
139    release_type='Minor release'; \
140    announcement_type='minor release'; \
141    dest=ftp; \
142  elif $(match_version) '$(stable_micro_version_rx)'; then \
143    release_type='Micro release'; \
144    announcement_type='maintenance release'; \
145    dest=ftp; \
146  elif $(match_version) '$(beta_version_rx)'; then \
147    release_type='Beta release'; \
148    announcement_type='test release'; \
149    dest=alpha; \
150  elif $(match_version) '$(alpha_version_rx)'; then \
151    echo "$@: improper version '$(VERSION)' for a release" >&2; \
152    if test -n '$(strip $(DEVEL_SNAPSHOT))'; then \
153      echo "$@: continuing anyway since DEVEL_SNAPSHOT is set" >&2; \
154      release_type='Development snapshot'; \
155      announcement_type='development snapshot'; \
156      dest=alpha; \
157    else \
158      exit 1; \
159    fi; \
160  else \
161    echo "$@: invalid version number '$(VERSION)'" >&2; \
162    exit 1; \
163  fi
164
165# Help the debugging of $(determine_release_type) and related code.
166print-release-type:
167	@$(determine_release_type); \
168	 echo "$$release_type $(VERSION);" \
169	      "it will be announced as a \"$$announcement_type\""
170
171git-tag-release: maintainer-check
172	@set -e -u; \
173	case '$(AM_TAG_DRYRUN)' in \
174	  ""|[nN]|[nN]o|NO) run="";; \
175	  *) run="echo Running:";; \
176	esac; \
177	$(git_must_have_clean_workdir); \
178	$$run $(GIT) tag -s "v$(VERSION)" -m "$(PACKAGE) $(VERSION)"
179
180git-upload-release:
181	@# Check this is a version we can cut a release (either test
182	@# or stable) from.
183	@$(determine_release_type)
184	@# The repository must be clean.
185	@$(git_must_have_clean_workdir)
186	@# Check that we are releasing from a valid tag.
187	@tag=`$(GIT) describe` \
188	  && case $$tag in "v$(VERSION)") true;; *) false;; esac \
189	  || { echo "$@: you can only create a release from a tagged" \
190	            "version" >&2; \
191	       exit 1; }
192	@# Build the distribution tarball(s).
193	$(MAKE) dist
194	@# Upload it to the correct FTP repository.
195	@$(determine_release_type) \
196	  && dest=$$dest.gnu.org:automake \
197	  && echo "Will upload to $$dest: $(DIST_ARCHIVES)" \
198	  && $(srcdir)/lib/gnupload $(GNUPLOADFLAGS) --to $$dest \
199	                            $(DIST_ARCHIVES)
200
201.PHONY: print-release-type git-upload-release git-tag-release
202
203
204# ------------------------------------------------------------------ #
205#  Explore differences of autogenerated files in different commits.  #
206# ------------------------------------------------------------------ #
207
208# Visually comparing differences between the Makefile.in files in
209# automake's own build system as generated in two different branches
210# might help to catch bugs and blunders.  This has already happened a
211# few times in the past, when we used to version-control Makefile.in.
212autodiffs:
213	@set -u; \
214	 NEW_COMMIT=$${NEW_COMMIT-"HEAD"}; \
215	 OLD_COMMIT=$${OLD_COMMIT-"HEAD~1"}; \
216	 am_gitdir='$(abs_top_srcdir)/.git'; \
217	 get_autofiles_from_rev () \
218	 { \
219	     rev=$$1 dir=$$2 \
220	       && echo "$@: will get files from revision $$rev" \
221	       && $(GIT) clone -q --depth 1 "$$am_gitdir" tmp \
222	       && cd tmp \
223	       && $(GIT) checkout -q "$$rev" \
224	       && echo "$@: bootstrapping $$rev" \
225	       && $(SHELL) ./bootstrap \
226	       && echo "$@: copying files from $$rev" \
227	       && makefile_ins=`find . -name Makefile.in` \
228	       && (tar cf - configure aclocal.m4 $$makefile_ins) | \
229	          (cd .. && cd "$$dir" && tar xf -) \
230	       && cd .. \
231	       && rm -rf tmp; \
232	 }; \
233	 outdir=$@.dir \
234	   && : Before proceeding, ensure the specified revisions truly exist. \
235	   && $(GIT) --git-dir="$$am_gitdir" describe $$OLD_COMMIT >/dev/null \
236	   && $(GIT) --git-dir="$$am_gitdir" describe $$NEW_COMMIT >/dev/null \
237	   && rm -rf $$outdir \
238	   && mkdir $$outdir \
239	   && cd $$outdir \
240	   && mkdir new old \
241	   && get_autofiles_from_rev $$OLD_COMMIT old \
242	   && get_autofiles_from_rev $$NEW_COMMIT new \
243	   && exit 0
244
245# With lots of eye candy; we like our developers pampered and spoiled :-)
246compare-autodiffs: autodiffs
247	@set -u; \
248	: $${COLORDIFF=colordiff} $${DIFF=diff}; \
249	dir=autodiffs.dir; \
250	if test ! -d "$$dir"; then \
251	  echo "$@: $$dir: Not a directory" >&2; \
252	  exit 1; \
253	fi; \
254	mydiff=false mypager=false; \
255	if test -t 1; then \
256	  if ($$COLORDIFF -r . .) </dev/null >/dev/null 2>&1; then \
257	    mydiff=$$COLORDIFF; \
258	    mypager="less -R"; \
259	  else \
260	    mypager=less; \
261	  fi; \
262	else \
263	  mypager=cat; \
264	fi; \
265	if test "$$mydiff" = false; then \
266	  if ($$DIFF -r -u . .); then \
267	    mydiff=$$DIFF; \
268	  else \
269	    echo "$@: no good-enough diff program specified" >&2; \
270	    exit 1; \
271	  fi; \
272	fi; \
273	st=0; $$mydiff -r -u $$dir/old $$dir/new | $$mypager || st=$$?; \
274	rm -rf $$dir; \
275	exit $$st
276.PHONY: autodiffs compare-autodiffs
277
278# ---------------------------------------------- #
279#  Help writing the announcement for a release.  #
280# ---------------------------------------------- #
281
282PACKAGE_MAILINGLIST = automake@gnu.org
283
284announcement: DEVEL_SNAPSHOT = yes
285announcement: NEWS
286	$(AM_V_GEN): \
287	  && rm -f $@ $@-t \
288	  && $(determine_release_type) \
289	  && ftp_base="https://$$dest.gnu.org/gnu/$(PACKAGE)" \
290	  && X () { printf '%s\n' "$$*" >> $@-t; } \
291	  && X "We are pleased to announce the $(PACKAGE_NAME) $(VERSION)" \
292	       "$$announcement_type." \
293	  && X \
294	  && X "**TODO** Brief description of the release here." \
295	  && X \
296	  && X "**TODO** This description can span multiple paragraphs." \
297	  && X \
298	  && X "See below for the detailed list of changes since the" \
299	  && X "previous version, as summarized by the NEWS file." \
300	  && X \
301	  && X "Download here:" \
302	  && X \
303	  && X "  $$ftp_base/$(PACKAGE)-$(VERSION).tar.gz" \
304	  && X "  $$ftp_base/$(PACKAGE)-$(VERSION).tar.xz" \
305	  && X \
306	  && X "Please report bugs and problems to" \
307	       "<$(PACKAGE_BUGREPORT)>," \
308	  && X "and send general comments and feedback to" \
309	       "<$(PACKAGE_MAILINGLIST)>." \
310	  && X \
311	  && X "Thanks to everyone who has reported problems, contributed" \
312	  && X "patches, and helped testing Automake!" \
313	  && X \
314	  && X "-*-*-*-" \
315	  && X \
316	  && $(AWK) '\
317	        ($$0 ~ /^New in .*:/) { wait_for_end=1; } \
318		(/^~~~/ && wait_for_end) { print; exit(0) } \
319		{ print } \
320	     ' <$(srcdir)/NEWS >> $@-t \
321	  && mv -f $@-t $@
322.PHONY: announcement
323CLEANFILES += announcement
324
325# --------------------------------------------------------------------- #
326#  Synchronize third-party files that are committed in our repository.  #
327# --------------------------------------------------------------------- #
328
329# Git repositories on Savannah.
330git-sv-host = git.savannah.gnu.org
331
332# Some repositories we sync files from.
333SV_GIT_CF = 'https://$(git-sv-host)/gitweb/?p=config.git;a=blob_plain;hb=HEAD;f='
334SV_GIT_GL = 'https://$(git-sv-host)/gitweb/?p=gnulib.git;a=blob_plain;hb=HEAD;f='
335
336# Files that we fetch and which we compare against.
337# Note that the 'lib/COPYING' file must still be synced by hand.
338FETCHFILES = \
339  $(SV_GIT_CF)config.guess \
340  $(SV_GIT_CF)config.sub \
341  $(SV_GIT_GL)build-aux/texinfo.tex \
342  $(SV_GIT_GL)build-aux/gendocs.sh \
343  $(SV_GIT_GL)build-aux/gitlog-to-changelog \
344  $(SV_GIT_GL)build-aux/gnupload \
345  $(SV_GIT_GL)build-aux/update-copyright \
346  $(SV_GIT_GL)doc/gendocs_template \
347  $(SV_GIT_GL)doc/INSTALL
348
349# Fetch the latest versions of few scripts and files we care about.
350# A retrieval failure or a copying failure usually mean serious problems,
351# so we'll just bail out if 'wget' or 'cp' fail.
352fetch:
353	$(AM_V_at)rm -rf Fetchdir
354	$(AM_V_at)mkdir Fetchdir
355	$(AM_V_GEN)set -e; \
356	if $(AM_V_P); then wget_opts=; else wget_opts=-nv; fi; \
357	for url in $(FETCHFILES); do \
358	   file=`printf '%s\n' "$$url" | sed 's|^.*/||; s|^.*=||'`; \
359	   $(WGET) $$wget_opts "$$url" -O Fetchdir/$$file || exit 1; \
360	   if cmp Fetchdir/$$file $(srcdir)/lib/$$file >/dev/null; then \
361	     : Nothing to do; \
362	   else \
363	     echo "$@: updating file $$file"; \
364	     cp Fetchdir/$$file $(srcdir)/lib/$$file || exit 1; \
365	   fi; \
366	done
367	$(AM_V_at)rm -rf Fetchdir
368.PHONY: fetch
369
370# ---------------------------------------------------------------------- #
371#  Generate and upload manuals in several formats, for the GNU website.  #
372# ---------------------------------------------------------------------- #
373
374web_manual_dir = doc/web-manual
375
376RSYNC = rsync
377CVS = cvs
378CVSU = cvsu
379CVS_USER = $${USER}
380WEBCVS_ROOT = cvs.savannah.gnu.org:/web
381CVS_RSH = ssh
382export CVS_RSH
383
384.PHONY: web-manual web-manual-update
385web-manual web-manual-update: t = $@.dir
386
387# Build manual in several formats.  Note to the recipe:
388# 1. The symlinking of automake.texi into the temporary directory is
389#    required to pacify extra checks from gendocs.sh.
390# 2. The redirection to /dev/null before the invocation of gendocs.sh
391#    is done to better respect silent rules.
392web-manual:
393	$(AM_V_at)rm -rf $(web_manual_dir) $t
394	$(AM_V_at)mkdir $t
395	$(AM_V_at)$(LN_S) '$(abs_srcdir)/doc/$(PACKAGE).texi' '$t/'
396	$(AM_V_GEN)cd $t \
397	  && GENDOCS_TEMPLATE_DIR='$(abs_srcdir)/lib' \
398	  && export GENDOCS_TEMPLATE_DIR \
399	  && if $(AM_V_P); then :; else exec >/dev/null 2>&1; fi \
400	  && $(SHELL) '$(abs_srcdir)/lib/gendocs.sh' \
401	     -I '$(abs_srcdir)/doc' --email $(PACKAGE_BUGREPORT) \
402	     $(PACKAGE) '$(PACKAGE_NAME)'
403	$(AM_V_at)mkdir $(web_manual_dir)
404	$(AM_V_at)mv -f $t/manual/* $(web_manual_dir)
405	$(AM_V_at)rm -rf $t
406	@! $(AM_V_P) || ls -l $(web_manual_dir)
407
408# Upload manual to www.gnu.org, using CVS (sigh!)
409web-manual-update:
410	$(AM_V_at)$(determine_release_type); \
411	case $$release_type in \
412	  [Mm]ajor\ release|[Mm]inor\ release|[Mm]icro\ release);; \
413	  *) echo "Cannot upload manuals from a \"$$release_type\"" >&2; \
414	     exit 1;; \
415	esac
416	$(AM_V_at)test -f $(web_manual_dir)/$(PACKAGE).html || { \
417	  echo 'You have to run "$(MAKE) web-manual" before' \
418	       'invoking "$(MAKE) $@"' >&2; \
419	  exit 1; \
420	}
421	$(AM_V_at)rm -rf $t
422	$(AM_V_at)mkdir $t
423	$(AM_V_at)cd $t \
424	  && $(CVS) -z3 -d :ext:$(CVS_USER)@$(WEBCVS_ROOT)/$(PACKAGE) \
425	            co $(PACKAGE)
426	@# According to the rsync manpage, "a trailing slash on the
427	@# source [...] avoids creating an additional directory
428	@# level at the destination".  So the trailing '/' after
429	@# '$(web_manual_dir)' below is intended.
430	$(AM_V_at)$(RSYNC) -avP $(web_manual_dir)/ $t/$(PACKAGE)/manual
431	$(AM_V_GEN): \
432	  && cd $t/$(PACKAGE)/manual \
433	  && new_files=`$(CVSU) --types='?'` \
434	  && new_files=`echo "$$new_files" | sed s/^..//` \
435	  && { test -z "$$new_files" || $(CVS) add -ko $$new_files; } \
436	  && $(CVS) ci -m $(VERSION)
437	$(AM_V_at)rm -rf $t
438.PHONY: web-manual-update
439
440clean-web-manual:
441	$(AM_V_at)rm -rf $(web_manual_dir)
442.PHONY: clean-web-manual
443clean-local: clean-web-manual
444
445EXTRA_DIST += lib/gendocs.sh lib/gendocs_template
446
447# ------------------------------------------------ #
448#  Update copyright years of all committed files.  #
449# ------------------------------------------------ #
450
451EXTRA_DIST += lib/update-copyright
452
453update_copyright_env = \
454  UPDATE_COPYRIGHT_FORCE=1 \
455  UPDATE_COPYRIGHT_USE_INTERVALS=2
456
457# In addition to the several README files, these as well are
458# not expected to have a copyright notice.
459files_without_copyright = \
460  .autom4te.cfg \
461  .dir-locals.el \
462  .git-log-fix \
463  .gitattributes \
464  .gitignore \
465  INSTALL \
466  COPYING \
467  AUTHORS \
468  THANKS \
469  lib/INSTALL \
470  lib/COPYING
471
472# This script is in the public domain.
473files_without_copyright += lib/mkinstalldirs
474
475# This script has an MIT-style license
476files_without_copyright += lib/install-sh
477
478# The UPDATE_COPYRIGHT_YEAR environment variable is honoured by the
479# 'lib/update-copyright' script.
480.PHONY: update-copyright
481update-copyright:
482	$(AM_V_GEN)set -e; \
483	if test -n "$$UPDATE_COPYRIGHT_YEAR"; then \
484	   current_year=$$UPDATE_COPYRIGHT_YEAR; \
485	else \
486	  current_year=`date +%Y` && test -n "$$current_year" \
487	    || { echo "$@: cannot get current year" >&2; exit 1; }; \
488	fi; \
489	sed -i "/^RELEASE_YEAR=/s/=.*$$/=$$current_year/" \
490	  bootstrap configure.ac; \
491	excluded_re=`( \
492	  for url in $(FETCHFILES); do echo "$$url"; done \
493	    | sed -e 's!^.*/!!' -e 's!^.*=!!' -e 's!^!lib/!' \
494	  && for f in $(files_without_copyright); do echo $$f; done \
495	) | sed -e '$$!s,$$,|,' | tr -d '\012\015'`; \
496	$(GIT) ls-files \
497	  | grep -Ev '(^|/)README$$' \
498	  | grep -Ev '^PLANS(/|$$)' \
499	  | grep -Ev "^($$excluded_re)$$" \
500	  | $(update_copyright_env) xargs $(srcdir)/lib/$@
501
502# -------------------------------------------------------------- #
503#  Run the testsuite with the least supported autoconf version.  #
504# -------------------------------------------------------------- #
505
506gnu-ftp = https://ftp.gnu.org/gnu
507
508# Various shorthands: version, name, package name, tarball name,
509# tarball location, installation directory.
510ac-v = $(required_autoconf_version)
511ac-n = autoconf
512ac-p = $(ac-n)-$(ac-v)
513ac-t = $(ac-p).tar.gz
514ac-l = maintainer/$(ac-t)
515ac-d = maintainer/$(ac-p)
516
517fetch-minimal-autoconf: o = $(ac-l)
518fetch-minimal-autoconf:
519	$(AM_V_at)$(MKDIR_P) $(dir $o)
520	$(AM_V_at)rm -f $o $o-t
521	$(AM_V_GEN)$(WGET) -O $o-t $(gnu-ftp)/$(ac-n)/$(ac-t)
522	$(AM_V_at)chmod a-w $o-t && mv -f $o-t $o && ls -l $o
523.PHONY: fetch-minimal-autoconf
524
525build-minimal-autoconf:
526	$(AM_V_GEN):; \
527	test -f $(ac-l) || { \
528	  echo "$@: tarball $(ac-l) seems missing." >&2; \
529	  echo "$@: have you run '$(MAKE) fetch-minimal-autoconf'?" >&2; \
530	  exit 1; \
531	}; \
532	  set -x \
533	  && $(PERL) $(srcdir)/t/ax/deltree.pl $(ac-d) \
534	  && $(MKDIR_P) $(ac-d) \
535	  && cd $(ac-d) \
536	  && tar xzf '$(CURDIR)/$(ac-l)' \
537	  && mv $(ac-p) src \
538	  && mkdir build \
539	  && cd build \
540	  && env CONFIG_SHELL='$(SHELL)' $(SHELL) ../src/configure \
541	       --prefix='$(CURDIR)/$(ac-d)' CONFIG_SHELL='$(SHELL)' \
542	  && $(MAKE) install
543	$(AM_V_at)echo ' ======' && $(ac-d)/bin/autoconf --version
544.PHONY: build-minimal-autoconf
545
546check-minimal-autoconf:
547	$(AM_V_at)p='$(ac-d)/bin/autoconf'; \
548	  if test ! -f "$$p" || test ! -x "$$p"; then \
549	    echo "$@: program '$$p' seems missing." >&2; \
550	    echo "$@: have you run '$(MAKE) build-minimal-autoconf'?" >&2; \
551	    exit 1; \
552	  fi
553	$(AM_V_GEN): \
554	  && PATH='$(CURDIR)/$(ac-d)/bin$(PATH_SEPARATOR)'$$PATH \
555	  && export PATH \
556	  && AUTOCONF=autoconf \
557	  && AUTOHEADER=autoheader \
558	  && AUTORECONF=autoreconf \
559	  && AUTOM4TE=autom4te \
560	  && AUTOUPDATE=autoupdate \
561	  && export AUTOCONF AUTOHEADER AUTORECONF AUTOM4TE AUTOUPDATE \
562	  && echo === check autoconf version '(must be = $(ac-v))' \
563	  && autoconf --version \
564	  && autoconf --version | sed -e 's/^/ /; s/$$/ /' -e 1q \
565	       | $(FGREP) '$(ac-v)' >/dev/null \
566	  && echo === configure \
567	  && $(srcdir)/configure $(shell ./config.status --config) \
568	  && echo === build and test \
569	  && $(MAKE) check
570.PHONY: check-minimal-autoconf
571
572
573# --------------------------------------------------------------- #
574#  Testing on real-world packages can help us avoid regressions.  #
575# --------------------------------------------------------------- #
576
577#
578# NOTE (from Stefano Lattarini):
579#
580# This section is mostly hacky and ad-hoc, but works for me and
581# on my system.  And while far from clean, it should help catching
582# real regressions on real world packages, which is important.
583# Ideas about how to improve this and make it more generic, portable,
584# clean, etc., are welcome.
585#
586
587# Tiny sample package.
588FEW_PACKAGES += hello
589# Smallish package using recursive make setup.
590FEW_PACKAGES += make
591# Medium-size package using non-recursive make setup.
592FEW_PACKAGES += coreutils
593
594ALL_PACKAGES = \
595  $(FEW_PACKAGES) \
596  autoconf \
597  bison \
598  grep \
599  tar \
600  diffutils \
601  smalltalk
602
603pkg-targets = check dist
604
605# Note: "ttp" stays for "Third Party Package".
606
607ttp-check ttp-check-all: do-clone = $(GIT) clone --verbose
608ttp-check: ttp-packages = $(FEW_PACKAGES)
609ttp-check-all: ttp-packages = $(ALL_PACKAGES)
610
611# Note: some packages depend on pkg-config, and its provided macros.
612ttp-check ttp-check-all: t/pkg-config-macros.log
613	@set -e; \
614	$(setup_autotools_paths); \
615	skip_all_ () \
616	{ \
617	  echo "***" >&2; \
618	  echo "*** $@: WARNING: $$@" >&2; \
619	  echo "*** $@: WARNING: some packages might fail to bootstrap" >&2; \
620	  echo "***" >&2;  \
621	}; \
622	. t/pkg-config-macros.dir/get.sh || exit 1; \
623	mkdir $@.d && cd $@.d || exit 1; \
624	for p in $(ttp-packages); do \
625	    echo; \
626	    echo ========  BEGIN TTP $$p  =========; \
627	    echo; \
628	    set -x; \
629	    $(do-clone) git://$(git-sv-host)/$$p.git || exit 1; \
630	    ( \
631	      cd $$p \
632	        && ls -l \
633	        && if test -f bootstrap; then \
634	             ./bootstrap --no-git; \
635		   else \
636		     $$AUTORECONF -fvi; \
637		   fi \
638		&& ./configure \
639		&& if test $$p = make; then \
640		     $(MAKE) update; \
641		   else :; fi \
642	        && for t in $(pkg-targets); do \
643	             $(MAKE) $$t WERROR_CFLAGS= || exit 1; \
644		   done \
645	    ) || exit 1; \
646	    set +x; \
647	    echo; \
648	    echo ========  END TTP $$p  =========; \
649	    echo; \
650	 done
651ifndef keep-ttp-dir
652	rm -rf $@.d
653endif
654
655# Alias for lazy typists.
656ttp: ttp-check
657ttp-all: ttp-check-all
658
659.PHONY: ttp ttp-check ttp-all ttp-check-all
660