+2004-05-22 Alexandre Duret-Lutz <adl@gnu.org>
+
+ Check directory names for unportable names. Shaking the code
+ to check this also led to the removal of the no-"/"-in-SUBDIRS
+ restriction, and a fix to _do_recursive_traversal.
+
+ * automake.in (check_directory): New function extracted from
+ handle_subdirs, and augmented to check for reserved W32/DOS name.
+ (check_directories_in_var): New function.
+ (handle_subdirs): Call check_directories_in_var. Doing so also
+ suppress the restriction that SUBDIRS should not contain slashes.
+ (scan_autoconf_traces) <AC_CONFIG_AUX_DIR>: Call check_directory
+ to ensure the argument exists and is safe.
+ * doc/automake.texi (Top level): Do not say that src/subdir
+ cannot be put in SUBDIRS.
+ (Dist): Mention that distdir and top_distdir can be absolute.
+ * lib/Automake/Variable.pm (_do_recursive_traversal) Support
+ undefined $fun_collect, and fix two bugs introduced with
+ skip_ac_subst on 2004-03-07.
+ * lib/am/distdir.am (distdir): Use absolute distdir and
+ top_distdir when recursing, because we can no longer prepend only
+ `..' in case of SUBDIRS with `/'.
+ * tests/auxdir4.test, tests/subdir9.test: New files.
+ * tests/Makefile.am (TESTS): Add auxdir4.test.
+ * tests/cond2.test, tests/subdir7.test: Augment to check location
+ in diagnostics.
+
2004-05-21 Eric Blake <ebb9@byu.net> (tiny changes)
* tests/txinfo22.test (AC_CONFIG_AUX_DIR): Use aux1, not aux, for
}
-# &handle_subdirs ()
-# ------------------
-# Handle subdirectories.
-sub handle_subdirs ()
+# check_directory ($NAME, $WHERE)
+# -------------------------------
+# Ensure $NAME is a directory, and that it uses sane name.
+# Use $WHERE as a location in the diagnostic, if any.
+sub check_directory ($$)
{
- my $subdirs = var ('SUBDIRS');
- return
- unless $subdirs;
+ my ($dir, $where) = @_;
- my @subdirs = $subdirs->value_as_list_recursive;
- my @dsubdirs = ();
- my $dsubdirs = var ('DIST_SUBDIRS');
- @dsubdirs = $dsubdirs->value_as_list_recursive
- if $dsubdirs;
+ error $where, "required directory $relative_dir/$dir does not exist"
+ unless -d "$relative_dir/$dir";
# If an `obj/' directory exists, BSD make will enter it before
# reading `Makefile'. Hence the `Makefile' in the current directory
# % pmake # BSD make
# echo World
# World
- msg_var ('portability', 'SUBDIRS',
- "naming a subdirectory `obj' causes troubles with BSD make")
- if grep ($_ eq 'obj', @subdirs);
- msg_var ('portability', 'DIST_SUBDIRS',
- "naming a subdirectory `obj' causes troubles with BSD make")
- if grep ($_ eq 'obj', @dsubdirs);
+ msg ('portability', $where,
+ "naming a subdirectory `obj' causes troubles with BSD make")
+ if $dir eq 'obj';
- # Make sure each directory mentioned in SUBDIRS actually exists.
- foreach my $dir (@subdirs)
- {
- # Skip directories substituted by configure.
- next if $dir =~ /^\@.*\@$/;
+ # `aux' is probably the most important of the following forbidden name,
+ # since it's tempting to use it as an AC_CONFIG_AUX_DIR.
+ msg ('portability', $where,
+ "name `$dir' is reserved on W32 and DOS platforms")
+ if grep (/^$dir$/i, qw/aux lpt1 lpt2 lpt3 com1 com2 com3 com4 con prn/);
+}
- if (! -d $relative_dir . '/' . $dir)
- {
- err_var ('SUBDIRS', "required directory $relative_dir/$dir "
- . "does not exist");
- next;
- }
+# check_directories_in_var ($VARIABLE)
+# ------------------------------------
+# Recursively check all items in variables $VARIABLE as directories
+sub check_directories_in_var ($)
+{
+ my ($var) = @_;
+ $var->traverse_recursively
+ (sub
+ {
+ my ($var, $val, $cond, $full_cond) = @_;
+ check_directory ($val, $var->rdef ($cond)->location);
+ return ();
+ },
+ undef,
+ skip_ac_subst => 1);
+}
- err_var 'SUBDIRS', "directory should not contain `/'"
- if $dir =~ /\//;
- }
+# &handle_subdirs ()
+# ------------------
+# Handle subdirectories.
+sub handle_subdirs ()
+{
+ my $subdirs = var ('SUBDIRS');
+ return
+ unless $subdirs;
+
+ check_directories_in_var $subdirs;
+
+ my $dsubdirs = var ('DIST_SUBDIRS');
+ check_directories_in_var $dsubdirs
+ if $dsubdirs;
$output_rules .= &file_contents ('subdirs', new Automake::Location);
rvar ('RECURSIVE_TARGETS')->rdef (TRUE)->{'pretty'} = VAR_SORTED; # Gross!
}
$config_aux_dir = $args[1];
$config_aux_dir_set_in_configure_ac = 1;
+ $relative_dir = '.';
+ check_directory ($config_aux_dir, $where);
}
elsif ($macro eq 'AC_CONFIG_FILES')
{
@vindex MAKE
@vindex MAKEFLAGS
-The directories mentioned in @code{SUBDIRS} must be direct children of
-the current directory. For instance, you cannot put @samp{src/subdir}
-into @code{SUBDIRS}. Instead you should put @code{SUBDIRS = subdir}
-into @file{src/Makefile.am}. Automake can be used to construct packages
-of arbitrary depth this way.
+The directories mentioned in @code{SUBDIRS} are usually direct
+children of the current directory, each subdirectory containing its
+own @file{Makefile.am} with a @code{SUBDIRS} pointing to deeper
+subdirectories. Automake can be used to construct packages of
+arbitrary depth this way.
By default, Automake generates @file{Makefiles} which work depth-first
(@samp{postfix}). However, it is possible to change this ordering.
tarball. If you are at the top-level directory, then @code{distdir =
$(PACKAGE)-$(VERSION)}. When used from subdirectory named
@file{foo/}, then @code{distdir = ../$(PACKAGE)-$(VERSION)/foo}.
+@code{$(distdir)} can be a relative or absolute path, do not assume
+any form.
@code{$(top_distdir)} always points to the root directory of the
distributed tree. At the top-level it's equal to @code{$(distdir)}.
In the @file{foo/} subdirectory
@code{top_distdir = ../$(PACKAGE)-$(VERSION)}.
+@code{$(top_distdir)} too can be a relative or absolute path.
Note that when packages are nested using @code{AC_CONFIG_SUBDIRS}
(@pxref{Subdirectories, AC_CONFIG_SUBDIRS, Configuring Other Packages
-@set UPDATED 15 May 2004
+@set UPDATED 22 May 2004
@set UPDATED-MONTH May 2004
@set EDITION 1.8a
@set VERSION 1.8a
-@set UPDATED 15 May 2004
+@set UPDATED 22 May 2004
@set UPDATED-MONTH May 2004
@set EDITION 1.8a
@set VERSION 1.8a
i.e., C<&fun_item> will never be called for them.
C<&fun_item> may return a list of items, they will be passed to
-C<&fun_store> later on. Define C<&fun_item> as C<undef> when it serve
-no purpose, this will speed things up.
+C<&fun_store> later on. Define C<&fun_item> or @<&fun_store> as
+C<undef> when they serve no purpose.
Once all items of a variable have been processed, the result (of the
calls to C<&fun_items>, or of recursive traversals of subvariables)
$fun_collect,
$cond_filter,
$full_cond,
- $inner_expand);
+ $inner_expand,
+ $skip_ac_subst);
push (@result, @res);
pop @_substfroms;
# We do not know any variable with this name. Fall through
# to filename processing.
}
- elsif ($skip_ac_subst && $var =~ /^\@.+\@$/)
+ elsif ($skip_ac_subst && $val =~ /^\@.+\@$/)
{
next;
}
# is free to use the same variable several times in the same definition.
$var->{'scanned'} = -1;
+ return ()
+ unless $fun_collect;
# Make sure you update the doc of Automake::Variable::traverse_recursively
# if you change the prototype of &fun_collect.
return &$fun_collect ($var, $parent_cond, @allresults);
list='$(%DIST_SUBDIR_NAME%)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
- || mkdir "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="../$(top_distdir)" \
- distdir="../$(distdir)/$$subdir" \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
auxdir.test \
auxdir2.test \
auxdir3.test \
+auxdir4.test \
backsl.test \
backsl2.test \
backsl3.test \
subdir6.test \
subdir7.test \
subdir8.test \
+subdir9.test \
subdirbuiltsources.test \
subcond.test \
subcond2.test \
auxdir.test \
auxdir2.test \
auxdir3.test \
+auxdir4.test \
backsl.test \
backsl2.test \
backsl3.test \
subdir6.test \
subdir7.test \
subdir8.test \
+subdir9.test \
subdirbuiltsources.test \
subcond.test \
subcond2.test \
--- /dev/null
+#! /bin/sh
+# Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Automake; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Make sure we diagnose dangerous AC_CONFIG_AUX_DIR names.
+
+. ./defs || exit 1
+
+set -e
+
+cat >configure.in <<'END'
+AC_INIT([auxdir4], [1.0])
+AC_CONFIG_AUX_DIR([aux])
+AM_INIT_AUTOMAKE
+AC_CONFIG_FILES([Makefile])
+END
+
+: > Makefile.am
+
+$ACLOCAL
+AUTOMAKE_fails
+grep 'configure.in:2:.*aux.*does not exist' stderr
+grep 'configure.in:2:.*aux.*W32' stderr
#! /bin/sh
-# Copyright (C) 1997, 2001, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
#
# This file is part of GNU Automake.
#
$ACLOCAL
AUTOMAKE_fails
-grep 'dir2.*does not exist' stderr
+grep 'Makefile.am:4:.*dir2.*does not exist' stderr
#! /bin/sh
-# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
#
# This file is part of GNU Automake.
#
$ACLOCAL
AUTOMAKE_fails
-grep 'obj.*BSD' stderr
+grep 'Makefile.am:1:.*obj.*BSD' stderr
-cat >Makefile.am <<EOF
+cat >Makefile.am <<'EOF'
SUBDIRS = @STH@
-DIST_SUBDIRS = obj
+FOO = obj
+DIST_SUBDIRS = $(FOO)
EOF
AUTOMAKE_fails
-grep 'obj.*BSD' stderr
+grep 'Makefile.am:2:.*obj.*BSD' stderr
--- /dev/null
+#! /bin/sh
+# Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Automake; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Test SUDBIRS with /.
+
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AC_CONFIG_FILES([src/subdir/Makefile src/subdir2/Makefile])
+AC_OUTPUT
+END
+
+echo SUBDIRS = src/subdir >Makefile.am
+
+mkdir src
+mkdir src/subdir
+mkdir src/subdir2
+
+: >src/subdir/foo
+: >src/subdir2/foo
+
+cat >src/subdir/Makefile.am <<'EOF'
+EXTRA_DIST = foo
+SUBDIRS = ../subdir2
+EOF
+
+cat >src/subdir2/Makefile.am <<'EOF'
+EXTRA_DIST = foo
+EOF
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --copy --add-missing
+./configure
+$MAKE distdir
+test -f subdir9-1.0/src/subdir/foo
+test -f subdir9-1.0/src/subdir2/foo
+$MAKE clean
+$MAKE distclean
+test ! -f src/subdir2/Makefile