automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/6] preproc: add support for relative names in included fragment


From: Stefano Lattarini
Subject: [PATCH 1/6] preproc: add support for relative names in included fragments
Date: Sun, 3 Feb 2013 21:44:39 +0100

From: Peter Rosin <address@hidden>

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 <address@hidden>
Signed-off-by: Stefano Lattarini <address@hidden>
---
 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{&@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 <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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]