libtool
[Top][All Lists]
Advanced

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

Re: How to use --whole-archive ld arg with libtool?


From: Ralf Wildenhues
Subject: Re: How to use --whole-archive ld arg with libtool?
Date: Mon, 7 Aug 2006 18:07:16 +0200
User-agent: Mutt/1.5.11

Hello Reid,

* Reid Spencer wrote on Sat, Aug 05, 2006 at 06:22:02AM CEST:
> On Sat, 2006-08-05 at 02:25 +0200, Ralf Wildenhues wrote:
> > 
> >   If you control lib1 and lib2 though (i.e., they are built
> > as part of your package, or as part of a dependent package you are the
> > author of), you could make them convenience archives, to achieve the
> > same effect.
> 
> They are under my control, but it seems (from the documentation) that
> convenience archives aren't exactly what I want.  If I understand it
> correctly, convenience archives are simply archives with dependent
> library information attached. That's fine, but I'm not sure the
> resulting program will get "whole-archive" behavior. That is, I want
> every object from both lib1.a and lib2.a linked into the program
> (statically).

Ah, yes, I keep forgetting this...

> Are you telling me that when I link a program with
> libtool and one of the libraries linked with is a convenience library
> that all objects in that library will be linked into the program?

Nope.  My advice was wrong; sorry about that.

* Reid Spencer wrote on Sat, Aug 05, 2006 at 06:31:20AM CEST:
> On Sat, 2006-08-05 at 02:30 +0200, Ralf Wildenhues wrote:
> > I forgot the main part of the answer, sorry.  You wrote:
> > >> The reason I need this capability is to ensure that all the symbols from
> > >> lib1 and lib2 are available to any dlopen'd modules that get loaded by
> > >> "myprog".
> > 
> > The _portable_ way to ensure this is to link each of the modules against
> > the libraries they need.  Period.
> 
> I assume by module you mean a shared library that will be dlopened and
> dlsymed by some program. If so, couldn't that lead to runtime link
> errors?

No, I don't think so.  At least not in the usual case.

> This is actually the problem we're trying to fix!  Let me be
> clear about our situation:
> 
> Suppose we have a library, foo, that defines exported symbols X and Y.
> We also have a program bar that uses symbol X but not symbol Y.
> Finally, we have a "module" (shared object), barmod, which uses both X
> and Y.  If I link both bar and barmod against foo, they will conflict on
> the definition of X. That is, bar linked in X from foo and barmod linked
> in X from foo. When barmod is loaded at runtime, we get "duplicate
> defined" error.  

OK.  Here's a stripped-down case that tries to replicate your situation.
It does not fail for me, and I think it's portable (to non-w32 hosts
that support dlopen(); I did not use libltdl in this case; and I did
use one internal detail by referring to lt_cv_dlopen_libs).

Could you change it in a way so that it exposes the issue you are
seeing (or show how you can make it fail)?  Thanks.

I found an unrelated error, by the way (in a followup mail).

Cheers,
Ralf

cat >configure.ac <<EOF
AC_INIT(dup,1,devnull)
AM_INIT_AUTOMAKE(foreign)
AC_PROG_CC
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_SUBST([LIBDL], [$lt_cv_dlopen_libs])
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
EOF

cat >Makefile.am <<EOF
lib_LTLIBRARIES = libfoo.la
bin_PROGRAMS = bar
bar_LDADD = libfoo.la $(LIBDL)
bar_LDFLAGS = "-dlopen" barmod.la
pkglib_LTLIBRARIES = barmod.la
barmod_la_LDFLAGS = -module
barmod_la_LIBADD = libfoo.la
EOF

cat >bar.c <<EOF
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

extern int X (void);

int main (int argc, char **argv)
{
  void *handle;
  int (*barmod)(void);
  char *error;

  handle = dlopen ("barmod.so", RTLD_LAZY);
  if (!handle) {
    fprintf (stderr, "%s\n", dlerror ());
    exit(EXIT_FAILURE);
  }

  *(void **) (&barmod) = dlsym (handle, "barmod");
  if ((error = dlerror()) != NULL)  {
    fprintf (stderr, "%s\n", error);
    exit (EXIT_FAILURE);
  }

  printf ("%d\n", (*barmod) ());
  dlclose (handle);
  return X () - 2;
}
EOF

cat >barmod.c <<EOF
extern int X (void);
extern double Y (void);

int barmod (void)
{
  return X () + 2 * Y ();
}
EOF

cat >libfoo.c <<EOF
int X (void) { return 2; }
double Y (void) { return 3.14; }
EOF

libtoolize -c
autoreconf -v -i
./configure
make
./libtool --mode=execute -dlopen barmod.la ./bar; echo $?
# should print 8 and 0.




reply via email to

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