Hi Peter,
* Peter Rosin wrote on Sat, Jul 10, 2010 at 10:15:09AM CEST:
Next in to MSVC queue...
This is a variation of
95bdbc456f7c5d6d669121cf20d62a9c28bec2bf
"Always dllimport the variable for MSVC in link-order.at"
Patch previously discussed here:
http://lists.gnu.org/archive/html/libtool-patches/2008-08/msg00053.html
In that discussion I claim that "With MSVC, you can declare any variable
with __decspec(dllimport), even if you are not actually importing it"
and I must have been thoroughly confused when I arrived at that
conclusion. It doesn't hold when I now try it...
So, instead of just "#ifdef _MSC_VER", this version does
#if defined _MSC_VER&& defined PIC
# define LIBCEE_SCOPE __declspec(dllimport)
Now, the PIC part isn't truly what we want to test for, since we don't
really want to dllimport when we a *building* a PIC library. We want
to dllimport when we *use* a shared library. But in this case it happens
to coincide, and the notion of using a shared vs. static library isn't
really covered by libtool, i.e. there's no -DUSE_PIC or equivalent that
can be used to discriminate in the code.
the patch looks fairly innocent at first sight, but your description
makes me wonder how a user is going to get that right. In fact, I don't
see how we *can* get that right as the preferred form of linking (static
or shared) might not yet be known at compile time at all. So I guess
the only viable route is to document the limitation somewhere, and tell
developers and users what to do and expect in face of it.
[Did you mean to send off-list? Feel free to quote and reply on-list]
On 7/11/2010 3:20 AM, Peter Rosin wrote:
> Den 2010-07-10 14:10 skrev Charles Wilson:
>> On cygwin, libtool's pic "flag" is DLL_EXPORT, so that +
>> BUILDING_LIBIDO is often used.
>
> In this case we know for sure that we are building since the
> preprocessing directives are in .c files, not .h files.
That is true.
> That, and the fact that using DLL_EXPORT when we want to
> import seems...wrong,
Out of order reply, below.
> made me go for PIC instead. Besides,
> PIC is still defined on Cygwin, is it not?
it is:
pic_flag=" -DDLL_EXPORT -DPIC"
However, because they are both defined by the same variable, using one
is much the same as using the other. (And some people are bothered by
the "PIC" flag on PE/COFF: 'there's no such thing as pic, blah blah blah).
> But I have no strong preference, do you?
Not a "strong" preference, especially as we're talking about test code.
(Although, test code often serves as an instructional example, so a
modicum of attention to detail is prudent).
The real issue is that libtool has no equivalent "mode" to: I'm not
BUILDING a library (dynamic or static), but I DO plan to LINK against
this specific shared library X. Therefore, when compiling my client, I
want to ensure the proper symbol decorations, so I should compile using
"pic_client_flag".
And the *reason* libtool doesn't have that, is because how do you then
say "I'm going to link against shared library X, but static library Y.
Therefore, libtool should set this generic pic_client_flag to
-DGENERIC_LIBRARY_IMPORT".
But doing that would "turn on" symbol decorations for BOTH X and Y.
At this level, you basically have to make a choice:
1) On my target, all libs will by default link dynamically. This was
the pre-auto-import choice for cygwin, and that's why binutils and gcc
default to dynamic linking (dll.a vs. .a, etc). To link statically, you
must explicitly define a per-library symbol, e.g. -DSTATIC_LIBFOO
-DSTATIC_LIBBAR.
2) On my target, I will use auto-import universally, and avoid special
flags to indicate symbol decoration. Everything is undecorated, and
binutils auto-import will fix everything for me. This is the
post-auto-import cgywin choice. Obviously this is not available for MSVC.
2a) Bruno Haible (gettext maintainer) has come up with a method that
allows pseudo-auto-import to work, universally. Basically, what he does
is (a) All clients always get decorated symbols (e.g. dllimport) -- even
when you plan to link statically. (b) the static libs themselves are
constructed with redirection thunks, manually constructed by .m4 rules
and various other support. See:
http://www.haible.de/bruno/woe32dll.html
http://article.gmane.org/gmane.comp.gnu.libtool.general/7753
This approach appears to work with MSVC -- and doesn't have any more
indirections that actual -fpic code on ELF (e.g. the "extra" thunks used
even in the static libs are basically GOT indirections, just like -fpic).
3) On my target, I will use a "stack" approach: if I am building a dll
(e.g. pic_flag) then I will assume that all client libs are also DLLs,
and will arrange that these client libs' headers will decorate with
dllimport whenever pic_flag (eg. -DDLL_EXPORT (or -DPIC)). Thus, I
can't build a DLL that links against the static lib, because the same
flag that is used to turn on my own *exports*, is also used to ensure
that I get the other DLL's *imports* properly decorated.
This is safe, because we can't link a DLL with static deps anyway.
The slightly wiggly thing about the "stack" approach, is when I am
building an EXE. I need to ensure that pic_flag is true, even though
libtool doesn't typically build the pic .o's for EXEs. So, this breaks
the encapsulation a bit: the package must explicitly add -DDLL_EXPORT
(or -DPIC) to appfoo_CPPFLAGS -- when means the user of libtool
designing the build framework needs to know about all of these silly
#defines....
Now, if I want to link my app statically to any of its deps, then I must
link statically to ALL of the dep libs (because I must not #define
DLL_EXPORT or PIC; and it becomes an all-or-nothing choice).
This #3 approach appears to be the compromise adopted by most open
source packages with MSVC support -- and appears to be the approach you
are taking here.
That's fine, but there are drawbacks. Unfortunately, I don't see any
*automatic* way around it for MSVC that doesn't make one assumption or
another -- unless you manually handle it all (separate -DLIBFOO_STATIC /
-DLIBFOO_IMPORT flags for every dependent library).
Unless we were to adopt Bruno's approach for libtool+MSVC, universally,
and hope it percolates through the free software economy.