Dan Harkless wrote:
> Drazen Kacar <[EMAIL PROTECTED]> writes:
> > Dan Harkless wrote:
> > > Drazen Kacar <[EMAIL PROTECTED]> writes:
> > > > I think developers tend to use libtool because they would very much
> > > > like to believe that it solves linking problems.
> > >
> > > And they believe that because in almost all cases, it's true.
> >
> > On a number of platforms libtool doesn't link the libraries in the way
> > that platform documentation recommends.
>
> What platforms?
SYSV-ish mostly. I think we both have access to Solaris, so we could use
it as a test case. And it has a good documentation, so there can be no
dispute as to what actually platform documentation says.
> What does libtool do wrong? When you say "link the
> libraries", I assume you're talking about building libraries, not linking to
> them?
Mostly. There are very few source packages which use libtool, although
they don't try to build any library, so I wasn't very concerned with
those. Libtool will probably still do one or two things wrong (or against
user's wishes), but that's easy to fix. If you're a shared library expert
and don't mind editing sh scripts.
> If so, I'm not too concerned, since Wget doesn't build any libraries.
I'm concerned about something else. You're promoting libtool usage. I can
prove that it doesn't work correctly on some platforms which it allegedly
supports (according to libtool documentation). If many people say many
times that libtool solves linking problems, that won't become true just
because they are saying it so often. But the observable effect is that
many other developers will never look into linking issues, just because they
think that there is this magic tool which can do it for them.
> > > > In my experience it just takes control from the user
> > >
> > > What control does it take away?
> >
> > When linking libraries it ignores LDFLAGS.
>
> Eh? It doesn't know anything about LDFLAGS -- that's a Makefile concept.
That is my only interface to libtool. Either through configure script or
through the make command.
> Are you saying it throws away any options you give it (which happened to
> come from the Makefile's LDFLAGS variable)? Sounds unlikely...
Yes. Try "LDFLAGS=-R/blah ./configure" with a source that uses libtool to
build some library and watch if -R is still there when it's linking the
library. It will be preserved when linking binaries, though.
> > On SYSV-ish platforms, it picks
> > the wrong linker by default (this might depend on the compiler you're
> > using, but since the correct linker is actually the compiler you're using,
> > I can't find the excuse for this). It takes away the ability to specify
> > positional linker flags.
>
> Not sure what you mean by that.
Take any source package which uses libtool to build library. On Solaris,
configure it like this:
CC=cc ./configure
Watch it when it builds the library. It directly invokes /usr/ccs/bin/ld.
That's a bug. The only time when you're supposed to invoke ld directly is
when you're building kernel modules (with ld -r). At all other times
you're supposed to use the compiler.
There is no magic in this; the compiler will add crti.o and crtn.o to the
list of object files. Libtool doesn't do that, so I can show you some
sources which won't work. I don't know what happens with gcc, because I
never tried. But still, the compiler you're using to compile the source
should be chosen as a linker by default (there are some exceptions, but if
we stick to the C sources then there is no exception).
You can cure this with "CC=cc LD=cc ./configure", but the only sane usage
for LD variable is when you're linking products of different compilers.
Say you're linking with some archive that was produced by a C++ compiler.
You should link the binary with that same compiler, but linking tools
probably can't know which C++ compiler was used for that archive.
Therefore it's reasonable to expect that user will supply that
information. In all other cases there is no need to expect that user will
set LD variable, because LD=$CC should be used.
As far as positional linker flags are concerned, it's pretty simple. I
would like to build wget in this way:
cc -o wget *.o ... -z lazyload -lssl -lcrypto -z nolazyload -lnsl -lsocket ...
The effect is that SSL libraries will be loaded in run-time only when wget
actually tries to use them (presumably when trying to access https URLs),
but not otherwise. The start-up is faster and you don't have to have SSL
libraries if you don't intend to use them, although the binary was linked
against them. It's probably not very important in case of wget, but we can
discuss GNOME, KDE and CDE binaries if you want.
> > When compiling libraries it severely limits the
> > choice of compilers (might be platform dependant, but I doubt it).
>
> Really?? I thought the general design was that if it didn't know something
> about a particular OS or compiler, it'd just pass through what you gave it
> unchanged.
But it must know. A few years back I was trying to play with Apogee C
compiler on Solaris. That compiler uses -PIC to generate position
independent code. Libtool (configure script, to be more precise) tested
if gcc was used (in which case it would decide to use -fPIC) and since it
wasn't, the fallback was -KPIC, which is the proper flag for Sun's
compiler. Then the configure test for shared library build failed and
libtool decided it won't build them.
The problem here is not that it didn't have support for Apogee C compiler.
The problem is that it doesn't provide a way for the user to override
libtool's assumptions (or configure script assumptions). You probably know
that one can use two PIC models on SPARCs. The small model gives faster
code, but it can't be used for big code, because there is a restriction on
number of bits that jump instructions can use for addresses. The big PIC
model has wider address range, but the code is slower.
Libtool documentation claims that libtool ignores the whole thing and
always uses big PIC model because arbitrary limitations are evil. Which is
like complaining about the speed of light being finite. RISCs have some
hardware limitations, but the compilers are supposed to be smarter (with
some help from the users sometimes), so the net effect should be faster
code. That's the theory. I don't think it holds water in all aspects, but
that's beside the point. It's correct here, because small PIC model
produces faster code, without a doubt.
If there was a --with-pic-flag, then I would be able to use small PIC
model if I choose to (and in the end I might suffer link error if the code
is too big, but that would be because of my decision). But what's more
important is that I would be able to specify --with-pic-flag=PIC and I
would be able to compile the source with Apogee C compiler, without having
to edit the configure script manually (and I'm sure you know how much fun
that is).
As it is, libtool must have hardcored knowledge about the compilers, so if
you choose to use it because you don't want to test every OS/compiler
combination, then you'll come closer to that goal. I suppose it only
supports gcc and the native compiler (there might be an exception or two,
though). This only applies to building libraries, but you asked (and
even put two question marks), so there you go.
> > There
> > is no sane way to tell it to discard all flags it thinks are correct
> > (except those which are specified by POSIX.2, as those are the only ones
> > which are always correct).
>
> Why would you want to tell it to discard all flags it thinks are correct?
Because I don't think they are correct. And I don't think they are
desirable. So I want to put my own instead, without resorting to editing
configure script, libtool script, *.la files, huge amount of cut & paste
operations (just to insert some linker flags) etc.
I am human and libtool is program. The difference is that humans are able
to read the documentation and do something smart, sometimes.
> > > Nothing?? Sorry, but that's pretty massive hyperbole.
> >
> > Well, I don't remember ever seeing libtool linking libraries in a way I
> > wanted them to be linked. No matter what I put in LDFLAGS or LIBS. Which
> > is why I end up linking libraries by hand in spite of libtool. That's not
> > a massive hyperbole, that's a massive amount of work required to have
> > libraries linked in a way which platform documentation recommends.
>
> Have you had these problems when libtool is only used for linking to
> existing libraries? If not, again, I don't see how this affects the
> decision to use libtool with Wget.
It doesn't. It's a response to your statement that my statement was a
pretty massive hyperbole.
> Are you sure all these problems you've seen are libtool's fault, and not the
> fault of the package authors? The only problems I've ever had with libtool
> have been because the package authors weren't using it correctly.
I'm not sure. To answer this question we would have to define what the
correct usage is. As far as I can see, libtool wants you to have all
libraries (except the ones living in OS default directory) managed by
libtool. I don't find that requirement acceptable. Could you tell me what
is the correct libtool usage (or point to the piece of documentation which
says that)? As far as know, there are only platform build rules, which
should be obeyed by the build tools. Libtool doesn't do that.
> > Yes, but it shouldn't produce unusable binary when compiling with gcc.
> > If I didn't say --with-ssl=/usr/local than it's OK if I don't get SSL
> > support, but it's not OK if I end up with unusable binary without any
> > error or warning.
>
> You don't. You get a binary that simply doesn't have SSL support, and you
> get a big fat warning about it.
No, I got a big fat warning with the second try, by using another
compiler. Building with gcc produced unusable binary because gcc adds
-L/usr/local/lib behind your back, but not -R/usr/local/lib. Last time I
was checking IRIX documentation, the native compiler there was doing the
same thing.
Your configure test passed because of this, so the AI thought SSL libraries
were in /usr/local/ssl/lib. This is beginners mistake (I don't intend to
insult you here; linking properly and being portable is extremely hard
to do.) Always check first if your test passes with LDFLAGS, LIBS and
CPPFLAGS (maybe some others, too) that you already have. Only if it fails,
try being smart and testing if some additions are needed. This principle
would save a lot of pain with configure scripts in general.
It would be nice to have some tool which knows a thing or two about
platforms (dynamic loader, to be more precise) and compilers, so it could
do the right thing for you. Libtool knows on which platform it's running
and it knows which compiler is being used, so libtool could do that. But
the fact is that it doesn't. So you'd have to do it yourself. All this
started when you said you wanted to use libtool because you don't want to
check each possible platform/compiler combination. But you will.
> > > > [7] RPATH $ORIGIN/../lib
> > >
> > > Sure, just use whatever custom LDFLAGS you would have used without libtool
> > > in the picture. It will respect and use them.
> >
> > I don't know how to use LDFLAGS for this, so I'm using something else
> > which bypasses libtool entirely.
>
> Huh? There was no concept of bypassing libtool before it was in the
> picture. Not sure what you mean when you say you aren't using LDFLAGS.
> How exactly *are* you building?? Can't address your problem if you can't be
> more descriptive of your build process.
That $ORIGIN thing is Solaris specific. In run-time it evaluates to the
directory where the binary lives (the information is provided by the
kernel, so it's always correct). So if wget lives in /usr/local/bin,
run-time linker will try to search for libraries in /usr/local/lib. That's
a nice feature which allows you to build binary packages which don't
depend on hardcoded run paths.
But $ has a special meaning to the sh utility, which wants to perform
something called variable expansion when it encounters $ORIGIN. And it has
a special meaning to the make utility, which wants to do the same thing.
So if you want to use it in the Makefile, you have to do it like this:
LDFLAGS=\$$ORIGIN/../lib
Since my interface to the build system is through configure script which also
wants to perform something nasty with $ORIGIN, I haven't found a way to
escape it in a way which works with a random configure script. Therefore
I'm using direct ld interface, usually some variant of this:
LD_OPTIONS='-R$ORIGIN/../lib' make
LD_OPTIONS controls ld directly, so I thought that I'd win with this, that
I found a way to bypass libtool. But little did I know about the evil ways of
the thing which wants to be linker instead of linker.
In general, I want to use $ORIGIN when building libraries, but I need
$ORIGIN/../lib when building libraries (as they don't live in the same
directory). Autoconf can't handle something like that, but I could just
let it build everything and then delete the resulting libraries and
binaries and rebuild them by hand, right? Wrong. Makefiles don't have
normal targets any more, so if you delete the binary and call make,
nothing happens. Instead, there is some thing with .la extension which is
the Makefile target. But if you delete it and run make, then it rebuilds
libraries and binaries together although they were up to date and one
would expect that no action should be taken.
This is probably a product of automake, so it doesn't apply here, but
since you wanted to know how exactly am I building, there you go. More to
follow on request.
Besides, the above is the documented and recommended build procedure on
Solaris, so it is the *standard* way to build on that platform.
> > But, if libtool decides it should use
> > -R/usr/local/lib (or whatever), how do I tell it that it's not a good idea?
>
> It doesn't decide that. configure adds -R<OpenSSL_lib_dir> to LDFLAGS, and
> libtool translates that to the appropriate flag for this OS (whether that's
> -R<dir>, "-Wl,-rpath -Wl,<dir>", "-Wl,-blibpath -Wl,<dir>", or whatever).
> If you don't want that -R parameter to even be fed to libtool in the first
> place, simply override the setting for LDFLAGS. Heck, set it to "" if
> you're linking some weird way that doesn't use LDFLAGS...
But I want the appropriate -L to be put there by the configure script.
I don't think this is unreasonable request, because -L and -l flags are
specified by POSIX.2 (c89 utility), while -R is not. What I want is a build
process which uses only documented POSIX.2 interfaces. I can take care
about the rest. It doesn't have to be the default. Having to pass
--posix-me-harder or --libtool-is-a-fool flag is perfectly acceptable.
> > > It's just that the average user no longer needs to be a shared library
> > > expert, as you apparently are.
> >
> > I'm not.
>
> Well, most non-experts generally wouldn't complain that libtool is taking
> away their control (you can't control what you don't understand), and that
> they want to link to shared libraries in special, non-standard ways.
But there is no standard way to build shared libraries, if by standard you
mean some multi-platform build procedure. There are only platform specific
ways to build, which should be documented for every platform. And build
tools (such as autoconf/automake/libtool trinity) should conform to that,
because there is not a solid piece of ground anywhere else.
--
.-. .-. Sarcasm is just one more service we offer.
(_ \ / _)
| [EMAIL PROTECTED]
|