From: Peter Rosin <p...@lysator.liu.se> The rationale for this change is that it is annoying to have to repeat the directory name when including a Makefile fragment. For deep directory structures these repeats can generate a lot of bloat. It also hinders reuse and easy directory restructuring if all Makefile fragments have to know exactly where they live.
Suggested by Bob Friesenhahn, and later discussed in bug#13524. * automake.in (read_am_file): Add third argument specifying the relative directory of this Makefile fragment compared to the main Makefile. Replace &{CURDIR}& and &{CANON_CURDIR}& in the fragment with this relative directory (with slashes etc, or canonicalized). (read_main_am_file): Adjust. * t/curdir.sh: New test. * t/list-of-tests.mk: Augment. * doc/automake.texi (Include): Document the new feature. NEWS: Add new feature. Signed-off-by: Peter Rosin <p...@lysator.liu.se> Signed-off-by: Stefano Lattarini <stefano.lattar...@gmail.com> --- NEWS | 10 +++++ automake.in | 24 +++++++--- doc/automake.texi | 20 +++++++++ t/curdir.sh | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ t/list-of-tests.mk | 1 + 5 files changed, 179 insertions(+), 5 deletions(-) create mode 100755 t/curdir.sh diff --git a/NEWS b/NEWS index 6dcce72..4511fbb 100644 --- a/NEWS +++ b/NEWS @@ -100,6 +100,16 @@ New in 1.13.2: be longer necessary, so we deprecate it with runtime warnings. It will likely be removed altogether in Automake 1.14. +* Current directory in makefile fragments: + + - Use the special makefile fragment substitutions &{CURDIR}& and + &{CANON_CURDIR}& (a.k.a. &{D}& and &{C}& respectively) to insert the + relative directory of the fragment (or its canonicalized version) in + the makefile: + + bin_PROGRAMS += &{CURDIR}&/foo + &{CANON_CURDIR}&_foo_SOURCES = &{CURDIR}&/bar.c + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New in 1.13.2: diff --git a/automake.in b/automake.in index d6ed599..e8e4c3a 100644 --- a/automake.in +++ b/automake.in @@ -6330,15 +6330,15 @@ sub check_trailing_slash ($\$) } -# &read_am_file ($AMFILE, $WHERE) -# ------------------------------- +# &read_am_file ($AMFILE, $WHERE, $CURDIR) +# ---------------------------------------- # Read Makefile.am and set up %contents. Simultaneously copy lines # from Makefile.am into $output_trailer, or define variables as # appropriate. NOTE we put rules in the trailer section. We want # user rules to come after our generated stuff. sub read_am_file ($$) { - my ($amfile, $where) = @_; + my ($amfile, $where, $curdir) = @_; my $am_file = new Automake::XFile ("< $amfile"); verb "reading $amfile"; @@ -6423,6 +6423,18 @@ sub read_am_file ($$) my $new_saw_bk = check_trailing_slash ($where, $_); + my $cur_dir = &canonicalize ($curdir); + if ($curdir eq '.') + { + # If present, eat the following '_' or '/', converting + # "&{CURDIR}&/foo" and "&{CANON_CURDIR}&_foo" into plain "foo" + # when $curdir is '.'. + $_ =~ s,&\{(D|CURDIR)\}&/,,g; + $_ =~ s,&\{(C|CANON_CURDIR)\}&_,,g; + } + $_ =~ s/&\{(D|CURDIR)\}&/${curdir}/g; + $_ =~ s/&\{(C|CANON_CURDIR)\}&/${cur_dir}/g; + if (/$IGNORE_PATTERN/o) { # Merely delete comments beginning with two hashes. @@ -6584,8 +6596,10 @@ sub read_am_file ($$) push_dist_common ("\$\(srcdir\)/$path"); $path = $relative_dir . "/" . $path if $relative_dir ne '.'; } + my $new_curdir = File::Spec->abs2rel ($path, $relative_dir); + $new_curdir = '.' if $new_curdir !~ s,/[^/]*$,,; $where->push_context ("'$path' included from here"); - &read_am_file ($path, $where); + &read_am_file ($path, $where, $new_curdir); $where->pop_context; } else @@ -6658,7 +6672,7 @@ sub read_main_am_file ($$) &define_standard_variables; # Read user file, which might override some of our values. - &read_am_file ($amfile, new Automake::Location); + &read_am_file ($amfile, new Automake::Location, '.'); } diff --git a/doc/automake.texi b/doc/automake.texi index feae3ac..725f30a 100644 --- a/doc/automake.texi +++ b/doc/automake.texi @@ -10519,6 +10519,26 @@ condition applies to the entire contents of that fragment. Makefile fragments included this way are always distributed because they are needed to rebuild @file{Makefile.in}. +Inside a fragment, the construct @code{&@{CURDIR@}&} is replaced with the +directory of the fragment relative to the base @file{Makefile.am}. +Similarly, @code{&@{CANON_CURDIR@}&} is replaced with the canonicalized +(@pxref{Canonicalization}) form of @code{&@{CURDIR@}&}. As a convenience, +@code{&@{D@}&} is a synonym for @code{&@{CURDIR@}&}, and @code{&@{C@}&} +is a synonym for @code{&@{CANON_CURDIR@}&}. + +A special feature is that if the fragment is in the same directory as +the base @file{Makefile.am} (i.e., @code{&@{CURDIR@}&} is @code{.}), then +@code{&@{CURDIR@}&} and @code{&@{CANON_CURDIR@}&} will expand to the empty +string as well as eat, if present, a following slash or underscore +respectively. + +Thus, a makefile fragment might look like this: + +@example +bin_PROGRAMS += &@{CURDIR@}&/mumble +&@{CANON_CURDIR@}&_mumble_SOURCES = &@{CURDIR@}&/one.c +@end example + @node Conditionals @chapter Conditionals diff --git a/t/curdir.sh b/t/curdir.sh new file mode 100755 index 0000000..d222a52 --- /dev/null +++ b/t/curdir.sh @@ -0,0 +1,129 @@ +#! /bin/sh +# Copyright (C) 2013 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 2, 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 &{CURDIR}& and &{CANON_CURDIR}&. + +. test-init.sh + +cat >> configure.ac << 'END' +AC_PROG_CC +AM_PROG_CC_C_O +AC_CONFIG_FILES([zot/Makefile]) +AC_OUTPUT +END + +mkdir foo +mkdir foo/bar +mkdir foo/foobar +mkdir zot + +cat > Makefile.am << 'END' +AUTOMAKE_OPTIONS = subdir-objects +bin_PROGRAMS = +include $(top_srcdir)/foo/local.mk +include $(srcdir)/foo/foobar/local.mk +include local.mk +END + +cat > zot/Makefile.am << 'END' +AUTOMAKE_OPTIONS = subdir-objects +bin_PROGRAMS = +include $(top_srcdir)/zot/local.mk +include $(top_srcdir)/top.mk +include ../reltop.mk +END + +cat > local.mk << 'END' +&{CANON_CURDIR}&_whoami: + @echo "I am &{CURDIR}&/local.mk" + +bin_PROGRAMS += &{CURDIR}&/mumble +&{CANON_CURDIR}&_mumble_SOURCES = &{CURDIR}&/one.c +END + +cat > top.mk << 'END' +&{CANON_CURDIR}&_top_whoami: + @echo "I am &{CURDIR}&/top.mk" + +bin_PROGRAMS += &{D}&/scream +&{C}&_scream_SOURCES = &{D}&/two.c +END + +cat > reltop.mk << 'END' +&{C}&_reltop_whoami: + @echo "I am &{D}&/reltop.mk" + +bin_PROGRAMS += &{CURDIR}&/sigh +&{CANON_CURDIR}&_sigh_SOURCES = &{CURDIR}&/three.c +END + +cat > one.c << 'END' +int main(void) { return 0; } +END + +cp local.mk foo +cp local.mk foo/bar +cp local.mk foo/foobar +cp local.mk zot +echo "include &{CURDIR}&/bar/local.mk" >> foo/local.mk + +cp one.c foo +cp one.c foo/bar +cp one.c foo/foobar +cp one.c zot +cp one.c two.c +cp one.c three.c + +$ACLOCAL +$AUTOCONF +$AUTOMAKE -a +./configure + +$MAKE whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am local.mk" output +$MAKE foo_whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am foo/local.mk" output +$MAKE foo_bar_whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am foo/bar/local.mk" output +$MAKE foo_foobar_whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am foo/foobar/local.mk" output + +$MAKE +./mumble +foo/mumble +foo/bar/mumble +foo/foobar/mumble + +cd zot + +$MAKE ___top_whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am ../top.mk" output +$MAKE ___reltop_whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am ../reltop.mk" output +$MAKE whoami >output 2>&1 || { cat output; exit 1; } +cat output +grep "I am local.mk" output + +$MAKE +./mumble +../scream +../sigh diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk index 0acbdcf..16644ea 100644 --- a/t/list-of-tests.mk +++ b/t/list-of-tests.mk @@ -340,6 +340,7 @@ t/cscope.tap \ t/cscope2.sh \ t/cscope3.sh \ t/c-demo.sh \ +t/curdir.sh \ t/cxx.sh \ t/cxx2.sh \ t/cxxcpp.sh \ -- 1.8.1.1.473.g9a6c84e