lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Mystic fix for so-attributes linker error


From: Vadim Zeitlin
Subject: Re: [lmi] Mystic fix for so-attributes linker error
Date: Thu, 9 Mar 2017 16:40:35 +0100

On Thu, 9 Mar 2017 14:59:45 +0000 Greg Chicares <address@hidden> wrote:

GC> That's a useful idea to keep in mind, but this one may be even better,
GC> if only because I can do it too (without accepting an unacceptable EULA
GC> that IIRC forbids using that proprietary compiler with free software).

 I really don't think this could possibly be true considering the amount of
free software that is regularly built with MSVC.

GC> >  But I also thought of something else: we could also change the default
GC> > visibility to hidden for the Unix builds. This should expose all the
GC> > problems due to missing/wrong LMI_SO usage too because ELF linker doesn't
GC> > do (nor even could do) any auto-linking neither. Should I do this instead
GC> > (or in addition to)?
GC> 
GC> I think that's a great idea.

 OK, I'll try to do it soon.

GC> >  AFAICS the problem is that mc_enum_base is DLL-exported but mc_enum<>
GC> > itself is not. If we want to encapsulate all the methods above in
GC> > liblmi.dll, then we shouldn't export mc_enum_base from it neither. But
GC> > currently virtual methods such as all_strings(), declared with LMI_SO in
GC> > the base class, but defined without it in the derived one, seem to create
GC> > problems.
GC> 
GC> That's deliberate, and I tested it successfully with mingw.org's gcc
GC> (probably most versions from 2.95 through 3.4.5) and also with comeau
GC> and borland.
GC> 
GC> The idea is that (virtual) base::foo() is externally visible, while
GC> (overriding) derived::foo() is not: then the external world can call
GC> into the shared library through the base class, and the shared library
GC> dispatches the call internally to the override.

 This does mean that the vtbl of the derived class must be exported from
the DLL and I don't know how to make this happen with gcc attributes other
than by using LMI_SO on the entire class.

GC> > GC> Perhaps I should finally start doing routine GTK builds here, with ELF
GC> > GC> visibility attributes.
GC> > 
GC> >  Notice that currently this wouldn't help because we don't use
GC> > -fvisibility=hidden yet.
GC> 
GC> AIUI, we'd simply need to define LMI_SO appropriately for ELF.
GC> I'm not sure whether the existing code is appropriate:
GC> 
GC> #       if defined LMI_BUILD_SO
GC> #           define LMI_SO __attribute__((visibility("default")))
GC> #       else  // !defined LMI_BUILD_SO
GC> #           define LMI_SO
GC> #       endif // !defined LMI_BUILD_SO
GC> 
GC> I wrote that after reading the first announcement of "visibility",
GC> but never tested it.

 It's appropriate provided that the default default visibility (i.e. the
visibility in absence of any special attributes) is hidden, otherwise this
simply doesn't do anything as all symbols are visible by default.

 I.e. the difference between MSW and ELF is that in the former symbols in
shared libraries are hidden by default and need to be made visible
("exported"), while in the latter all symbols are visible by default. This
got muddled later by MinGW implementing auto-export, i.e. making all
symbols defined in the DLL exported, and by ELF visibility addition,
allowing to change the default visibility to "hidden", as in MSW, but the
default behaviour still remains unchanged since 1980s.

GC> >  Why don't we use USE_SO_ATTRIBUTES=1 (and, ideally, 
--disable-auto-import)
GC> > by default?
GC> 
GC> IIRC, the reason for this decision was that the mingw.org toolchain
GC> worked much better this way around the turn of the century.

 Yes, there were performance problems with building libraries with a lot of
exported functions with gcc 4.[56], see

https://github.com/wxWidgets/wxWidgets/blob/v3.1.0/include/wx/dlimpexp.h#L38

and the comment preceding it. But this is not the case any more since gcc
4.7 and I think it could be well worth testing this again.

 BTW, on a tangentially related note: could we remove (i.e. can I make a
patch removing) gcc version checks, at least with all versions < 4.8? As
the code uses C++11 now and the gcc versions until 4.8 didn't have support
for it (well, 4.6 and 4.7 did have beginnings of it with -std=c++0x, but it
was insufficient anyhow), current code won't compile with them anyhow, so
it bothers me to see checks like "LMI_GCC_VERSION < 30404" which can't
possibly be true. Please let me know if I can get rid of them.

 Thanks,
VZ


reply via email to

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