automake-patches
[Top][All Lists]
Advanced

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

FYI: Fix PR/285: ltlibraries conditionally installed in different dirs


From: Alexandre Duret-Lutz
Subject: FYI: Fix PR/285: ltlibraries conditionally installed in different dirs
Date: Sun, 07 Mar 2004 13:36:39 +0100
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux)

I'm installing this on HEAD and closing the PR.

2004-03-07  Alexandre Duret-Lutz  <address@hidden>

        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.

Index: NEWS
===================================================================
RCS file: /cvs/automake/automake/NEWS,v
retrieving revision 1.263
diff -u -r1.263 NEWS
--- NEWS        1 Feb 2004 12:54:01 -0000       1.263
+++ NEWS        7 Mar 2004 12:34:43 -0000
@@ -19,6 +19,16 @@
 
 * 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 = ...
+
 
 New in 1.8:
 
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1545
diff -u -r1.1545 automake.in
--- automake.in 7 Mar 2004 09:24:21 -0000       1.1545
+++ automake.in 7 Mar 2004 12:34:46 -0000
@@ -2386,7 +2386,6 @@
                                 'noinst', 'lib', 'pkglib', 'check');
   return if ! @liblist;
 
-  my %instdirs;
   my @prefix = am_primary_prefixes ('LTLIBRARIES', 0, 'lib', 'pkglib',
                                    'noinst', 'check');
 
@@ -2396,6 +2395,8 @@
       $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 @@
       # 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 @@
          $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: lib/Automake/DisjConditions.pm
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/DisjConditions.pm,v
retrieving revision 1.10
diff -u -r1.10 DisjConditions.pm
--- lib/Automake/DisjConditions.pm      12 Aug 2003 23:32:59 -0000      1.10
+++ lib/Automake/DisjConditions.pm      7 Mar 2004 12:34:47 -0000
@@ -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 @@
   #   "(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;
@@ -286,6 +289,23 @@
     }
   $self->{'human'} = $res;
   return $res;
+}
+
+
+=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
address@hidden<Condition>s or C<DisjConditions>.
+
+=cut
+
+sub merge ($@)
+{
+  my ($self, @otherconds) = @_;
+  new Automake::DisjConditions (
+    map { $_->isa ("Automake::DisjConditions") ? $_->conds : $_ }
+        ($self, @otherconds));
 }
 
 
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.550
diff -u -r1.550 Makefile.am
--- tests/Makefile.am   29 Feb 2004 19:10:21 -0000      1.550
+++ tests/Makefile.am   7 Mar 2004 12:34:49 -0000
@@ -283,6 +283,7 @@
 libtool5.test \
 libtool6.test \
 libtool7.test \
+libtool8.test \
 license.test \
 link_c_cxx.test        \
 link_dist.test \
Index: tests/libtool6.test
===================================================================
RCS file: /cvs/automake/automake/tests/libtool6.test,v
retrieving revision 1.4
diff -u -r1.4 libtool6.test
--- tests/libtool6.test 6 Sep 2003 05:36:57 -0000       1.4
+++ tests/libtool6.test 7 Mar 2004 12:34:49 -0000
@@ -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 @@
 
 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`
Index: tests/libtool8.test
===================================================================
RCS file: tests/libtool8.test
diff -N tests/libtool8.test
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/libtool8.test 7 Mar 2004 12:34:49 -0000
@@ -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

-- 
Alexandre Duret-Lutz





reply via email to

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