[xml] MSYS and MINGW: undefined reference to _imp__xmlFree



Hi,

Most of my C/C++ experience is from Linux/GCC, so I will leave MSVC/Borland for
now (others using it might rather consider if the problems are valid for these tools
and handle it).

Although I have been building Gtk2, Glade3 and Gtk2-Perl and all their dependencies
from scratch for the last 2-3 years in a MSYS/MINGW environment, and probably
have been bitten by most issues, I will not pretend to be an expert.  If anything is
unclear or not 100% factual, I will gladly clarify or are open to being corrected.

The issue I would like to discuss is from:

http://mail.gnome.org/archives/xml/2004-February/msg00004.html
https://bugzilla.gnome.org/show_bug.cgi?id=561340 
https://bugzilla.gnome.org/show_bug.cgi?id=590302 

and the committed fix:

http://git.gnome.org/cgit/libxml2/commit/?id=a194ccb8d19ddde94c2c04ddf197e6a629f7cc9b 

The original thread and bug #561340 do not have enough output (only of the link
failure, and not of linking the object files, so I will rather not try to guess what the
circumstances was that produced the problem .  As for bug #590302, I cannot
reproduce it, and not knowing the rest of the build environment, configure options
or more output from the build, I will also rather not try to analyse it.

The root of the problem though, is that the objects (.o) are compiled WITHOUT
LIBXML_STATIC defined, and then linked to the STATIC version of the libxml
library.

Functions exported from either the dll or static library will link fine due to the
auto-import feature (dll). Variables exported from either are a different matter though.
If linking against the dll, you need:

  extern __declspec(dllimport)

and for the static library you just need (same as either static or dynamic when
dealing with Linux):

  extern

If "extern __declspec(dllimport)" was present though, the compiler adds "_imp_"
to the symbol that should be resolved at link time, which is not present if linking
against the static library and thus failing.

In the case of libxml, this is true for xmlMalloc, xmlFree and others defined in
include/libxml/globals.h, causing the failure if compiling without the define
(LIBXML_STATIC), but linking against the static version of the library.

The circumstances where I have seen this to happen is:
- only the static via ./configure inside MSYS/MINGW, and then not using
pkg-config or xml-config to get the CFLAGS, and not manually adding to
the CFLAGS the needed "-DLIBXML_STATIC"
- only the static via scripts under win32, and not manually adding to
the CFLAGS the needed "-DLIBXML_STATIC"
- both dll and static via scripts under win32.  The reason here is that the
import library then have ".lib" as extension, and ld's search order when called
with "-lxml2" seems to be: .dll.a, .a, .lib
- directly specifying libxml.a with its path to gcc/ld and not adding the
required define to CFLAGS
- possibly others I did not encounter or thought about and reproduced

As for the committed fix from:

http://git.gnome.org/cgit/libxml2/commit/?id=a194ccb8d19ddde94c2c04ddf197e6a629f7cc9b

when LIBXML_STATIC is not defined, the following now holds for linking
against both the static library and the dll:

    #define XMLPUBFUN __declspec(dllexport)
    #define XMLPUBVAR __declspec(dllexport)

Linking for both static and dll versions seems to work without any problems,
however depending on if exported variables was used, it might crash.

Functions are not marked to be exported, gets resolved at link time and are
added to the import table in the dll case, or linked in when static (I will rather not try
to guess why it works, as I have no idea how the internals of binutils work).  Variables
however, are added to the export table, but not added to the import table (for the dll
case, or resolved for static), so when a binary uses xmlMalloc, xmlFree, etc., a null
pointer is referenced (in the cases I tested), resulting in a crash.

For xmllint.exe and xmlcatalog.exe - they work fine, as they only use functions
and not any of the variables.  Try running "make check" however, and runtest.exe
will crash. (This is for 2.7.6 only - I have not checked xmllint.exe, etc. with older.)

As for fixing this issue - I guess the first will be to back out that patch again.  Then I
have thought about two possible solutions:
- deal with linking to static without LIBXML_STATIC defined by keep telling people
to not do that.  As for the failures with xmllint, etc. I can try to help debug that if I
could get more information about build environment, etc.
- rather use the approach GLIB and friends use - only allow either static or shared
builds, and define LIBXML_STATIC via the headers if needed instead of hoping
the user will remember it

Personally I thought the second approach will be the less painful in future approach,
and I made a patch as well as tested it in the situations I could think could cause the
failure.  I also redid the definitions in xmlexports.h to be more like glib's which I think
is more clear.

Comments appreciated.  Let me know if the patch is mangled and I should put it
online somewhere.


Regards,

Martin

Attachment: libxml2-2.7.6-mingw.patch
Description: Text document



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