Added --strictness option.
+Mon Dec 4 11:55:36 1995 Tom Tromey <tromey@cambric.colorado.edu>
+
+ * Makefile.am (bin_SCRIPTS): Changed name from SCRIPTS.
+
+ * automake.in (LENIENT, GNU, GNITS): New constants.
+ (initialize_per_input): New function.
+ (generate_makefile): Use it.
+ (initialize_global_constants): Renamed from init_globals.
+ (require_file): Added strictness argument.
+ (parse_arguments): Added --strict option.
+ (set_strictness): New function.
+ (parse_arguments): use it.
+ (initialize_global_constants): Document --strictness.
+
+ * automake.in: Use ${1+"$@"} to preserve quoting when running
+ under sh.
+
+ * texinfos.am (install-info): Don't use "true".
+ * tags.am (TAGS): Don't use "true".
+
+ * dist.am, dist-subd-top.am, remake-hdr.am, remake-subd.am,
+ remake.am, subdirs.am, texinfos.am: Use "&&" after cd.
+
+ * program.am (@PROGRAM@): Use LINK macro.
+ * compile.am (.c.o): Use COMPILE macro.
+
+ * clean.am, remake-hdr.am, remake.am, texinfos.am: Use $(...), not
+ ${...}.
+
+ * subdirs.am (RECURSIVE): Removed macro.
+
+ * clean.am: Changed to not be so verbose.
+
+ * Makefile.am (pkgdata_DATA): Include texi-clean.am.
+ * automake.in (handle_texinfo): Transform texi-clean and put into
+ output rules.
+ * texinfos-vars.am (TEXFILES): Removed.
+ * texinfos.am: Removed 'clean' targets.
+ * texi-clean.am: New file.
+
+ * Makefile.am (ETAGS_ARGS): Just use 'automake.in'.
+
+ * texinfos-vars.am (TEXFILES): Added *.op.
+
+ * dist-vars.am (DISTFILES): Renamed from DIST_FILES, per GNU
+ standards.
+ * dist.am (dist): Use DISTFILES.
+ * dist-subd.am (dist): Use DISTFILES.
+ * dist-subd-top.am (dist): Use DISTFILES.
+
Sun Dec 3 00:24:08 1995 Tom Tromey <tromey@cambric.colorado.edu>
+ * Makefile.am (ETAGS_ARGS): Define.
+
+ * depend.am (.deps/.P): Use ":", not "echo timestamp". From Jim
+ Meyering.
+
* dist-vars.am (DIST_FILES): Removed PACKAGEDATA.
* automake.in (handle_scripts): Use am_install_var.
-SCRIPTS = automake
+bin_SCRIPTS = automake
TEXINFOS = automake.texi
# SUBDIRS = intl po
# CONFIG_HEADER = config.h
libraries.am library.am mans-vars.am \
program.am programs.am remake-hdr.am \
remake-subd.am remake.am scripts.am subdirs.am tags.am tags-subd.am \
-tags-clean.am texi-version.am texinfos-vars.am texinfos.am
+tags-clean.am \
+texi-clean.am texi-version.am texinfos-vars.am texinfos.am
DIST_OTHER = automake.in
automake: automake.in
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+# The following requires a fixed version of the Emacs 19.30 etags.
+ETAGS_ARGS = automake.in
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
-
-SCRIPTS = automake
-
+bin_SCRIPTS = automake
TEXINFOS = automake.texi
pkgdata_DATA = clean-kr.am clean.am compile-kr.am compile-vars.am \
compile.am data.am depend.am dist-subd-top.am \
dist-subd.am dist-vars.am dist.am footer.am header-vars.am \
-kr-vars.am libscripts.am libprograms.am libraries-vars.am \
+kr-vars.am libprograms.am libraries-vars.am \
libraries.am library.am mans-vars.am \
program.am programs.am remake-hdr.am \
remake-subd.am remake.am scripts.am subdirs.am tags.am tags-subd.am \
-tags-clean.am texi-version.am texinfos-vars.am texinfos.am
-
+tags-clean.am \
+texi-clean.am texi-version.am texinfos-vars.am texinfos.am
DIST_OTHER = automake.in
-DIST_SUBDIRS = RCS samples
+ETAGS_ARGS = automake.in
+
+SCRIPTS = ${bin_SCRIPTS}
MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
-TEXFILES = *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg *.toc *.tp *.vr
+TEXFILES = *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg \
+*.toc *.tp *.vr *.op
INFOS = automake.info*
INFO_DEPS = automake.info
PACKAGE = @PACKAGE@
VERSION = @VERSION@
-DIST_FILES = $(SOURCES) $(HEADERS) $(TEXINFOS) $(INFOS) $(MANS) \
- $(DIST_OTHER) $(DIST_COMMON) $(DATA) $(PACKAGEDATA)
+DISTFILES = $(SOURCES) $(HEADERS) $(TEXINFOS) $(INFOS) $(MANS) \
+ $(DIST_OTHER) $(DIST_COMMON) $(DATA)
default: all
-install-scripts: $(SCRIPTS)
+install-binSCRIPTS: $(bin_SCRIPTS)
$(top_srcdir)/mkinstalldirs $(bindir)
- for p in $(SCRIPTS); do \
+ for p in $(bin_SCRIPTS); do \
$(INSTALL_SCRIPT) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
done
-uninstall-scripts:
- for p in $(SCRIPTS); do \
+uninstall-binSCRIPTS:
+ for p in $(bin_SCRIPTS); do \
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
done
mostlyclean-scripts:
clean-scripts:
- rm -f $(SCRIPTS)
+ rm -f $(bin_SCRIPTS)
distclean-scripts:
if test -f $$file; then \
d=.; \
else \
- d=${srcdir}; \
+ d=$(srcdir); \
fi; \
for ifile in $${file}*; do \
$(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \
done; \
- if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
- install-info --infodir=$(infodir) $$d/$$file; \
- else \
- true; \
- fi; \
+ $(SHELL) -c 'install-info --version' >/dev/null 2>&1 \
+ && install-info --infodir=$(infodir) $$d/$$file; \
done
uninstall-info:
- cd $(srcdir); for file in *.info*; do
+ cd $(srcdir) && for file in *.info*; do
rm -f $(infodir)/$$file; \
done
mostlyclean-info:
- rm -f $(TEXFILES)
+ rm -f automake.aux automake.cp automake.cps automake.dvi
+ rm -f automake.fn automake.fns automake.ky automake.log
+ rm -f automake.pg automake.toc automake.tp automake.vr automake.op
clean-info:
done
$(srcdir)/Makefile.in: Makefile.am
- cd $(srcdir); automake Makefile
+ cd $(srcdir) && automake Makefile
# For an explanation of the following Makefile rules, see node
# `Automatic Remaking' in GNU Autoconf documentation.
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
config.status: configure
./config.status --recheck
-${srcdir}/configure: configure.in ${ACLOCAL}
- cd $(srcdir); autoconf
+$(srcdir)/configure: configure.in $(ACLOCAL)
+ cd $(srcdir) && autoconf
+
+id: ID
+
+ID:
+ here=`pwd`; cd $(srcdir) && mkid -f $$here/ID $(SOURCES) $(HEADERS)
tags: TAGS
+
TAGS:
+ here=`pwd`; cd $(srcdir) && etags $(ETAGS_ARGS) $(SOURCES) $(HEADERS) -o $$here/TAGS
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ rm -f TAGS ID
+
+maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
-dist: $(DIST_FILES)
+dist: $(DISTFILES)
rm -rf $(distdir)
mkdir $(distdir)
- (cd $(srcdir); automake --include-deps --output-dir=$(distdir))
- @for file in $(DIST_FILES); do \
+ (cd $(srcdir) && automake --include-deps --output-dir=$(distdir))
+ @for file in $(DISTFILES); do \
test -f $(distdir)/$$file || { \
echo linking $$file; \
ln $(srcdir)/$$file $(distdir)/$$file; \
@sublist="$(DIST_SUBDIRS)"; \
for dir in $$sublist; do \
echo copying directory $$dir; \
- tar -chof - $$dir | (cd $(distdir); tar -xBpf -); \
+ tar -chof - $$dir | (cd $(distdir) && tar -xBpf -); \
done
chmod -R a+r $(distdir)
tar -chozf $(distdir).tar.gz $(distdir)
rm -rf $(distdir)
-all: info $(SCRIPTS)
+all: info
info: $(INFO_DEPS)
installcheck:
-install-exec: install-scripts
+install-exec: install-binSCRIPTS
install-data: install-info install-pkgdataDATA
install: install-exec install-data
-uninstall: uninstall-scripts uninstall-info uninstall-pkgdataDATA
+uninstall: uninstall-binSCRIPTS uninstall-info uninstall-pkgdataDATA
installdirs:
- $(top_srcdir)/mkinstalldirs $(bindir) $(infodir) ${pkgdatadir}
-
-
+ $(top_srcdir)/mkinstalldirs ${bindir} $(infodir) ${pkgdatadir}
mostlyclean-generic:
- if test -n "$(MOSTLYCLEANFILES)"; then \
- rm -f $(MOSTLYCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
- if test -n "$(CLEANFILES)"; then \
- rm -f $(CLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
rm -f Makefile $(DISTCLEANFILES)
- rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
+ rm -f config.cache config.log config.status $(CONFIG_HEADER) stamp-h
maintainer-clean-generic:
- if test -n "$(MAINTAINERCLEANFILES)"; then \
- rm -f $(MAINTAINERCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-mostlyclean: mostlyclean-scripts mostlyclean-vti mostlyclean-info mostlyclean-generic
+mostlyclean: mostlyclean-vti mostlyclean-info mostlyclean-tags mostlyclean-generic
-clean: mostlyclean clean-scripts clean-vti clean-info clean-generic
+clean: mostlyclean clean-vti clean-info clean-tags clean-generic
-distclean: clean distclean-scripts distclean-vti distclean-info distclean-generic
+distclean: clean distclean-vti distclean-info distclean-tags distclean-generic
-maintainer-clean: distclean maintainer-clean-scripts maintainer-clean-vti maintainer-clean-info maintainer-clean-generic
+maintainer-clean: distclean maintainer-clean-vti maintainer-clean-info maintainer-clean-tags maintainer-clean-generic
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
automake: automake.in
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+# The following requires a fixed version of the Emacs 19.30 etags.
+
.SUFFIXES:
.SUFFIXES: .texi .info .dvi
* FINISH new `where_HOW' scheme!
* Update docs!
-Some known problems:
-* clean targets not very well tested
+Clean up the output:
+* Order rules sensibly
+* Ensure every line has a purpose. Omit unused stuff
+* Eliminate extraneous rules when possible (eg 'install-am' stuff)
+* Make sure vertical spacing is correct
+* pretty-print targets, rules, etc.
+
+Need OTHER_SOURCES to hold sources whose objects end up in eg LIBOBJS.
+Dependency tracking should work here.
+
+Consider automatic support for ".y" files. At the very least arrange
+to have the corresponding ".c" file be distributed.
+
+Implement better rule for copying through comments. Rule should be
+that if comment immediately precedes rule or variable definition, then
+comment should be put there. Else what happens now is ok.
+
+install-info doesn't have to look in build directory for info files;
+just don't support this mode.
+
+Write autoconf macro to do all work necessary for automake. Eg define
+PACKAGE, VERSION, etc.
+
+Change glob pattern to look for to '*/Makefile*.am', so that gettext's
+po directory can use a Makefile.in.am (and generate Makefile.in.in)
Should 'distclean' remove $(SCRIPTS)?
Should 'maintainer-clean' do "rm -rf .deps"?
It would be good to check some parts of GNU standards. Already check
for install-sh and mkinstalldirs. What else is required to be in
package by GNU standards or by automake?
+here are some ideas:
+* --gnits, --gnu-, --no-gnu (default) are checking options
+* --gnits is most strict
+Some things for --gnits:
+* "cd $(foo); something" is an error in a rule. Should be:
+ "cd $(foo) && something"
Maybe it should be possible to disable all GNU-specific things with
--no-gnu? --ignore-standards? But what? And why?
will need more than one stamp-vti.
[ actually, we could just number them. version0.texi, version1.texi,
-etc ]
+etc ] [ actually, we can't, because the user could be reasonably
+expected to want to make dependencies using the name of the .texi file
+]
================================================================
AM_TEXINFOS override form
SUFFIXES additional suffixes
+Document customary ordering of Makefile.am. From Franc,ois.
+
================================================================
Libraries:
-* Need a way to specify library should be installed
+X Need a way to specify library should be installed
* Should support standalone library along with subdir library in same
Makefile.am. Maybe: turn off "standalone" mode if library's Makefile.am
is not only one specd?
-* Need a way to install library header files.
+X Need a way to install library header files.
* Need a way to handle shared libraries.
It would be really interesting to be able to easily (as the end-user)
make many different versions of the library: shared, static, profiling,
# -*- perl -*-
# @configure_input@
-eval "exec /usr/local/bin/perl -S $0 $*"
+eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# automake - create Makefile.in from Makefile.am
\f
+# Constants to define the "strictness" level.
+$LENIENT = 0;
+$GNU = 1;
+$GNITS = 2;
+
+\f
+
+# Variables global to entire run.
+
+# Strictness level.
+$strictness = $LENIENT;
+
# This is TRUE if GNU make specific automatic dependency generation
# code should be included in generated Makefile.in.
$use_dependencies = 1;
# we have processed all input files.
$exit_status = 0;
-# These two variables are used when generating each Makefile.in. They
-# hold the Makefile.in until it is ready to be printed.
-$output_rules = '';
-$output_vars = '';
-$output_trailer = '';
-
-# Suffixes found during a run.
-@suffixes = ();
-
-# This holds the contents of a Makefile.am, as parsed by read_am_file.
-%contents = ();
-
-# This holds the "relative directory" of the current Makefile.in. Eg
-# for src/Makefile.in, this is "src".
-$relative_dir = '';
-
-# Directory where output files go. Actually, output files are
-# relative to this directory.
-$output_directory = '.';
-
-# This holds a list of files that are included in the distribution.
-@dist_common = ();
-
-# List of dependencies for the obvious targets.
-@install_data = ();
-@install_exec = ();
-@uninstall = ();
-@installdirs = ();
-
-@info = ();
-@dvi = ();
-@all = ();
-@check = ();
-@installcheck = ();
-@clean = ();
-
-# TRUE if current directory holds any C source files. (Actually holds
-# object extension, but this information is encapsulated in the
-# function get_object_extension).
-$dir_holds_sources = '';
-
-# TRUE if install targets should work recursively.
-$recursive_install = 0;
-
\f
-&init_globals;
+&initialize_global_constants;
# Parse command line.
@input_files = &parse_arguments (@ARGV);
}
elsif ($arglist[0] eq '--amdir')
{
- if ($#arglist == 0)
- {
- print STDERR
- "automake: no argument given for option \`$arglist[0]'\n";
- exit 1;
- }
+ &require_argument (@arglist);
shift (@arglist);
$am_dir = $arglist[0];
}
+ elsif ($arglist[0] =~ /^--strictness=(.+)$/)
+ {
+ &set_strictness ($1);
+ }
+ elsif ($arglist[0] eq '--strictness')
+ {
+ &require_argument (@arglist);
+ shift (@arglist);
+ &set_strictness ($arglist[0]);
+ }
elsif ($arglist[0] eq '--include-deps')
{
$use_dependencies = 0;
}
elsif ($arglist[0] eq '--output-dir')
{
- if ($#arglist == 0)
- {
- print STDERR
- "automake: no argument given for option \`$arglist[0]'\n";
- exit 1;
- }
+ &require_argument (@arglist);
shift (@arglist);
$output_directory = $arglist[0];
}
return (@make_list);
}
+# Ensure argument exists, or die.
+sub require_argument
+{
+ local ($arg, @arglist) = @_;
+ if ($#arglist >= 0)
+ {
+ print STDERR "automake: no argument given for option \`$arg'\n";
+ exit 1;
+ }
+}
+
################################################################
# Generate a Makefile.in given the name of the corresponding Makefile.
print "creating ", $makefile, ".in\n";
+ &initialize_per_input;
$relative_dir = &dirname ($makefile);
- $output_rules = '';
- $output_vars = '';
- $output_trailer = '';
- @suffixes = ();
- %contents = ();
# FIXME with new 'dist' target, don't need Makefile.in. Probably
# should remove it here.
@dist_common = ('Makefile.in', 'Makefile.am');
- @install_data = ();
- @install_exec = ();
- @uninstall = ();
- @installdirs = ();
- $dir_holds_sources = '';
- $recursive_install = 0;
- @info = ();
- @dvi = ();
- @all = ();
- @check = ();
- @installcheck = ();
- @clean = ();
# Generate header before reading .am file. The header must come
# before anything else, and read_am_file copies code into the
$dir_holds_sources = '.${kr}o';
push (@suffixes, '._c', '._o');
- &require_file ('ansi2knr.c');
- &require_file ('ansi2knr.1');
+ &require_file ($NORMAL, 'ansi2knr.c');
+ &require_file ($NORMAL, 'ansi2knr.1');
$output_vars .= &file_contents ('kr-vars');
$output_rules .= &file_contents ('compile-kr');
($tfile = &file_contents ('texi-version')) =~ s/\@TEXI\@/$texis[0]/g;
$output_rules = $output_rules . $tfile;
- &require_file ('mdate-sh');
+ &require_file ($NORMAL, 'mdate-sh');
}
# If user specified file_TEXINFOS, then use that as explicit
$output_vars = $output_vars . &file_contents ('texinfos-vars');
$output_rules = $output_rules . &file_contents ('texinfos');
+ # How to clean.
+ local ($crules) = &file_contents ('texi-clean');
+ $crules =~ s/\@TEXI\@/$infobase/g;
+ $output_rules .= $crules;
+
push (@suffixes, '.texi', '.info', '.dvi');
push (@uninstall, 'uninstall-info');
push (@clean, 'info');
. "DVIS = " . $infobase . ".dvi\n\n");
# Do some error checking.
- &require_file ('texinfo.tex');
+ &require_file ($NORMAL, 'texinfo.tex');
}
# Handle any man pages.
$output_rules .= &file_contents ('remake');
# Look for some files we need.
- &require_file ('install-sh');
- &require_file ('mkinstalldirs');
+ &require_file ($NORMAL, 'install-sh');
+ &require_file ($NORMAL, 'mkinstalldirs');
}
if (defined ($contents{'CONFIG_HEADER'})
################################################################
-# Initialize global variables.
-sub init_globals
+sub initialize_global_constants
{
# Associative array of standard directory names. Entry is TRUE if
# corresponding directory should be installed during
';
# Commonly found files we look for and automatically include in
- # DIST_FILES.
+ # DISTFILES.
@common_files =
(
"THANKS", "TODO", "README", "NEWS", "COPYING", "COPYING.LIB",
--help print this help, then exit
--include-deps include generated dependencies in Makefile.in
--output-dir=DIR put generated Makefile.in's into DIR
+ --strictness=LEVEL set strictness level. LEVEL is normal, gnu, gnits
--version print version number, then exit\n";
+}
+
+# (Re)-Initialize per-Makefile.am variables.
+sub initialize_per_input
+{
+ # These two variables are used when generating each Makefile.in.
+ # They hold the Makefile.in until it is ready to be printed.
+ $output_rules = '';
+ $output_vars = '';
+ $output_trailer = '';
+
+ # Suffixes found during a run.
+ @suffixes = ();
+
+ # This holds the contents of a Makefile.am, as parsed by
+ # read_am_file.
+ %contents = ();
+
+ # This holds the "relative directory" of the current Makefile.in.
+ # Eg for src/Makefile.in, this is "src".
+ $relative_dir = '';
+
+ # Directory where output files go. Actually, output files are
+ # relative to this directory.
+ $output_directory = '.';
+
+ # This holds a list of files that are included in the
+ # distribution.
+ @dist_common = ();
+
+ # List of dependencies for the obvious targets.
+ @install_data = ();
+ @install_exec = ();
+ @uninstall = ();
+ @installdirs = ();
+
+ @info = ();
+ @dvi = ();
+ @all = ();
+ @check = ();
+ @installcheck = ();
+ @clean = ();
+ # TRUE if current directory holds any C source files. (Actually
+ # holds object extension, but this information is encapsulated in
+ # the function get_object_extension).
+ $dir_holds_sources = '';
+
+ # TRUE if install targets should work recursively.
+ $recursive_install = 0;
}
+
################################################################
# Return contents of a file from $am_dir.
# the second argument is the primary variable (eg HEADERS), and all
# subsequent arguments are possible installation locations. FIXME
# should scan all defined variables and do some error checking to
-# avoid typos (eg 'bnidir_PROGRAMS' should give error). Returns TRUE
-# if any items were found, FALSE otherwise.
+# avoid typos (eg 'bni_PROGRAMS' should give error). Returns TRUE if
+# any items were found, FALSE otherwise.
sub am_install_var
{
local ($file, $primary, @prefixes) = @_;
################################################################
# Verify that the file must exist in the current directory.
+# Usage: require_file (strictness, file)
+# strictness is the strictness level at which this file becomes
+# required.
sub require_file
{
- local ($file) = @_;
+ local ($mystrict, $file) = @_;
local ($fullfile) = $relative_dir . "/" . $file;
- if (! -f $fullfile)
+ if (-f $fullfile)
+ {
+ push (@dist_common, $file);
+ }
+ elsif ($strictness >= $mystrict)
{
+ # Only an error if strictness constraint violated.
&am_error ("required file \"$fullfile\" not found");
}
+}
+
+# Set strictness.
+sub set_strictness
+{
+ local ($name) = @_;
+
+ if ($name eq 'gnu')
+ {
+ $strictness = $GNU;
+ }
+ elsif ($name eq 'gnits')
+ {
+ $strictness = $GNITS;
+ }
+ elsif ($name eq 'normal')
+ {
+ $strictness = $NORMAL;
+ }
else
{
- push (@dist_common, $file);
+ print STDERR "automake: level \`$name' not recognized\n";
+ exit 1;
}
}
@include version.texi
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* automake: (automake). Making Makefile.in's
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
@ifinfo
This file documents GNU automake @value{VERSION}
@titlepage
-@title GNU AutoMake
+@title GNU Automake
@subtitle For version @value{VERSION}, @value{UPDATED}
@c copyright page
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1995 Free Software Foundation, Inc.
@sp 2
-This is the first edition of the GNU AutoMake documentation,@*
-and is consistent with GNU AutoMake @value{VERSION}.@*
+This is the first edition of the GNU Automake documentation,@*
+and is consistent with GNU Automake @value{VERSION}.@*
@sp 2
Published by the Free Software Foundation @*
675 Massachusetts Avenue, @*
@ifinfo
@node Top, Introduction, (dir), (dir)
@comment node-name, next, previous, up
-@top
+@top GNU Automake
-This file documents the GNU AutoMake package for creating GNU
+This file documents the GNU Automake package for creating GNU
Standards-compliant Makefiles from template files. This edition
documents version @value{VERSION}.
@menu
-* Introduction:: AutoMake's purpose
-* Details:: Creating an AutoMake template file
+* Introduction:: Automake's purpose
+* Details:: Creating an Automake template file
* Invoking automake:: Creating a Makefile.in
* Future:: Some ideas for the future.
* Some index:: Index of variables
(@pxref{Makefile Conventions, , Makefile Conventions, standards.info, The
GNU Coding Standards})
is long, complicated,
-and subject to change. The goal of AutoMake is to remove the burden of
+and subject to change. The goal of Automake is to remove the burden of
Makefile maintenance from back the individual GNU maintainer (and put it
-on the back of the AutoMake maintainer)
+on the back of the Automake maintainer)
-Typical AutoMake input files are simply a series of macro definitions.
-AutoMake processes these files to produce @file{Makefile.in}s which are
+Typical Automake input files are simply a series of macro definitions.
+Automake processes these files to produce @file{Makefile.in}s which are
distribution-ready.
-AutoMake does force some structure on the package maintainer. However,
+Automake does force some structure on the package maintainer. However,
it is felt that this (minor) inconvenience is more than offset by
-AutoMake's convenience.
+Automake's convenience.
@node Details
@chapter Making @code{automake} templates
@menu
-* configure:: AutoMake and configure
+* configure:: Automake and configure
* Depth:: Types of package hierarchy
* Programs:: What gets built
* Source:: Specifying source files
@node configure
@section How @code{automake} and @code{configure} interact
-AutoMake enforces a certain amount of structure on the package
+Automake enforces a certain amount of structure on the package
maintainer. One such item is its requirement that the
@file{configure.in} for the package define the variables @samp{PACKAGE}
and @samp{VERSION}.
@var{PACKAGE} should be the name of the package as it appears when
-bundled for distribution. For instance, AutoMake defines @samp{PACKAGE}
-to be @samp{am}.
+bundled for distribution. For instance, Automake defines @samp{PACKAGE}
+to be @samp{automake}.
@var{VERSION} should be the version number of the release being worked
on. We recommend that you make @file{configure.in} the only place you
configure time. For instance, GNU cpio only builts @code{mt} and
@code{rmt} under special circumstances.
-In this case, you must notify AutoMake of all the programs that can
+In this case, you must notify Automake of all the programs that can
possibly be built, but at the same time cause the generated
@file{Makefile.in} to use the programs specified by @code{configure}.
You can do this using the @code{AM_PROGRAMS} variable. Here is the
@node Extending
-@section When AutoMake Isn't Enough
+@section When Automake Isn't Enough
Sometimes @code{automake} isn't enough. Then you just lose.
## We must test each macro because it might be empty, and an empty
## "rm -rf" command looks disturbing.
-
-## Each "if" must always have an else because, in some versions of sh,
-## "if" will return false if the test fails and there is no else
-## clause. Bogus!
-
mostlyclean-generic:
- if test -n "$(MOSTLYCLEANFILES)"; then \
- rm -f $(MOSTLYCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
- if test -n "$(CLEANFILES)"; then \
- rm -f $(CLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
rm -f Makefile $(DISTCLEANFILES)
- rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
+ rm -f config.cache config.log config.status $(CONFIG_HEADER) stamp-h
maintainer-clean-generic:
- if test -n "$(MAINTAINERCLEANFILES)"; then \
- rm -f $(MAINTAINERCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
.c.o:
- $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $<
+ $(COMPILE) $<
mostlyclean-compile:
rm -f *.o core
-include .deps/.P
.deps/.P:
test -d .deps || mkdir .deps
- echo timestamp > $@
+## Use ":" here and not "echo timestamp". Otherwise GNU Make barfs:
+## .deps/.P:1: *** missing separator. Stop.
+ : > $@
-include $(DEP_FILES)
$(DEP_FILES): .deps/.P
distdir = $(PACKAGE)-$(VERSION)
-dist: $(DIST_FILES)
+dist: $(DISTFILES)
rm -rf $(distdir)
mkdir $(distdir)
- (cd $(srcdir); automake --include-deps --output-dir=$(distdir))
- @for file in $(DIST_FILES); do \
+ (cd $(srcdir) && automake --include-deps --output-dir=$(distdir))
+ @for file in $(DISTFILES); do \
## Test for file existence because sometimes a file gets included in
-## DIST_FILES twice. For example this happens when a single source
+## DISTFILES twice. For example this happens when a single source
## file is used in building more than one program. Also, there are
## situations in which "ln" can fail. For instance a file to
## distribute could actually be a cross-filesystem symlink -- this can
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
- (cd $$subdir; $(MAKE) $@) || exit 1; \
+ (cd $$subdir && $(MAKE) $@) || exit 1; \
done
## Set "sublist" here because shells fail on "for dir in ; do".
@sublist="$(DIST_SUBDIRS)"; \
for dir in $$sublist; do \
echo copying directory $$dir; \
- tar -chf - $$dir | (cd $(distdir); tar -xBpf -); \
+ tar -chf - $$dir | (cd $(distdir) && tar -xBpf -); \
done
chmod -R a+r $(distdir)
tar -chozf $(distdir).tar.gz $(distdir)
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
-dist: $(DIST_FILES)
- @for file in $(DIST_FILES); do \
+dist: $(DISTFILES)
+ @for file in $(DISTFILES); do \
## See dist-subd-top.am to understand this.
test -f $(distdir)/$$file || { \
echo linking $$file; \
PACKAGE = @PACKAGE@
VERSION = @VERSION@
-DIST_FILES = $(SOURCES) $(HEADERS) $(TEXINFOS) $(INFOS) $(MANS) \
+DISTFILES = $(SOURCES) $(HEADERS) $(TEXINFOS) $(INFOS) $(MANS) \
$(DIST_OTHER) $(DIST_COMMON) $(DATA)
## See dist-subd-top.am to understand this file.
distdir = $(PACKAGE)-$(VERSION)
-dist: $(DIST_FILES)
+dist: $(DISTFILES)
rm -rf $(distdir)
mkdir $(distdir)
- (cd $(srcdir); automake --include-deps --output-dir=$(distdir))
- @for file in $(DIST_FILES); do \
+ (cd $(srcdir) && automake --include-deps --output-dir=$(distdir))
+ @for file in $(DISTFILES); do \
test -f $(distdir)/$$file || { \
echo linking $$file; \
ln $(srcdir)/$$file $(distdir)/$$file; \
@sublist="$(DIST_SUBDIRS)"; \
for dir in $$sublist; do \
echo copying directory $$dir; \
- tar -chof - $$dir | (cd $(distdir); tar -xBpf -); \
+ tar -chof - $$dir | (cd $(distdir) && tar -xBpf -); \
done
chmod -R a+r $(distdir)
tar -chozf $(distdir).tar.gz $(distdir)
-SCRIPTS = automake
+bin_SCRIPTS = automake
TEXINFOS = automake.texi
# SUBDIRS = intl po
# CONFIG_HEADER = config.h
libraries.am library.am mans-vars.am \
program.am programs.am remake-hdr.am \
remake-subd.am remake.am scripts.am subdirs.am tags.am tags-subd.am \
-tags-clean.am texi-version.am texinfos-vars.am texinfos.am
+tags-clean.am \
+texi-clean.am texi-version.am texinfos-vars.am texinfos.am
DIST_OTHER = automake.in
automake: automake.in
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+# The following requires a fixed version of the Emacs 19.30 etags.
+ETAGS_ARGS = automake.in
## We must test each macro because it might be empty, and an empty
## "rm -rf" command looks disturbing.
-
-## Each "if" must always have an else because, in some versions of sh,
-## "if" will return false if the test fails and there is no else
-## clause. Bogus!
-
mostlyclean-generic:
- if test -n "$(MOSTLYCLEANFILES)"; then \
- rm -f $(MOSTLYCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
- if test -n "$(CLEANFILES)"; then \
- rm -f $(CLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
rm -f Makefile $(DISTCLEANFILES)
- rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
+ rm -f config.cache config.log config.status $(CONFIG_HEADER) stamp-h
maintainer-clean-generic:
- if test -n "$(MAINTAINERCLEANFILES)"; then \
- rm -f $(MAINTAINERCLEANFILES); \
- else \
- true; \
- fi
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
.c.o:
- $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $<
+ $(COMPILE) $<
mostlyclean-compile:
rm -f *.o core
-include .deps/.P
.deps/.P:
test -d .deps || mkdir .deps
- echo timestamp > $@
+## Use ":" here and not "echo timestamp". Otherwise GNU Make barfs:
+## .deps/.P:1: *** missing separator. Stop.
+ : > $@
-include $(DEP_FILES)
$(DEP_FILES): .deps/.P
@PROGRAM@: $(@PROGRAM@_OBJECTS)
- $(CC) -o $@ $(@PROGRAM@_OBJECTS) $(LDFLAGS) $(@PROGRAM@_LDADD) $(LIBS)
+ $(LINK) $(@PROGRAM@_OBJECTS) $(@PROGRAM@_LDADD) $(LIBS)
-${CONFIG_HEADER}: stamp-h
-stamp-h: ${CONFIG_HEADER}.in config.status
- CONFIG_FILES= CONFIG_HEADERS=${CONFIG_HEADER} ./config.status
-${srcdir}/${CONFIG_HEADER}.in: stamp-h.in
-${srcdir}/stamp-h.in: configure.in ${ACLOCAL} ${ACCONFIG} ${CONFIG_TOP} ${CONFIG_BOT}
- cd $(srcdir); autoheader
+$(CONFIG_HEADER): stamp-h
+stamp-h: $(CONFIG_HEADER).in config.status
+ CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADER) ./config.status
+$(srcdir)/$(CONFIG_HEADER).in: stamp-h.in
+$(srcdir)/stamp-h.in: configure.in $(ACLOCAL) $(ACCONFIG) $(CONFIG_TOP) $(CONFIG_BOT)
+ cd $(srcdir) && autoheader
echo timestamp > $(srcdir)/stamp-h.in
@SET_MAKE@
-RECURSIVE = all-recursive install-data-recursive install-exec-recursive \
+all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive clean-recursive distclean-recursive \
-maintainer-clean-recursive
-
-$(RECURSIVE):
+maintainer-clean-recursive:
for subdir in $(SUBDIRS); do \
target=`echo $@ | sed s/-recursive//`; \
echo making $$target in $$subdir; \
- (cd $$subdir; $(MAKE) $$target) \
+ (cd $$subdir && $(MAKE) $$target) \
## This trick allows "-k" to keep its natural meaning when running a
## recursive rule.
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
for subdir in $(SUBDIRS); do \
## Never fail here if a subdir fails.
(cd $$subdir && $(MAKE) TAGS); \
- if test -f $$subdir/TAGS; then \
+ test -f $$subdir/TAGS && { \
tags="$$tags -i $$here/$$subdir/TAGS"; \
- else \
- true; \
- fi; \
+ } \
done; \
## Make sure we have something to run etags on. See clean.am to
## understand "if...else" braindamage.
- if test -n "$(ETAGS_ARGS)$(CONFIG_HEADER)$(SOURCES)$(HEADERS)$$tags"; \
- then \
- etags $(ETAGS_ARGS) $$tags $(CONFIG_HEADER) $(SOURCES) $(HEADERS); \
- else \
- true; \
- fi
+ test -n "$(ETAGS_ARGS)$(CONFIG_HEADER)$(SOURCES)$(HEADERS)$$tags" \
+ && etags $(ETAGS_ARGS) $$tags $(CONFIG_HEADER) $(SOURCES) $(HEADERS)
if test -f $$file; then \
d=.; \
else \
- d=${srcdir}; \
+ d=$(srcdir); \
fi; \
+## This ${...} is in the shell, not in make.
for ifile in $${file}*; do \
$(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \
done; \
- if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
- install-info --infodir=$(infodir) $$d/$$file; \
- else \
- true; \
- fi; \
+ $(SHELL) -c 'install-info --version' >/dev/null 2>&1 \
+ && install-info --infodir=$(infodir) $$d/$$file; \
done
uninstall-info:
- cd $(srcdir); for file in *.info*; do
+ cd $(srcdir) && for file in *.info*; do
rm -f $(infodir)/$$file; \
done
-mostlyclean-info:
- rm -f $(TEXFILES)
-
-clean-info:
-
-distclean-info:
-
-maintainer-clean-info:
- rm -f $(INFOS)
-
@PROGRAM@: $(@PROGRAM@_OBJECTS)
- $(CC) -o $@ $(@PROGRAM@_OBJECTS) $(LDFLAGS) $(@PROGRAM@_LDADD) $(LIBS)
+ $(LINK) $(@PROGRAM@_OBJECTS) $(@PROGRAM@_LDADD) $(LIBS)
-${CONFIG_HEADER}: stamp-h
-stamp-h: ${CONFIG_HEADER}.in config.status
- CONFIG_FILES= CONFIG_HEADERS=${CONFIG_HEADER} ./config.status
-${srcdir}/${CONFIG_HEADER}.in: stamp-h.in
-${srcdir}/stamp-h.in: configure.in ${ACLOCAL} ${ACCONFIG} ${CONFIG_TOP} ${CONFIG_BOT}
- cd $(srcdir); autoheader
+$(CONFIG_HEADER): stamp-h
+stamp-h: $(CONFIG_HEADER).in config.status
+ CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADER) ./config.status
+$(srcdir)/$(CONFIG_HEADER).in: stamp-h.in
+$(srcdir)/stamp-h.in: configure.in $(ACLOCAL) $(ACCONFIG) $(CONFIG_TOP) $(CONFIG_BOT)
+ cd $(srcdir) && autoheader
echo timestamp > $(srcdir)/stamp-h.in
cd $(top_srcdir) && automake $(subdir)/Makefile
Makefile: ../config.status Makefile.in
- cd ..; CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+ cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
$(srcdir)/Makefile.in: Makefile.am
- cd $(srcdir); automake Makefile
+ cd $(srcdir) && automake Makefile
# For an explanation of the following Makefile rules, see node
# `Automatic Remaking' in GNU Autoconf documentation.
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
config.status: configure
./config.status --recheck
-${srcdir}/configure: configure.in ${ACLOCAL}
- cd $(srcdir); autoconf
+$(srcdir)/configure: configure.in $(ACLOCAL)
+ cd $(srcdir) && autoconf
@SET_MAKE@
-RECURSIVE = all-recursive install-data-recursive install-exec-recursive \
+all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive clean-recursive distclean-recursive \
-maintainer-clean-recursive
-
-$(RECURSIVE):
+maintainer-clean-recursive:
for subdir in $(SUBDIRS); do \
target=`echo $@ | sed s/-recursive//`; \
echo making $$target in $$subdir; \
- (cd $$subdir; $(MAKE) $$target) \
+ (cd $$subdir && $(MAKE) $$target) \
## This trick allows "-k" to keep its natural meaning when running a
## recursive rule.
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
for subdir in $(SUBDIRS); do \
## Never fail here if a subdir fails.
(cd $$subdir && $(MAKE) TAGS); \
- if test -f $$subdir/TAGS; then \
+ test -f $$subdir/TAGS && { \
tags="$$tags -i $$here/$$subdir/TAGS"; \
- else \
- true; \
- fi; \
+ } \
done; \
## Make sure we have something to run etags on. See clean.am to
## understand "if...else" braindamage.
- if test -n "$(ETAGS_ARGS)$(CONFIG_HEADER)$(SOURCES)$(HEADERS)$$tags"; \
- then \
- etags $(ETAGS_ARGS) $$tags $(CONFIG_HEADER) $(SOURCES) $(HEADERS); \
- else \
- true; \
- fi
+ test -n "$(ETAGS_ARGS)$(CONFIG_HEADER)$(SOURCES)$(HEADERS)$$tags" \
+ && etags $(ETAGS_ARGS) $$tags $(CONFIG_HEADER) $(SOURCES) $(HEADERS)
--- /dev/null
+## We substitute the name of the texinfo file here because otherwise
+## too many things could be removed. In particular the ".log"
+## extension might be used in other contexts by the user
+mostlyclean-info:
+ rm -f @TEXI@.aux @TEXI@.cp @TEXI@.cps @TEXI@.dvi
+ rm -f @TEXI@.fn @TEXI@.fns @TEXI@.ky @TEXI@.log
+ rm -f @TEXI@.pg @TEXI@.toc @TEXI@.tp @TEXI@.vr @TEXI@.op
+
+clean-info:
+
+distclean-info:
+
+maintainer-clean-info:
+ rm -f $(INFOS)
+
MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
-TEXFILES = *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg *.toc *.tp *.vr
+TEXFILES = *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg \
+*.toc *.tp *.vr *.op
if test -f $$file; then \
d=.; \
else \
- d=${srcdir}; \
+ d=$(srcdir); \
fi; \
+## This ${...} is in the shell, not in make.
for ifile in $${file}*; do \
$(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \
done; \
- if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
- install-info --infodir=$(infodir) $$d/$$file; \
- else \
- true; \
- fi; \
+ $(SHELL) -c 'install-info --version' >/dev/null 2>&1 \
+ && install-info --infodir=$(infodir) $$d/$$file; \
done
uninstall-info:
- cd $(srcdir); for file in *.info*; do
+ cd $(srcdir) && for file in *.info*; do
rm -f $(infodir)/$$file; \
done
-mostlyclean-info:
- rm -f $(TEXFILES)
-
-clean-info:
-
-distclean-info:
-
-maintainer-clean-info:
- rm -f $(INFOS)
-