[Top][All Lists]
[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.