When "make dist" is run in a package tree that has subpackages, those tasks that are already done by the top package need not be repeated by a subpackage. For the length check (option filename-length-max=99) we already do this, as well as for the initial removal of part of the distdir tree, but for the mode fixing command, this was not done. Consequently, with a deep package hierarchy, the code was traversing the tree quite a bit more often than necessary.
This patch fixes it. This is not a bugfix, but only an optimization issue; the test that I added does not fail with the prior code, but it would fail if the new code failed to traverse the whole tree. Pushed to master. Cheers, Ralf distdir: avoid duplicate `find' traversal with subpackages. * lib/am/distdir.am (distdir) [%?SUBDIRS%]: When recursing, set `am__skip_mode_fix'. [%?TOPDIR_P%]: When `$(am__skip_mode_fix)' is set, avoid tree walk. * tests/subpkg4.test: New test, to ensure that we still walk the whole tree while fixing permissions. We don't ensure it is walked once only. * tests/Makefile.am: Update. diff --git a/lib/am/distdir.am b/lib/am/distdir.am index 5ee7b5c..9fc03cb 100644 --- a/lib/am/distdir.am +++ b/lib/am/distdir.am @@ -249,7 +249,7 @@ if %?SUBDIRS% $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: distdir)"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ @@ -260,6 +260,8 @@ if %?SUBDIRS% am__remove_distdir=: \ ## Disable filename length check: am__skip_length_check=: \ +## No need to fix modes more than once: + am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ @@ -293,8 +295,13 @@ endif %?DIST-TARGETS% ## We use $(install_sh) because that is a known-portable way to modify ## the file in place in the source tree. ## +## If we are being invoked recursively, then there is no need to walk +## the whole subtree again. This is a complexity reduction for a deep +## hierarchy of subpackages. +## if %?TOPDIR_P% - -find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 09b979c..afcfda8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -629,6 +629,7 @@ subobjname.test \ subpkg.test \ subpkg2.test \ subpkg3.test \ +subpkg4.test \ subst.test \ subst2.test \ subst3.test \ diff --git a/tests/subpkg4.test b/tests/subpkg4.test new file mode 100755 index 0000000..592b37e --- /dev/null +++ b/tests/subpkg4.test @@ -0,0 +1,73 @@ +#! /bin/sh +# Copyright (C) 2006, 2009 Free Software Foundation, Inc. +# +# This program 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 3, 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Test to ensure `distdir' fixes the mode of files and directories +# copied into `$(distdir)', even with sub-packages. + +. ./defs || Exit 1 + +set -e + +cat >Makefile.am <<'END' +SUBDIRS = subpkg +test-distdir-is-readable: + bad_dirs=`find $(distdir) -type d ! -perm -777 -print`; \ + if test -n "$$bad_dirs"; then \ + echo "directories not permissive: $$bad_dirs" >&2; \ + exit 1; \ + fi + bad_files=`find $(distdir) ! -type d ! -perm -444 -print`; \ + if test -n "$$bad_files"; then \ + echo "file not permissive: $$bad_files" >&2; \ + exit 1; \ + fi +END + +cat >>configure.in <<'END' +AC_CONFIG_SUBDIRS([subpkg]) +AC_OUTPUT +END + +mkdir subpkg subpkg/dir +echo foobar >subpkg/foobar +echo baz > subpkg/dir/baz + +chmod go-rwx subpkg/foobar subpkg/dir/baz subpkg/dir + +cat >subpkg/Makefile.am <<'END' +EXTRA_DIST = foobar dir +END + +cat >subpkg/configure.in <<'END' +AC_INIT([subpkg], [1.0]) +AM_INIT_AUTOMAKE +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT +END + +$ACLOCAL +$AUTOMAKE +$AUTOCONF + +cd subpkg +$ACLOCAL +$AUTOMAKE +$AUTOCONF +cd .. + +./configure +$MAKE distdir +$MAKE test-distdir-is-readable