libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MSVC: Always dllimport the variable for MSVC in link-order.at


From: Peter Rosin
Subject: Re: MSVC: Always dllimport the variable for MSVC in link-order.at
Date: Thu, 15 Jul 2010 22:39:42 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.4) Gecko/20100608 Thunderbird/3.1

Hi Ralf,

Den 2010-07-12 07:46 skrev Ralf Wildenhues:
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.

This is nothing new. It is the same situation that applied to GNU on
Windows before auto-import, I think. I'm quoting this off-list
conversation with Chuck (off-list due to some misunderstanding) that
describes the situation quite well:

Den 2010-07-11 19:40 skrev Charles Wilson:
[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.

The above implies that you need to select one way to do this universally
for "my target", but I don't think that you need to do the same everywhere.
So, I just just the method that cleared up the test case in the least
intrusive way I could think of.

[back to Ralf's message]

Is that documentation step hidden somewhere in your queue already, or
does that still need to be done?

It is not hidden in my queue, so it is a TODO. I didn't think the onus
was on me to write this as it has been a known issue on Windows for a
long time (I was just temporarily fooled that it was a non-issue with
MSVC when I misguidedly thought you could always dllimport with it).

The manual already says that it is not portable to export data items from
a libtool library. At least I think it does.

I really think it is as innocent as it looks. Whether to use #ifdef PIC
or #ifdef DLL_EXPORT is not important to me, and if DLL_EXPORT makes it
look even more innocent then that's perfectly fine with me :-)

Hmmm, there is one quirk that's perhaps MSVC-specific: dllexport isn't
needed as the symbol pipe is used to dig out exports. But I don't know
for sure if that's MSVC-specific...

Cheers,
Peter



reply via email to

[Prev in Thread] Current Thread [Next in Thread]