This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, 3/4] Enable libstdc++ as a DLL on windows platforms.
[aw geez. I see 15 more messages since I began composing this. I'm gonna
post it anyway; if I repeat points already raised by others, please
forgive me]
Dave Korn wrote:
> Charles Wilson wrote:
>> Since users on windows may already be accustomed to defining (or not
>> defining) "_DLL" depending on whether they wish to link against the
>> shared (or static) C/C++ runtime(s), we choose to use the same symbol?
>
>> (Of course, end users still aren't REQUIRED to use -D_DLL when linking
>> with --shared-libstdc++. [snip])
>
> Right. I didn't in fact design this myself, it was in patches I inherited
> from Aaron and Danny, so they may want to explain it, but as far as I can see
> it's efficiency not correctness, so let's just leave it to the user, and let's
> use the standard name they're all already familiar with.
Well, I guess. See below.
>> Third, is it possible to "mix" the C++ and C runtimes when linking a
>> single image -- that is, --static-libgcc and --shared-libstdc++, or vice
>> versa (this "mixing" is not possible on MSVC, because the same linktime
>> flag is used to control both C and C++ runtime).
>
> Not all combinations are valid. You can have static libstdc with shared
> libgcc, but static libgcc with shared libstdc won't work.
I see.
>> If it is possible,
>> then ... we probably need one of the following:
>> a) distinct compiled time flag for clients of the libraries to define,
>> instead of _DLL for both, OR
>> b) policy decision that the C runtime shall not decorate any items
>> with declspec(dllimport) at all. This implies that when linking against
>> the shared libgcc then the auto-import functionality will be used (which
>> may not be much of an issue if there are no client-visible data items
>> exported by that DLL [*]).
>
> I think it's a desirable goal to move away from reliance on
> auto-import/auto-export in general and do it as properly as possible; the auto
> functionality is not as efficient and is really there to provide a convenience
> fallback for compiling ported unix code on windows without having to annotate
> it all up.
For an interesting approach to avoiding autoimport without "compile this
way when you plan to link against static lib, this other way when you
plan to link aginst the dll", see:
http://www.haible.de/bruno/woe32dll.html
So, ignoring Bruno's approach, if (in general) you want to have specific
compilation macro that controls whether symbols declared in a header
file are decorated with declspec(dllimport) or not, then you really need
one that is specific to each library that you may link against. That
is, if you have two unrelated libraries:
foo.dll / foo.a
bar.dll / bar.a
and you want to compile baz.exe and link against foo.dll but bar.a, then
foo.h and bar.h must use different -DSYMBOLS to control the decoration.
Obvious, right? (Naturally, it gets a little more complicated if foo
and bar have some dependency relationship).
Now, for cygwin, we have
libstdc++ (shared or static)
libgcc (shared or static)
cygwin (DLL only, natch)
and neither MSVCRT nor any headers declaring symbols from it are
involved; then it's fine to use -D_DLL. Plus, you never ever use MS's
runtime headers (you might use MS's w32api headers, but not thier
version of "stdio.h").
However, I think Kai's concern is this:
For mingw, we (will) have
libstdc++ (shared or static)
libgcc (shared or static)
MSVC (runtime) (shared or static)
Now, because MinGW gcc always links against msvcrt.dll (unless you play
games with the spec file; let's not worry about that right now), THEN
If you use MS's header files, you might get the following for C (and
C++?) runtime functions from crtdef.h:
/* Define _CRTIMP */
#ifndef _CRTIMP
#ifdef _DLL
#define _CRTIMP __declspec(dllimport)
#else /* ndef _DLL */
#define _CRTIMP
#endif /* _DLL */
#endif /* _CRTIMP */
However, it is unclear whether you get <crtdef.h> when you're just using
the "SDK" headers, as opposed to the runtime headers. And why would you
use MS's runtime headers, when mingw gcc is designed to use the ones
from mingwrt? It's not as if the MS headers include the correct C99
extern inline stuff needed by gcc, etc. (Using the MS SDK headers in
preference to the mingw w32api ones, sure...but the runtime ones? like
<stdio.h> and <fstream>? Surely that isn't supposed to work anyway?)
Anyway, all the interesting stuff from the official MS runtime C (C++?)
headers are decorated using _CRTIMP. The same is true for the mingwrt
headers, except there the definition of that symbol within the mingw
headers is controlled by __USE_CRTIMP, not _DLL.
So, I can see where some people might be in the habit, of defining
-D_DLL with mingw gcc -- even though it really, at present, should have
NO effect with mingw gcc, since:
a) the mingwrt headers are insensitive to its value
b) you're supposed to use the mingwrt headers, NOT the ones from
C:/Program Files/Microsoft Visual Studio 8/VC/include
c) it's fine if you use either
C:/Program Files/Microsoft SDKs/Windows/v6.0/Include
or
cygwin: /usr/include/w32api
mingw: <MINGWROOT>/include
for the Windows API. In either case, you shouldn't "pull in"
headers from the C or C++ runtime.
NOTE: the standard mingw installation puts its runtime headers, AND
its version of the w32api headers, all into the same directory.
So...it looks like, to me, that at present _DLL does nothing on
mingw/cygwin. But *because* it does nothing, folks using source code
developed for MSVC might be in the habit of leaving it defined. By
repurposing that macro to control decoration of libstdc++, rather than
(MSVCRT + MSVC++RT)'s decoration...we may be introducing a regression
for those users:
Assuming that on mingw, the default link mode remains
--static-libstdc++, then the users in the situation above must
1) remove -D_DLL which previously made no difference, or
2) add --shared-libstdc++.
But contra Kai's contention, I don't believe the use of -D_DLL makes
*any* difference with regards to getting MSVCRT symbols -- when the
correct mingwrt headers are being used.
--
Chuck