Re: Stop relink searching host directory when installation prefix provided

2011-01-19 Thread Martin Panter
On 16 January 2011 17:13, Ralf Wildenhues ralf.wildenh...@gmx.de wrote:
 I haven't looked into this in detail yet, but thanks for the good
 writeup and the many references.  We need testsuite exposure for
 this.

Hello again

I've made a test case for my issue (attached patch file). It fails
with current Libtool and if you remove the XFAIL line it passes with
my solution applied. I'm just guessing the syntax etc based on the
other tests, so I wouldn't say it's perfect, but hopefully you can see
what I'm trying to do from the comments.

When I ran all the tests with make -k check there are no issues with
the rest of the tests, with or without my patch.

I understand this relinking (at least on Linux) is only needed to
remove hard-coded build directory paths to library dependencies that
Libtool stores during the initial link, which are only put there as a
convenience before things are properly installed. So perhaps a less
controversial solution or workaround to my problem would be an easy
way to disable these convenient build paths and thus the relinking
completely? But I still don't see a problem with my original solution.

-Martin
Index: libtool-2.4+host-relink/tests/destdir.at
===
--- libtool-2.4+host-relink.orig/tests/destdir.at
+++ libtool-2.4+host-relink/tests/destdir.at
@@ -139,4 +139,54 @@ fi
 
 AT_CLEANUP
 
+
+AT_SETUP([Not relinking against host library])
+AT_KEYWORDS([libtool])
+
+_LT_DIRSETUP
+trickydir=$(pwd)/trickydir
+rm -rf $trickydir
+$mkdir_p $trickydir
+cd src
+
+# Create real libtricky and install directly into $trickydir
+echo int tricky() { return 0; }  tricky.c
+$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c tricky.c
+$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o libtricky.la tricky.lo -rpath 
$trickydir
+$LIBTOOL --mode=install cp libtricky.la $trickydir/libtricky.la
+$LIBTOOL --mode=clean rm -f libtricky.la
+
+# Create libdep, to be eventually installed into target's /$prefix, that
+# depends on libtricky
+echo extern int tricky(); int dep() { return tricky(); }  dep.c
+$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c -o dep.lo dep.c
+$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -L$trickydir -ltricky -o libdep.la 
-rpath $prefix dep.lo
+
+# Create libtest, to also be eventually installed into target's /$prefix,
+# that depends on libdep
+echo extern int tricky(), dep(); int test() { return dep() + tricky(); }  
test.c
+$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c -o test.lo test.c
+$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS libdep.la -o libtest.la -rpath 
$prefix test.lo
+
+# Install libdep into $DESTDIR/$prefix
+$LIBTOOL --mode=install cp libdep.la $DESTDIR$prefix
+
+# Create false libtricky and install directly into host's /$prefix
+# Not sure of a perfectly portable way of doing this; currently using an
+# empty lib.so file. With GCC this fails for me with the message
+#   libtricky.so: file not recognized: File truncated
+:  $prefix/libtricky.so
+
+# Install libtest to trigger a relink. Relink command should be like
+#   $CC -o libtest.so test.o -L$DESTDIR$prefix -ldep -L$trickydir -ltricky
+# not like
+#   $CC -o libtest.so test.o -L$DESTDIR$prefix -L$prefix -ldep 
-L$trickydir -ltricky
+# Verify that the relink succeeds and it didn't search $prefix or find the
+# false libtricky there
+AT_XFAIL_IF([true])
+AT_CHECK([$LIBTOOL --mode=install cp libtest.la $DESTDIR$prefix],
+  [0], [ignore], [ignore])
+
+AT_CLEANUP
+
 m4_popdef([_LT_DIRSETUP])


Re: Stop relink searching host directory when installation prefix provided

2011-01-17 Thread Martin Panter
On 16 January 2011 17:13, Ralf Wildenhues ralf.wildenh...@gmx.de wrote:
 Hello Martin,

 * Martin Panter wrote on Sun, Jan 16, 2011 at 01:04:00PM CET:
 Don't search host directory during relink if $inst_prefix is provided

 --- libtool-2.4.orig/libltdl/config/ltmain.m4sh
 +++ libtool-2.4/libltdl/config/ltmain.m4sh
 @@ -6122,12 +6122,14 @@ func_mode_link ()
 fi
   else
 # We cannot seem to hardcode it, guess we'll fake it.
 -   add_dir=-L$libdir
 -   # Try looking first in the location we're being installed to.
 +
 +   # Default if $libdir is not relative to the prefix:
 +   add_dir=-L$libdir
 +
 if test -n $inst_prefix_dir; then
   case $libdir in
 [\\/]*)
 - func_append add_dir  -L$inst_prefix_dir$libdir
 + add_dir=-L$inst_prefix_dir$libdir
   ;;
   esac
 fi

 Wouldn't it also suffice to just prepend instead of append
 -L$inst_prefix_dir$libdir?  If no, why not?

