build wxWidgets dll without __declspec(dllexport) for MinGW target

220 views
Skip to first unread message

asmwarrior

unread,
Oct 16, 2015, 12:41:29 AM10/16/15
to wx-u...@googlegroups.com
Hi, I just see in the source \include\wx\dlimpexp.h

/*
While gcc also supports __declspec(dllexport), it creates unusably huge
DLL files since gcc 4.5 (while taking horribly long amounts of time),
see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43601. Because of this
we rely on binutils auto export/import support which seems to work
quite well for 4.5+.
*/
# elif defined(__GNUC__) && !wxCHECK_GCC_VERSION(4, 5)
/*
__declspec could be used here too but let's use the native
__attribute__ instead for clarity.
*/
# define WXEXPORT __attribute__((dllexport))
# define WXIMPORT __attribute__((dllimport))
# endif

Which means, if I build wx with gcc 4.5 or later, we don't have dllexport decoration.
By ld's document: ld and WIN32 (cygwin/mingw) -
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/win32.html
The default option is: -export-all-symbols.

Read some discussion:
43601 – Enormous increase in DLL object files size in 4.5 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43601
This is the way said as the comment 12.

But now, we can build wx with the option: -fno-keep-inline-dllexport
Such as stated in: Charles Wilson - [ANNOUNCEMENT] Updated: mingw-gcc-{core,g++,fortran,objc}-4.7.3-1; NEW:
- https://cygwin.com/ml/cygwin/2013-07/msg00362.html
Or wiki: Compiling wxWidgets with MinGW - WxWiki - https://wiki.wxwidgets.org/Compiling_wxWidgets_with_MinGW#Memory_Exhausted_.28bin.2Fld.exe:_out_of_memory_allocating_N_bytes.29

So, my question is: can we enable the __declspec(dllexport) for later GCC version(such as GCC 4.7 and later version)
and combined with the -fno-keep-inline-dllexport? The issue for the GCC bug #43601 is still valid?

Since I see an issue: if I want to export a symbol from my own dll, the symbol is defined as:
WX_DECLARE_EXPORTED_OBJARRAY(RegExStruct, RegExArray);
And actually, this symbol does not have dllexport decoration because it use the WXEXPORT, but it expand to nothing in my MinGW-w64 GCC 5.2.
See: Re: Build C::B against wx3.02 with gcc 5.2 under Windows - http://forums.codeblocks.org/index.php/topic,20607.msg140504.html#msg140504

Thanks.

Asmwarrior

asmwarrior

unread,
Oct 16, 2015, 1:00:56 AM10/16/15
to wx-u...@googlegroups.com
It looks like someone has already done that?
See this patch:
MINGW-packages/wxWidgets-3.0.0-gcc-codelight.patch at master · Alexpux/MINGW-packages - https://github.com/Alexpux/MINGW-packages/blob/master/mingw-w64-wxwidgets/wxWidgets-3.0.0-gcc-codelight.patch


Vadim Zeitlin

unread,
Oct 16, 2015, 11:36:02 AM10/16/15
to wx-u...@googlegroups.com
On Fri, 16 Oct 2015 12:52:28 +0800 asmwarrior wrote:

a> Hi, I just see in the source \include\wx\dlimpexp.h
a>
a> /*
a> While gcc also supports __declspec(dllexport), it creates unusably huge
a> DLL files since gcc 4.5 (while taking horribly long amounts of time),
a> see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43601. Because of this
a> we rely on binutils auto export/import support which seems to work
a> quite well for 4.5+.
a> */
a> # elif defined(__GNUC__) && !wxCHECK_GCC_VERSION(4, 5)
a> /*
a> __declspec could be used here too but let's use the native
a> __attribute__ instead for clarity.
a> */
a> # define WXEXPORT __attribute__((dllexport))
a> # define WXIMPORT __attribute__((dllimport))
a> # endif
a>
a> Which means, if I build wx with gcc 4.5 or later, we don't have
a> dllexport decoration.

Yes.

