lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Testing build with native MinGW 4.9.1


From: Vadim Zeitlin
Subject: Re: [lmi] Testing build with native MinGW 4.9.1
Date: Fri, 29 Jan 2016 03:08:40 +0100

On Fri, 29 Jan 2016 00:53:39 +0000 Greg Chicares <address@hidden> wrote:

GC> Unfortunately, I extended your patch to 'mc_enum_types_aux.cpp' in the
GC> hope of averting future problems, and my extension fails in this case
GC> (where your original patch works):
GC> 
GC>   $make --jobs=6 all build_type=so_test USE_SO_ATTRIBUTES=1
GC>   /MinGW_/bin/g++  -o lmi_wx_shared.exe \
GC>     main_wx.o lmi_msw_res.o skeleton.dll liblmi.dll \
GC>     -L . -L /opt/lmi/local/lib -L /opt/lmi/local/bin  -L /opt/lmi/local/lib 
\
GC>     -lwx_mswu-3.1-i686-w64-mingw32 -mwindows    -lexslt -lxslt -lxml2 \
GC>     -Wl,-Map,lmi_wx_shared.exe.map
GC>   main_wx.o: In function `lmi_force_linkmc_enum_types_aux':
GC>   /lmi/src/lmi/main_wx.cpp:55: undefined reference to 
`lmi_link_dummy_func_mc_enum_types_aux()'
GC> 
GC> so I'll have to revert my extension. Evidently the problem is that I
GC> was trying to force linking through a DLL barrier:

 I don't think it is ever necessary to do this when using a DLL. If a DLL
is loaded at all, all its global objects will be initialized, unlike a
static library, a DLL can't be "partially loaded", whereas this is exactly
what happens in the static case: parts of the library which are not
otherwise referenced don't become part of the final executable at all and
so the global variables in them are simply not present.

GC> I tried twiddling 'force_linking.hpp' by adding LMI_SO to various
GC> combinations of the three declarations of
GC>   lmi_link_dummy_func_##translation_unit_name()
GC> but that only introduced more diagnostics. And AFAIK there is no
GC> standard grammar for "declspec" that works for every compiler, so this
GC> is deep magic and the less voodoo we use the better.

 There is no standard, but in practice all compilers support either MSVC
__declspec(dll{ex,im}port) or gcc __attribute__((dll{ex,im}port)), so it's
not like it's difficult to cover all cases.

GC> I heard some exciting talk about ELF visibility attributes many years
GC> ago, and even attempted to provide for that in 'so_attributes.hpp':
GC> 
GC> #   if defined LMI_MSW
GC> ...
GC> #   elif defined __GNUC__ && 30400 <= LMI_GCC_VERSION
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> #   else  // !defined LMI_MSW and no ELF visibility support
GC> 
GC> Did that feature live up to the hopes expressed at its introduction,
GC> so that it will be useful when building lmi on an ELF platform?

 Yes, absolutely, all shared libraries should use hidden visibility by
default and explicitly set the visibility on the selected exported symbols.
This has two big benefits: first, it clearly defines the shared library
public interface instead of making all and every symbol defined inside it
for the use from the outside and, second, significantly speeds up loading
of the libraries with many symbols.

GC> and have I even implemented visibility correctly above?

 As far as the code goes, yes, you have, but this is useless without using
the appropriate flags (-fvisibility=hidden -fvisibility-inlines-hidden)
when compiling -- otherwise all symbols are visible by default anyhow and
explicitly setting their visibility to "default" doesn't change anything.

 Of course, at the risk of repeating the obvious, ELF visibility doesn't
exist in MSW DLLs, they always use hidden visibility by default and this
can't be changed.

 Regards,
VZ

reply via email to

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