]> git.ipfire.org Git - thirdparty/automake.git/commitdiff
Fix for PR automake/285:
authorAlexandre Duret-Lutz <adl@gnu.org>
Sun, 7 Mar 2004 12:36:54 +0000 (12:36 +0000)
committerAlexandre Duret-Lutz <adl@gnu.org>
Sun, 7 Mar 2004 12:36:54 +0000 (12:36 +0000)
* automake.in (handle_ltlibraries): Keep track of installation
directories for each condition, then define a $(am_TARGET_rpath)
variable to hold the -rpath flags of Libtool libraries conditionally
installed in different directories.
* lib/Automake/DisjConditions.pm (merge): New function.
* tests/libtool6.test: Adjust.
* tests/libtool8.test: New file.
* tests/Makefile.am (TEST): Add libtool8.test.

ChangeLog
NEWS
automake.in
lib/Automake/DisjConditions.pm
tests/Makefile.am
tests/Makefile.in
tests/libtool6.test
tests/libtool8.test [new file with mode: 0755]

index abe5e293ca10123697264cb544baeb95a1134c66..930808b35c427b68a036e8765d05574c5e14c59d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2004-03-07  Alexandre Duret-Lutz  <adl@gnu.org>
 
+       Fix for PR automake/285:
+       * automake.in (handle_ltlibraries): Keep track of installation
+       directories for each condition, then define a $(am_TARGET_rpath)
+       variable to hold the -rpath flags of Libtool libraries conditionally
+       installed in different directories.
+       * lib/Automake/DisjConditions.pm (merge): New function.
+       * tests/libtool6.test: Adjust.
+       * tests/libtool8.test: New file.
+       * tests/Makefile.am (TEST): Add libtool8.test.
+
        * lib/Automake/Variable.pm (traverse_recursively,
        _do_recursive_traversal): Honor the skip_ac_subst option.
        * automake.in (handle_dist): Use skip_ac_subst.
diff --git a/NEWS b/NEWS
index e90e9a44d21e7641b1b5f2ae2f0ab529f849ee9a..7e9156c19edebdb3e6a8b663ca57c6e370a9f46a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,16 @@ New in 1.8a:
 
 * Support for conditional _LISP.
 
+* Automake is now able to handle setups where a libtool library is
+  conditionally installed in different directories, as in
+
+    if COND
+      lib_LTLIBRARIES = liba.la
+    else
+      pkglib_LTLIBRARIES = liba.la
+    endif
+    liba_la_SOURCES = ...
+
 \f
 New in 1.8:
 
index bd23301273209bc550bdd99eb7409996ea4b149f..c7f59c3bf0717ea5b6f5fbbbab8a8fb5d5b0b9b7 100755 (executable)
@@ -2386,7 +2386,6 @@ sub handle_ltlibraries
                                 'noinst', 'lib', 'pkglib', 'check');
   return if ! @liblist;
 
-  my %instdirs;
   my @prefix = am_primary_prefixes ('LTLIBRARIES', 0, 'lib', 'pkglib',
                                    'noinst', 'check');
 
@@ -2396,6 +2395,8 @@ sub handle_ltlibraries
       $var->requires_variables ('Libtool library used', 'LIBTOOL');
     }
 
+  my %instdirs = ();
+  my %instconds = ();
   my %liblocations = ();       # Location (in Makefile.am) of each library.
 
   foreach my $key (@prefix)
@@ -2403,39 +2404,66 @@ sub handle_ltlibraries
       # Get the installation directory of each library.
       (my $dir = $key) =~ s/^nobase_//;
       my $var = rvar ($key . '_LTLIBRARIES');