a> But now, we can build wx with the option: -fno-keep-inline-dllexport
a> Such as stated in: Charles Wilson - [ANNOUNCEMENT] Updated: mingw-gcc-{core,g++,fortran,objc}-4.7.3-1; NEW:
a> - https://cygwin.com/ml/cygwin/2013-07/msg00362.html

The post says that this option can be used for all files but one, but we
still need to generate DLL exported versions of inline methods from
somewhere, see the "source file, that includes all headers" part. I don't
understand how can things work if -fno-keep-inline-dllexport is used
globally, the inline methods then must not be exported from the library at
all and so any code using them with inlining disabled should fail to link.

a> So, my question is: can we enable the __declspec(dllexport) for later
a> GCC version(such as GCC 4.7 and later version) and combined with the
a> -fno-keep-inline-dllexport? The issue for the GCC bug #43601 is still
a> valid?

I haven't tested this with any recent gcc versions. It would be useful if
you could do it and let us know how do the numbers (object files size, DLL
size, build time) change if you remove "wxCHECK_GCC_VERSION(4, 5)" above.

a> Since I see an issue: if I want to export a symbol from my own dll, the
a> symbol is defined as:
a> WX_DECLARE_EXPORTED_OBJARRAY(RegExStruct, RegExArray);

First of all, you shouldn't use wx arrays at all unless there is a really
good reason to do it. Second, if you do use them, you should be using
WX_DECLARE_USER_EXPORTED_OBJARRAY() which allows you to specify your own
__attribute__((whatever)) as needed.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

asmwarrior

unread,
Oct 17, 2015, 3:29:54 AM10/17/15
to wx-u...@googlegroups.com
Hi, thanks for the reply, I have just build the version which enable the __declspec(dllexport).
The compiler I use is MinGW-build gcc 5.2(32bit), I don't measure the time, but here is my build command:

mingw32-make -f makefile.gcc USE_XRC=1 SHARED=1 MONOLITHIC=1 BUILD=debug UNICODE=1 USE_OPENGL=1 VENDOR=cb CXXFLAGS="-Wno-unused-local-typedefs -Wno-deprecated-declarations -fno-keep-inline-dllexport" >log-debug.txt 2>&1

The reason I use the debug version of wx is the release build crash C::B on Windows XP, see my post:
help: wired crash issue which only happens in Windows XP system with release build of wx 3.0.2 - Google Groups - https://groups.google.com/forum/?fromgroups#!topic/wx-users/6sAlKVVpQiI

Now, I run strip command on the generated wxmsw30ud_gcc_cb.dll. wxWidgets 3.0.2

original version dllexport enabled version
The file size: 15203KB 13924KB
exported symbol number:49307 21414

So, this indeed has benefits. Also, I don't see the "-fno-keep-inline-dllexport" used globally cause any issue.

>
> a> Since I see an issue: if I want to export a symbol from my own dll, the
> a> symbol is defined as:
> a> WX_DECLARE_EXPORTED_OBJARRAY(RegExStruct, RegExArray);
>
> First of all, you shouldn't use wx arrays at all unless there is a really
> good reason to do it. Second, if you do use them, you should be using
> WX_DECLARE_USER_EXPORTED_OBJARRAY() which allows you to specify your own
> __attribute__((whatever)) as needed.
>
Because, in Codeblocks' source code, it has some kinds of WX_DECLARE_OBJARRAY usage.
The codeblocks.dll is build with "-export-all-symbols" enabled in its linker option, so it don't cause any issue.
But since I want to use the __declspec(dllexport) to the export symbols from codeblocks.dll, WX_DECLARE_OBJARRAY or WX_DECLARE_EXPORTED_OBJARRAY cause the issue.

Finally, I solve the issue by using the method you mentioned:
WX_DECLARE_USER_EXPORTED_OBJARRAY(RegExStruct, RegExArray, DLLIMPORT);

Thanks.
Asmwarrior

Vadim Zeitlin

