[Top][All Lists]

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

Accounting for -rpath when libtool isn't helping

From: Paul \"LeoNerd\" Evans
Subject: Accounting for -rpath when libtool isn't helping
Date: Wed, 6 Feb 2019 13:21:34 +0000

Hi all,

A *slightly* offtopic question here but I'm hoping someone will be able
to offer some assistance.

First off, the all-libtool case for comparison. If I install some
libtool-based library, it drops some files in (for example)
$HOME/lib - these files primarily are the* collection of the
actual library, and the file that controls how libtool works.
Combined with pkg-config to set the linker flags to "-L$HOME/lib -lfoo"
if I then use libtool again somewhere else to compile a program using
that library, then it appears that the compiler is invoked with

  cc -L$HOME/lib -lfoo program.c

but something exciting and magical happens - libtool appends the rpath
argument. On my Linux box at least, what this turns into is

  cc -L$HOME/lib -lfoo program.c -Wl,-rpath -Wl,$HOME/lib

This then bakes the appropriate RUNPATH into the compiled program so
that it can find its library at runtime. All is good.

Nowthen - my actual question concerns what happens when I am not using
libtool to build my program. Such a case is common when building
C-level integration libraries for dynamic languages (Perl in my case).
I can't get libtool to directly build the code in question, because
Perl has its own build tooling. I can ask pkg-config what it thinks of
the --cflags and --libs to link against the library, but without
getting libtool involved in the magic step above, I don't get the
-rpath argument added.

So firstly, a question:

  Is there a way I can ask libtool to print what extra arguments it
  would have applied? Or failing that, to just print the full `cc`
  commandline and I can try to parse that back out?

Failing that as an option, I have instead taken to trying to
reïmplement that bit of logic, by trying to read through the ~12k line
shell script that is `libtool`, to see if I can work out what it does.
I think my summary is basically:

  * Collect up the -L$DIR arguments to form a search path

  * Collect up the -l$foo arguments to look for a lib$ file in
    the search path.
    For each .la file, add its containing directory to the eventual set
    of rpaths

  * Append those rpaths to the `cc` commandline

In order to assist my Perl build process, I've come up with the
following code, to try to recreate this magical step and allow things
to link properly. (Variously commented to try to explain the overall
approach to those unfamiliar with Perl):

   # the original commandline goes here
   my @extra_linker_flags = ... 

   my @system_libdirs = my @libdirs = qw( /lib /usr/lib );
   my @rpaths;

   FLAG: foreach my $flag ( @extra_linker_flags ) {
      # Match an -LDIR argument and parse the DIR part out of it
      if( $flag =~ m/^-L(.*)$/ ) {
         push @libdirs, $1;
         next FLAG;

      # Match an -lLIB argument and parse the LIB part out of it
      if( $flag =~ m/^-l(.*)$/ ) {
         my $lafile = "lib$";

         # Look for the first directory in @libdirs containing the $lafile
         my $libdir = first { -f "$_/$lafile" } @libdirs;

         # Skip if we didn't find the lafile
         defined $libdir or next FLAG;

         # Avoid already-known system directories and duplicates that
         # we've already collected
         $_ eq $libdir and next FLAG for @system_libdirs, @rpaths;

         print STDERR "Accumulated extra -rpath=$libdir\n";
         push @rpaths, $libdir;
         next FLAG;

   # Append the appropriate linker arguments for the new rpaths we found
   foreach my $rpath ( @rpaths ) {
      push @extra_linker_flags, "-Wl,-rpath", "-Wl,$rpath";

Does that overall logic feel about right? Is this the best thing to be
doing, or is there a different approach I ought to be taking?

Paul "LeoNerd" Evans

address@hidden      |  |

Attachment: pgpU6wunTJnzU.pgp
Description: OpenPGP digital signature

reply via email to

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