I did some experimenting cross-compiling with Open embedded's
gettext-0.18-r4 package using angstrom-2008.1 distro.

With original Libtool and all relevant patches not present: (I
abbreviated the output to make it more readable)
| arm-angstrom-linux-gnueabi-libtool: relink:
arm-angstrom-linux-gnueabi-gcc . . . [*.o] . . . -L/. .
./image/usr/lib -L/usr/lib -lgettextlib -L/. .
./armv7a-angstrom-linux-gnueabi/usr/lib -lncurses -lc . . . -o
.libs/libgettextsrc-0.18.so
| /usr/lib/libncursesw.so: file not recognized: File format not recognized

With both $add_dir -L options, but swapped around as Ralf suggested:
| arm-angstrom-linux-gnueabi-libtool: relink:
arm-angstrom-linux-gnueabi-gcc . . . [*.o] . . . -L/usr/lib -L/. .
./image/usr/lib -lgettextlib -L/. .
./armv7a-angstrom-linux-gnueabi/usr/lib -lncurses -lc . . . -o
.libs/libgettextsrc-0.18.so
| /usr/lib/libgettextlib.so: file not recognized: File format not recognized

Now that I've done the experiment I vaguely remember seeing code
inside Libtool that reversed the order of all those $add_dir -L
options, just after the part identified in my patch. That would
explain what happened here, so I think the current unpatched situation
is already doing what Ralf intended.

Just for kicks, with my patch applied for only one $add_dir -L option,
a successful relink looks like:
arm-angstrom-linux-gnueabi-libtool: relink:
arm-angstrom-linux-gnueabi-gcc . . . [*.o] . . . -L/. .
./image/usr/lib -lgettextlib -L/. .
./armv7a-angstrom-linux-gnueabi/usr/lib -lncurses -lc . . . -o
.libs/libgettextsrc-0.18.so

 Asking because I'm fairly sure not everybody uses DESTDIR for cross
 compilation and assumes that the target directory is no-go land for
 us.  (I for one often do 'make install DESTDIR=/tmp/dest' merely to
 tar up the installation tree to be scp'ed to another machine where
 the NFS share is mounted rw.)

I hadn't really considered that some people would expect to implicitly
link against libraries found in the $libdir directory. I'd tend to
argue that you should have to explicitly specify a -L$libdir option
if you really want to link against libraries from there. (It seems
$libdir comes straight from the target .la file?) But I'm not an
expert on how to use Libtool and maybe common usage or other people
would disagree with me.

I also tried natively (Arch Linux) compiling gettext 0.18. Original
Libtool behaviour installing into staging directory:
libtool: relink: gcc . . . [*.o] . . . -L/. . ./stage/usr/local/lib
-L/usr/local/lib -lgettextlib -lacl -lcroco-0.6 -lglib-2.0 -lxml2
-lncurses -lc . . . -o .libs/libgettextsrc-0.18.so

I would argue that it shouldn't search the OS's /usr/local/lib for any
of the dependencies even though the target library is supposed to
eventually exist there. If any of the target's dependencies did exist
in /usr/local/lib, I'd expect I'd have to provide that directory to
the configure script or linker. In my gettext case, the initial link
doesn't search any usr/local/lib directory at all, and the gettextlib
dependency is already installed into the staging directory before the
above relink happens.

With my proposed patch:
libtool: relink: gcc . . . [*.o] . . . -L/. . ./stage/usr/local/lib
-lgettextlib -lacl -lcroco-0.6 -lglib-2.0 -lxml2 -lncurses -lc . . .
-o .libs/libgettextsrc-0.18.so

On 16 January 2011 17:23, Charles Wilson libt...@cwilson.fastmail.fm wrote:
 Actually, Ralf's example (or one very similar to it) is the *primary*
 use of DESTDIR.  It's how many packaging tools -- like rpm, or cygport
 on cygwin -- create installable binary packages.

Agreed, that example already tends to work with unmodified Libtool. I
want to get cross-compiled installable binary packages working as
well.

-Martin



Re: Stop relink searching host directory when installation prefix provided

2011-01-17 Thread Charles Wilson
On 1/17/2011 8:23 AM, Martin Panter wrote:
 On 16 January 2011 17:23, Charles Wilson wrote:
 Actually, Ralf's example (or one very similar to it) is the *primary*
 use of DESTDIR.  It's how many packaging tools -- like rpm, or cygport
 on cygwin -- create installable binary packages.
 
 Agreed, that example already tends to work with unmodified Libtool. I
 want to get cross-compiled installable binary packages working as
 well.

