>From b32d5197ac8f6c97750a22990995c98240c4cadb Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Sun, 27 Jan 2013 00:48:28 +0100 Subject: [PATCH] curdir: add support for relative names in included fragments 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 --- 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 7a25b80..3a2d8e7 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,16 @@ New in 1.14: over the same-named automake-provided macro, as defined in file '/usr/local/share/aclocal-1.14/vala.m4'. +* 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 + * Obsolescent features flagged: - Use of the special makefile variable 'ACLOCAL_AMFLAGS' is deprecated. diff --git a/automake.in b/automake.in index 4776581..f31a4ba 100644 --- a/automake.in +++ b/automake.in @@ -6302,15 +6302,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"; @@ -6395,6 +6395,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. @@ -6556,8 +6568,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 @@ -6630,7 +6644,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 263e0cc..43b3542 100644 --- a/doc/automake.texi +++ b/doc/automake.texi @@ -10500,6 +10500,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{&@address@hidden&} is replaced with the +directory of the fragment relative to the base @file{Makefile.am}. +Similarly, @code{&@address@hidden&} is replaced with the canonicalized +(@pxref{Canonicalization}) form of @code{&@address@hidden&}. As a convenience, address@hidden&@address@hidden&} is a synonym for @code{&@address@hidden&}, and @code{&@address@hidden&} +is a synonym for @code{&@address@hidden&}. + +A special feature is that if the fragment is in the same directory as +the base @file{Makefile.am} (i.e., @code{&@address@hidden&} is @code{.}), then address@hidden&@address@hidden&} and @code{&@address@hidden&} 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: + address@hidden +bin_PROGRAMS += &@address@hidden&/mumble +&@address@hidden&_mumble_SOURCES = &@address@hidden&/one.c address@hidden 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 . + +# 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 af78211..cc8d808 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.7.9