-      for my $pair ($var->value_as_list_recursive (location => 1))
-       {
-         my ($where, $lib) = @$pair;
-         # We reject libraries which are installed in several places,
-         # because we don't handle this in the rules (think `-rpath').
-         #
-         # However, we allow the same library to be listed many times
-         # for the same directory.  This is for users who need setups
-         # like
-         #   if COND1
-         #     lib_LTLIBRARIES = libfoo.la
-         #   endif
-         #   if COND2
-         #     lib_LTLIBRARIES = libfoo.la
-         #   endif
-         #
-         # Actually this will also allow
-         #   lib_LTLIBRARIES = libfoo.la libfoo.la
-         # Diagnosing this case doesn't seem worth the plain (we'd
-         # have to fill $instdirs on a per-condition basis, check
-         # implied conditions, etc.)
-         if (defined $instdirs{$lib} && $instdirs{$lib} ne $dir)
-           {
-             error ($where, "`$lib' is already going to be installed in "
-                    . "`$instdirs{$lib}'", partial => 1);
-             error ($liblocations{$lib}, "`$lib' previously declared here");
-           }
-         else
-           {
-             $instdirs{$lib} = $dir;
-             $liblocations{$lib} = $where->clone;
-           }
-       }
+
+      # We reject libraries which are installed in several places
+      # in the same condition, because we can only specify one
+      # `-rpath' option.
+      $var->traverse_recursively
+       (sub
+        {
+          my ($var, $val, $cond, $full_cond) = @_;
+          my $hcond = $full_cond->human;
+          my $where = $var->rdef ($cond)->location;
+          # A library cannot be installed in different directory
+          # in overlapping conditions.
+          if (exists $instconds{$val})
+            {
+              my ($msg, $acond) =
+                $instconds{$val}->ambiguous_p ($val, $full_cond);
+
+              if ($msg)
+                {
+                  error ($where, $msg, partial => 1);
+
+                  my $dirtxt = "installed in `$dir'";
+                  $dirtxt = "built for `$dir'"
+                    if $dir eq 'EXTRA' || $dir eq 'noinst' || $dir eq 'check';
+                  my $dircond =
+                    $full_cond->true ? "" : " in condition $hcond";
+
+                  error ($where, "`$val' should be $dirtxt$dircond ...",
+                         partial => 1);
+
+                  my $hacond = $acond->human;
+                  my $adir = $instdirs{$val}{$acond};
+                  my $adirtxt = "installed in `$adir'";
+                  $adirtxt = "built for `$adir'"
+                    if ($adir eq 'EXTRA' || $adir eq 'noinst'
+                        || $adir eq 'check');
+                  my $adircond = $acond->true ? "" : " in condition $hacond";
+
+                  my $onlyone = ($dir ne $adir) ?
+                    ("\nLibtool libraries can be built for only one "
+                     . "destination.") : "";
+
+                  error ($liblocations{$val}{$acond},
+                         "... and should also be $adirtxt$adircond.$onlyone");
+                  return;
+                }
+            }
+          else
+            {
+              $instconds{$val} = new Automake::DisjConditions;
+            }
+          $instdirs{$val}{$full_cond} = $dir;
+          $liblocations{$val}{$full_cond} = $where;
+          $instconds{$val} = $instconds{$val}->merge ($full_cond);
+        },
+        sub
+        {
+          return ();
+        },
+         skip_ac_subst => 1);
     }
 
   foreach my $pair (@liblist)
@@ -2505,21 +2533,36 @@ sub handle_ltlibraries
          $xlink = $linker ? $linker : 'LINK';
        }
 
-      my $rpath;
-      if ($instdirs{$onelib} eq 'EXTRA'
-         || $instdirs{$onelib} eq 'noinst'
-         || $instdirs{$onelib} eq 'check')
-       {
-         # It's an EXTRA_ library, so we can't specify -rpath,
-         # because we don't know where the library will end up.
-         # The user probably knows, but generally speaking automake
-         # doesn't -- and in fact configure could decide
-         # dynamically between two different locations.
-         $rpath = '';
-       }
-      else
-       {
-         $rpath = ('-rpath $(' . $instdirs{$onelib} . 'dir)');
+      my $rpathvar = "am_${xlib}_rpath";
+      my $rpath = "\$($rpathvar)";
+      foreach my $rcond ($instconds{$onelib}->conds)
+        {
+         my $val;
+         if ($instdirs{$onelib}{$rcond} eq 'EXTRA'
+             || $instdirs{$onelib}{$rcond} eq 'noinst'
+             || $instdirs{$onelib}{$rcond} eq 'check')
+           {
+             # It's an EXTRA_ library, so we can't specify -rpath,
+             # because we don't know where the library will end up.
+             # The user probably knows, but generally speaking automake
+             # doesn't -- and in fact configure could decide
+             # dynamically between two different locations.
+             $val = '';
+           }
+         else
+           {
+             $val = ('-rpath $(' . $instdirs{$onelib}{$rcond} . 'dir)');
+           }
+         if ($rcond->true)
+           {
+             # If $rcond is true there is only one condition and
+             # there is no point defining an helper variable.
+             $rpath = $val;
+           }
+         else
+           {
+             define_pretty_variable ($rpathvar, $rcond, INTERNAL, $val);
+           }
        }
 
       # If the resulting library lies into a subdirectory,
index 9204b76bf31cc51d5eccfa5ddcecbe3ef063dd57..45745c4afbda9aec2f2ccd0ae9f93aa022b014fe 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 2001, 2002, 2003  Free Software Foundation, Inc.
+# Copyright (C) 1997, 2001, 2002, 2003, 2004  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
@@ -61,6 +61,9 @@ Automake::DisjConditions - record a disjunction of Conditions
   #   "(COND1 and !COND2) or (!COND3)"
   my $str = $set->human;
 
+  # Merge (OR) several DisjConditions.
+  my $all = $set->merge($set2, $set3, ...)
+
   # Invert a DisjConditions, i.e., create a new DisjConditions
   # that complements $set.
   my $inv = $set->invert;
@@ -289,6 +292,23 @@ sub human ($ )
 }
 
 
