Mail Archives: cygwin/2002/11/11/16:55:09
Robert Collins wrote:
>
>>But, I think it's overkill to define "system libs that should not be
>>re-exported" as "anything in /usr/lib" or something similarly broad.
>>
>
> Why? *anything* in /usr/lib is able to be linked to from multiple
> packages. If one package creates a dll from there, then we will get this
> problem. We're currently *manually* excluding *how many* libs? fortran.
> gcc. stdc++. cygwin. And thats from memory. Do we want to hack ld when a
> test g++-3.3 is released? IMO No.
No need. If we don't include the trailing '.' in the basename exclusion
list, the same test can match
libtstdc++.a
libstdc++-2.a
libstdc++-3.3.a
or whatever. Chris just committed a patch to binutils CVS that does
this generalization.
> I think that nothing specific to gcc should be handled by ld. If gcc
> knows about file foo, be that mingw specific, or c++ specific, it should
> tell ld to do the right thing. This centralises the knowledge about the
> exceptions.
Ideally, sure -- but that'll require a LOT of info to be passed (see
below). But the fact is, ld already incorporates LOTS of knowledge
about the way gcc does things -- and not just on cygwin/win32. binutils
is tightly tied to gcc (and vice versa), like it or not.
>>On the other hand, we're really arguing about a problem that hasn't bit
>>anyone yet. By excluding the main (gcc) static runtime libs from
>>re-export, and the main (platform) static runtime libs like libmingw32
>>libmingwex from re-export -- we pretty much cover all the important bases.
>>
>
> True. My suspicion though is that as folk find .dll's easier to build,
> with the libtool dll support hitting mainstream as of(?1.4?) it will be
> more common to link against something. Let me give you another contrived
> example:
>
> I create a static lib foo (say readline for arguments sake). It gets
> installed into /usr/local/lib.
>
> Someone else makes a library bar depending on foo. This library is a
> .dll. It gets installed into /usr/local/lib.
Aha! But that can't happen given the recent changes in libtool. If any
dependency is static, then libtool will refuse to create a DLL (unless:
my changes exempt the platform and compiler libs from this check. But,
I don't hardcode them in libtool; libtool computes the stdlib names from
gcc and ld output)
Now, if you're building a DLL "by hand" then sure, problems can happen.
But as you say, DLL-making will only become widespread "with the
libtool dll support hitting mainstream". 1.4.x had a limited version,
which still required lots of sourcecode modification and __declspec
magic. 1.5.x will use auto-import, and life will become VERY easy.
That's mainstream. 1.4.x was an attempt, but turned out to be too
difficult in practice.
> Every app that links against both foo and bar (and if bar is a libtool
> library, it will suck in foo for us) will get duplicate symbols.
Nope. See above. This is why I agree, in principle, with the recent
changes in libtool that made things suck briefly. It was a lot of work
to "fix" -- but the general idea "don't build sharedlibs that depend on
static libs" is a good one. And is still in place, even in my patched
versions of recent libtool.
>>Anything else is obviously a corner case, since it hasn't bit anyone yet
>>-- and the fix is for that person to specifically exclude the static lib
>>that "bit" them by using --exclude-libs.
> That is *a* fix. Why doesn't it bite folk on linux or BSD? Why should it
> bite anyone here when *we can make ld do the right thing*.
It *did* bite linux/BSD folks -- but since ELF has provisions for symbol
overriding, it didn't really have too much of an effect. We don't have
those provisions; duplicate symbols are a major problem in pei-386.
That's why the recent changes to libtool prohibit buiding sharedlibs
that depend on static libs -- to avoid these problems (even the minor
ones on linux/BSD).
In my libtool changes, I'm only arguing for an *exception* to that
algorithm when the static libs in question are gcc-provided or
platform-provided ones, that already have "don't re-export me"
provisions in ld. [but I'm not hardcoding that knowledge; it's computed
on-the-fly from gcc/ld output] But that's a libtool discussion.
In binutils, we already have a "don't re-export me" list. I think that
the following heuristic is reasonable for keeping that list short:
1) libraries provided by the gcc compiler suite
2) win32 (cygwin, mingw, pw32) "platform" libraries that are commonly
available only as static libs. [remember, this code is in pe-dll.c and
only applies to win32ish platforms]
We already refuse to re-export symbols imported from DLLs. So, we only
need to worry about "standard" libs that are available only as static
libs.
Right now, that's a short list: the gcc libs, and libmingw32 +
libmingwex. The end. Dropping the final '.' in the matchstring, and we
can exclude all versioned instances of the gcc libs, without making the
list too long.
> We only want to export static archive symbols when
> a) it's a convenience library,
> b) we are creating a forwarding library for the archive.
or when --whole-archive libfoo.a --no-whole-archive is used. Or when
libtool can't fit all of the objects on a single commandline, and has to
build separate archives. [these are not treated as convenience libs,
becuase clibs get incorporated into DLLs by *unpacking them* and
explicitly listing the component objects on the link command -- which
doesn't help the linkcmd length :-) ]
Refusing to export symbols from "static" archives in general on cygwin,
will break established idioms (not counting libtool). As I explained
earlier, libtool has already decided to prevent this action in general.
> In a) the library won't be in /usr/lib unless you are building from a
> subdir of that (unlikely!).
true
> In b) the library *may* be in /usr/lib, so we can allow a --include-libs
> flag to override the heuristic (and I think we already have one, no?)
Urgh. Not another flag. (unless your "we already have one" reference
is to --whole-archive).
>>The problem here, is that because of our packaging of gcc-2, we're
>>missing the names of the (gcc) static runtime libs for that "package".
>>Plus, libmingwex is another (platform) static runtime lib that we're
>>missing -- but it was only recently added to the mingw "platform".
>>
>
> The problem is that dll's are non intuitive, and our automagic support
> is incomplete :}. There's a refactoring smell, uhmm, 'Shotgun Surgery'.
> When we change the names of common system libraries, we have to change
> ld as well. That's plain wrong.
Yes, it would be -- if we were changing the names. Do you really think
that libgcc is going to change its name anytime soon? We shouldn't have
included the trailing '.' in the first place; removing it solves all of
your versioned runtimelibs worries at once.
It is kinda kludgy that everytime a new compiler frontend is added, we'd
need to add that frontend's runtime lib to the exclude list. But we've
added exactly ONE new frontend in five years. gcj. Sue me.
[BTW, each front end needs work to support __declspec() attributes and
autoimport before this really becomes an issue. Right now, g77 doesn't
support exporting DATA items from DLLs at all; only functional
interfaces are allowed. This is because the g77 frontend won't allow us
to decorate common block variables (__declspec(); old style). And
that's a prerequisite for working auto-import/auto-export support. So
libtool-on-cygwin doesn't even pretend to support DLLs in fortran. And
there's no provision for gcj at all. One thing at a time. And the gcc
frontends need work first]
And binutils IS tightly linked to gcc. If it needs to know the names of
the gcc-provided libs, thats okay with me. In an ideal world, our gcc
spec file would include
--exclude-lib=libstdc++
every time it mentions -lstdc++. And there would be a similar ld
command called "--exclude-object" so that every time gcc's spec file added
crt0.o
it would also say
--exclude-object=crt0.o
And ld wouldn't need a list of "internal DLL layout symbols" like
{ "_head_", 6 },
{ "_fmode", 6 },
{ "_impure_ptr", 11 },
{ "cygwin_attach_dll", 17 },
{ "cygwin_premain0", 15 },
{ "cygwin_premain1", 15 },
{ "cygwin_premain2", 15 },
{ "cygwin_premain3", 15 },
{ "environ", 7 },
because the gcc spec file would say --exclude-symbol=... every damn time
you build a DLL.
Where do you stop? As a practical matter, ld can't be purely data
driven; it needs to KNOW some things about DLLs. And the platforms
where DLLs are used, like cygwin and mingw. And it needs to know about
the ONLY compiler suite on those platforms: gcc.
I really don't think the current "division of knowledge" is that bad.
> I think that the revised patch is fine, along the existing approach, but
> the existing approach is much less than optimal.
There are certainly areas where improvements can be made -- but your
idea of optimal is suboptimal, IMO. :-) Your desire seems to be similar
to that of setup.exe: purely data driven. I think that's a great idea
for setup -- but I don't think it's a good path for ld. Right now ld
handles some things, and gcc handles others -- and
1) some knowledge is shared (e.g. is maintained in the codebase, and
must be coordinated to some extent)
2) other knowledge is passed on the command line (gcc's spec file)
The stuff in 1) doesn't change often (time constant == years? The last
change to this part of the code was August 2001). I think the division
of knowledge is about right, subject to minor tweaking.
--Chuck
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -