GNOME Bugzilla – Bug 138402
[cygwin patch] Symbols not exported from DLL
Last modified: 2011-02-18 16:07:24 UTC
Programs fail to link with cygglib.dll on Cygwin, because only five symbols are exported. This is because __declspec(dllimport) is used, which prevents symbol automatic export. The patch makes this conditional only for G_OS_WIN32, rather than G_PLATFORM_WIN32, so all the symbols are correctly exported when building on Cygwin.
Created attachment 26058 [details] [review] rl-glib-CVSHEAD-cygwin-exports.patch Against CVS HEAD.
So building on Cygwin doesn't use the .def file? Patch looks fine.
I think the def file is ignored, and all symbols are exported. However, when __declspec(dllimport) is used, this overrides automatic symbol export, so disabling this for Cygwin makes the default behaviour work correctly. At least, this is what I *think* happens, according to the gcc/ld docs.
I think it might even be that with current gcc and/or binutils, the __declspec (dllexport) declarations for variables aren't necessary for mingw either, and just having them in the .def file would be enough. At some point it didn't work that way, variables weren't exported if they were only mentioned in the .def file.
Adding the PATCH keyword.
Is it only __declspec(dllexport) of variable *definitions* that cause problems on Cygwin? I mean, these five variables are also *declared* with __declspec (dllexport) in various header files.
Removing the declarations in the headers breaks GModule. I don't entirely understand how linking works on Windows, but it appears that the build and tests are OK with the original patch, but the removing all __declspec declarations from the headers on Cygwin breaks the GModule checks. I'm unsure of the effect on GType or GParamSpec, but it seems that whilst removing all of the __declspec(dllimport) declarations is OK, but __declspec(dllexport) in gmodule.h is still required (even though dllexport breaks when used in source files). I've attached two patches. The first is not broken, though I'm not sure exactly how it will impact on modules not built in the GLib tree. This might possibly cause breakage, though "make check" shows it works. The second breaks "make check" module-test. I'm unsure why, but perhaps the test modules need .def files if dllexport isn't used? [the other symbols where I removed dllexport also appear in the def file]. This corresponds with what I've read in the GCC info manual: exports are either automatic with -export-all or are done with the def file. glib is doing the latter, making __declspec(dllimport) unnecessary. Apparently, __declspec(dllimport) is also unnecessary since ld will auto-resolve symbols if passed --enable-auto-import. I can't see this being used, but I do see automatic import of some symbols (perhaps GCC passes it automatically?). Perhaps it's best to leave these patches, since they seem OK without them (the original patch is still required however). With a bit of tweaking, I think these two patches might eventually work too, but it might cause unacceptable breakage in other packages? Regards, Roger (and to think that once upon a time I thought UNIX shared libraries were complicated enough ;-)
Created attachment 26407 [details] [review] rl-glib-CVSHEAD-cygwin-gmodule2.patch Works, but could it break other packages?
Created attachment 26408 [details] [review] rl-glib-CVSHEAD-cygwin-gmodule-BROKEN.patch This breaks make check (module-test), but I think this is because the test modules don't have a .def file. This is a little worrying though--if a .def file is created, the existing headers will still add __declspec(dllexport), which will break any module that /does/ have a .def file (I think).
We must also remember that GLib is intended to be buildable with Microsoft's tools. Even more importantly, GLib-using code should be buildable with Microsoft's tools. It must be possible to build GLib with MSVC and use the resulting DLL from gcc-compiled code and vice versa. The Microsoft linker doesn't do auto-imports of variables, so the __declspec(dllimport) declarations are definitely needed in the headers. If we can assume an auto-importing GNU linker, they could be conditional on _MSC_VER, but as they don't do any harm with gcc, why bother. I think my conclusion so far is that the __declspec(dllexport) declarations for the variable definitions in the source files can be removed (as you originally suggested, if they cause harm on Cygwin and are otherwise unnecessary), but other things are best left as is?
> I think my conclusion so far is that the __declspec(dllexport) declarations for > the variable definitions in the source files can be removed (as you originally > suggested, if they cause harm on Cygwin and are otherwise unnecessary), but > other things are best left as is? I think this is the best thing to do. (Longer-term, since Cygwin doesn't strictly require any __declspec stuff, I'd like the toolchain to take care of automatic symbol export, too. If the defaults were changed, I think this could be done today. This probably just requires some libtool tweaks to adjust the gcc and linker flags. This isn't urgent though.)
*** Bug 139491 has been marked as a duplicate of this bug. ***
BTW, Hans, can you confirm that the __declspec(dllexport) attributes can be removed from the variable definitions in the .c files?
Or actually, I think I did confirm myself that they aren't needed for MSVC builds, either. Removed them and committed.
Confirmed, too. Dia already did it (searched for DIAVAR in all of dia/lib and found only in header files).