+=item C<$newcond = $cond-E<gt>merge (@otherconds)>
+
+Return a new C<DisjConditions> which is the disjunction of
+C<$cond> and C<@otherconds>.  Items in C<@otherconds> can be
+@C<Condition>s or C<DisjConditions>.
+
+=cut
+
+sub merge ($@)
+{
+  my ($self, @otherconds) = @_;
+  new Automake::DisjConditions (
+    map { $_->isa ("Automake::DisjConditions") ? $_->conds : $_ }
+        ($self, @otherconds));
+}
+
+
 =item C<$prod = $set1-E<gt>multiply ($set2)>
 
 Multiply two conditional sets.
index a1333479ce9522d59870f7e8468f8bec1c0c0f1f..67adfad7b6e27f97a608d48f2ce8692602b4c095 100644 (file)
@@ -283,6 +283,7 @@ libtool4.test \
 libtool5.test \
 libtool6.test \
 libtool7.test \
+libtool8.test \
 license.test \
 link_c_cxx.test        \
 link_dist.test \
index 8b808575f5e6523afa0d49fef2224e5d2f693151..5ae0e5e8b8f9fc4a3817b2cabc80edce0c99f571 100644 (file)
@@ -398,6 +398,7 @@ libtool4.test \
 libtool5.test \
 libtool6.test \
 libtool7.test \
+libtool8.test \
 license.test \
 link_c_cxx.test        \
 link_dist.test \
index fc18d7c1fbe00478316d68879643a54e4a10a76c..bc190a944ab97c9efaf32eb86d4b5289f2db905a 100755 (executable)
@@ -1,5 +1,5 @@
 #!/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.
 #
@@ -18,8 +18,8 @@
 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 # Boston, MA 02111-1307, USA.
 
-# Make sure it's not ok to install a library under different conditions
-# in different directories.
+# Make sure it's OK to install a library under different conditions
+# in different directories.  PR/285.
 
 required='libtoolize'
 . ./defs || exit 1
@@ -45,7 +45,6 @@ END
 
 libtoolize
 $ACLOCAL
-AUTOMAKE_fails
-grep 'liba\.la.* installed .*lib' stderr
-grep 'Makefile.am:5:' stderr
-grep 'Makefile.am:2:' stderr
+$AUTOMAKE --add-missing
+# am_liba_la_rpath is defined twice, and used once
+test 3 = `grep 'am_liba_la_rpath' Makefile.in | wc -l`
diff --git a/tests/libtool8.test b/tests/libtool8.test
new file mode 100755 (executable)
index 0000000..18b1d18
--- /dev/null
@@ -0,0 +1,56 @@
+#!/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 Automake diagnoses conflicting installations.
+
+required='libtoolize'
+. ./defs || exit 1
+
+set -e
+
+cat >>configure.in <<'END'
+AM_CONDITIONAL([COND1], [true])
+AM_CONDITIONAL([COND2], [false])
+AC_PROG_CC
+AC_PROG_LIBTOOL
+AC_OUTPUT
+END
+
+cat >Makefile.am <<'END'
+if COND1
+  lib_LTLIBRARIES = liba.la
+  EXTRA_LTLIBRARIES = libc.la libc.la libb.la
+else
+  lib_LTLIBRARIES = libb.la
+endif
+if COND2
+if COND1
+    pkglib_LTLIBRARIES = liba.la
+endif
+endif
+END
+
+libtoolize
+$ACLOCAL
+AUTOMAKE_fails --add-missing
+grep libb stderr && exit 1
+grep 'Makefile.am:3:.*libc.la.*multiply defined' stderr
+grep 'Makefile.am:9:.*`pkglib' stderr
+grep 'Makefile.am:2:.*`lib' stderr