[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: Fix PR/285: ltlibraries conditionally installed in different dirs,
Alexandre Duret-Lutz <=