unread,
Oct 17, 2015, 8:44:52 AM10/17/15
to wx-u...@googlegroups.com
On Sat, 17 Oct 2015 15:40:57 +0800 asmwarrior wrote:

a> Hi, thanks for the reply, I have just build the version which enable the
a> __declspec(dllexport). The compiler I use is MinGW-build gcc 5.2(32bit),
a> I don't measure the time,

What about the object files size, has it remained reasonable?

a> Now, I run strip command on the generated wxmsw30ud_gcc_cb.dll. wxWidgets 3.0.2
a>
a> original version dllexport enabled version
a> The file size: 15203KB 13924KB
a> exported symbol number:49307 21414
a>
a> So, this indeed has benefits.

Yes, 8% of reduction in size is not bad. Maybe we should reenable the use
of DLL export attribute, the question is starting from which version this
should be done. 4.7 I guess?

a> Also, I don't see the "-fno-keep-inline-dllexport" used globally cause
a> any issue.

I still wonder what happens if you compile the code using the library with
-fno-inline with such build. AFAIU it should fail to link. Of course, maybe
it's not such a huge problem in practice...

AsmWarrior

unread,
Oct 23, 2015, 6:06:29 PM10/23/15
to wx-users


On Saturday, October 17, 2015 at 8:44:52 PM UTC+8, Vadim Zeitlin wrote:
On Sat, 17 Oct 2015 15:40:57 +0800 asmwarrior wrote:

a> Hi, thanks for the reply, I have just build the version which enable the
a> __declspec(dllexport). The compiler I use is MinGW-build gcc 5.2(32bit),
a> I don't measure the time,

 What about the object files size, has it remained reasonable?

Hi, Vadim Zeitlin, sorry for the late reply.
The previous build of wx is overwrite by the new build, so I don't have a object files size comparsion, the folder named msw/gcc_mswuddll is currently about 450M. That's the size of the new build objects, note that I have "-g" option in the command line, so the objects contain debug information.

a> Now, I run strip command on the generated wxmsw30ud_gcc_cb.dll. wxWidgets 3.0.2
a>
a>                        original version          dllexport enabled version
a> The file size:         15203KB                   13924KB
a> exported symbol number:49307                     21414
a>
a> So, this indeed has benefits.

 Yes, 8% of reduction in size is not bad. Maybe we should reenable the use
of DLL export attribute, the question is starting from which version this
should be done. 4.7 I guess?

I agree. 4.7 is OK.

 

a> Also, I don't see the "-fno-keep-inline-dllexport" used globally cause
a> any issue.

 I still wonder what happens if you compile the code using the library with
-fno-inline with such build. AFAIU it should fail to link. Of course, maybe
it's not such a huge problem in practice...


You mean I use "-fno-inline" when building some applications? I haven't tried it.
I see that normally, when I build applications, I don't add the "-fno-keep-inline-dllexport"option, and the result application works fine. So, it is not a big deal as I can see.

Asmwarrior

Vadim Zeitlin

unread,
Oct 25, 2015, 8:46:12 AM10/25/15
to wx-u...@googlegroups.com
On Fri, 23 Oct 2015 15:06:28 -0700 (PDT) AsmWarrior wrote:

A> > a> Now, I run strip command on the generated wxmsw30ud_gcc_cb.dll.
A> > wxWidgets 3.0.2
A> > a>
A> > a> original version dllexport enabled
A> > version
A> > a> The file size: 15203KB 13924KB
A> > a> exported symbol number:49307 21414
A> > a>
A> > a> So, this indeed has benefits.
A> >
A> > Yes, 8% of reduction in size is not bad. Maybe we should reenable the use
A> > of DLL export attribute, the question is starting from which version this
A> > should be done. 4.7 I guess?
A>
A> I agree. 4.7 is OK.

I've reenabled the use of explicit attributes for 4.7 and later now, see

https://github.com/wxWidgets/wxWidgets/commit/db966da330a1caf634df8f96dd78640b7d9695fb

Please let me know if anybody runs into any new problems after this change.

Thanks,
Reply all
Reply to author
Forward
0 new messages