Right, but if you remove the $DESTDIR/$libdir from the relink command,
then you'd break these native builds (because, e.g. /usr/lib is still in
the compiler's default search path).

For instance, suppose you're building gettext: it installs several so's
(with interesting dependencies between them) AND a bunch of executables
that depend on THOSE so's.  If you use $DESTDIR, and need to relink, but
don't include $DESTDIR/$libdir in the -L spec, then you'd relink the
executables (and so's with internal dependencies) against the versions
installed by gettext-$OLDVER in /usr/lib.

If the new apps depend on any added/new interfaces...boom.

--
Chuck




Re: Stop relink searching host directory when installation prefix provided

2011-01-17 Thread Martin Panter
Hi Charles

On 18 January 2011 02:38, Charles Wilson libt...@cwilson.fastmail.fm wrote:
 Right, but if you remove the $DESTDIR/$libdir from the relink command,
 then you'd break these native builds (because, e.g. /usr/lib is still in
 the compiler's default search path).

 For instance, suppose you're building gettext: it installs several so's
 (with interesting dependencies between them) AND a bunch of executables
 that depend on THOSE so's.  If you use $DESTDIR, and need to relink, but
 don't include $DESTDIR/$libdir in the -L spec, then you'd relink the
 executables (and so's with internal dependencies) against the versions
 installed by gettext-$OLDVER in /usr/lib.

I'm not trying to remove the $DESTDIR/$libdir reference; I'm trying to
remove the OS's /$libdir reference. Compare these relink commands,
adapted from previous email:

Current behaviour:
gcc *.o -L$DESTDIR/$libdir -L/$libdir -lgettextlib . . . -o
.libs/libgettextsrc-0.18.so

With my change:
gcc *.o -L$DESTDIR/$libdir -lgettextlib . . . -o .libs/libgettextsrc-0.18.so

The current behaviour already means it would find the newer gettextlib
dependency (because it gets installed in $DESTDIR/$libdir before
gettextsrc does). If anything I think my change would make it less
likely to find the old version of gettextlib. Hope we are
understanding each other :)

 If the new apps depend on any added/new interfaces...boom.

It sounds like you're describing something like what's going on in
this report, thought I haven't quite figured out how it happens:

Relink with a DESTDIR install mistakenly links against old installed
libraries rather than those in DESTDIR
http://savannah.gnu.org/support/?107416

-Martin



Re: Stop relink searching host directory when installation prefix provided

2011-01-16 Thread Ralf Wildenhues
Hello Martin,

* Martin Panter wrote on Sun, Jan 16, 2011 at 01:04:00PM CET:
 Don't search host directory during relink if $inst_prefix is provided

 --- libtool-2.4.orig/libltdl/config/ltmain.m4sh
 +++ libtool-2.4/libltdl/config/ltmain.m4sh
 @@ -6122,12 +6122,14 @@ func_mode_link ()
 fi
   else
 # We cannot seem to hardcode it, guess we'll fake it.
 -   add_dir=-L$libdir
 -   # Try looking first in the location we're being installed to.
 +   
 +   # Default if $libdir is not relative to the prefix:
 +   add_dir=-L$libdir
 +   
 if test -n $inst_prefix_dir; then
   case $libdir in
 [\\/]*)
 - func_append add_dir  -L$inst_prefix_dir$libdir
 + add_dir=-L$inst_prefix_dir$libdir
   ;;
   esac
 fi

Wouldn't it also suffice to just prepend instead of append
-L$inst_prefix_dir$libdir?  If no, why not?

Asking because I'm fairly sure not everybody uses DESTDIR for cross
compilation and assumes that the target directory is no-go land for
us.  (I for one often do 'make install DESTDIR=/tmp/dest' merely to
tar up the installation tree to be scp'ed to another machine where
the NFS share is mounted rw.)

I haven't looked into this in detail yet, but thanks for the good
writeup and the many references.  We need testsuite exposure for
this.

Cheers,
Ralf



Re: Stop relink searching host directory when installation prefix provided

2011-01-16 Thread Charles Wilson
On 1/16/2011 12:13 PM, Ralf Wildenhues wrote:
 (I for one often do 'make install DESTDIR=/tmp/dest' merely to
 tar up the installation tree to be scp'ed to another machine where
 the NFS share is mounted rw.)

Actually, Ralf's example (or one very similar to it) is the *primary*
use of DESTDIR.  It's how many packaging tools -- like rpm, or cygport
on cygwin -- create installable binary packages.

--
Chuck