After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 731432 - Resolving "LNK4049: locally defined symbol "_xmlFree" imported" on Windows
Resolving "LNK4049: locally defined symbol "_xmlFree" imported" on Windows
Status: RESOLVED OBSOLETE
Product: libxml2
Classification: Platform
Component: general
git master
Other Windows
: Normal normal
: ---
Assigned To: Daniel Veillard
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2014-06-10 00:50 UTC by lhuxley
Modified: 2021-07-05 13:25 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description lhuxley 2014-06-10 00:50:16 UTC
I am building Libxml2 as a static library using Visual Studio 2012 on Windows.  Igor Zlatkovic's VS 2010 solution and projects port well enough to VS 2012.  

However, the dreaded LNK4049 error occurs when linking the static library into a program.  A search of the net shows that this error has been cropping up for more than a decade.

Furthermore, the MS linker generates an import library and an export file for the executable, indicating that the executable is exporting symbols.  A dump of the .lib file shows that all of the symbols are exported by Libxml2.  This is entirely unacceptable.

The Libxml2 project file includes both static and dynamic library configurations.  However, it looks like the static configurations were never fully tested (by actually linking the static libraries into an executable).

At the heart of this issue is the LIBXML_STATIC define.  It is defined at the bottom of <libxml.h>, after it is actually used in xmlexports.h (where all of the trouble happens).
  
<libxml.h> includes...
"config.h" includes...
<libxml/xmlversion.h> includes...
<libxml/xmlexports.h>

The following code at the bottom of <libxml.h> is the culprit:

#if !defined(PIC) && !defined(NOLIBTOOL)
#  define LIBXML_STATIC
#endif

That code should appear before "config.h" is included in <libxml.h>.  

Back in 2002, Igor's advice to resolve the LNK4049 error was to search for /D in win32/makefile.msvc and add the defined symbols to the compiler predefines.  Of course that doesn't work on its own.  However, my advice is to do what Igor says, but pay attention to what you're defining.  Some of the defines conflict with each other.  

Once the above change is made to <libxml.h>, the key to successfully building a static version of Libxml2 is to make sure that NOLIBTOOLS is not defined.  To build the DLL version, make sure that NOLIBTOOLS is defined.

But that still won't necessarily get rid of the LNK4049 error.  Specifically, the linker issues the following message when building the application:

warning LNK4049: locally defined symbol "_xmlFree" imported

The obvious question is why doesn't the linker complain about any other Libxml2 functions?  Actually xmlFree (and xmlMalloc, xmlRealloc and a few other seldom called functionS) are actually pointers to functions, and the linker would complain about any one of them.  By default xmlFree is declared as following in "globals.h":

XMLPUBVAR xmlFreeFunc xmlFree;

If LIBXML_STATIC isn't defined before <libxml/xmlexports.h> is included in the application, then XMLPUBVAR is declared as 

__declspec(dllimport) extern

instead of as plain "extern".  In the application, the former declaration forces the linker to jump through extra hoops to successfully link in a non-DLL symbol after it was compiled in as such.  Presumably the resulting code is less efficient and hence the LNK4049 error.

Naively following the tutorials as I have done, and including <libxml/xmlparser.h> and <libxml/xmltree.h> in my application will still result in an LNK4049 error.  It is necessary to include <libxml.h> before any other Libxml2 include files, to ensure that LIBXML_STATIC is properly defined.

There are actually several different approaches to resolving this issue.  Personally, I have chosen to comment out the 3 lines quoted above from <libxml.h> and predefine LIBXML_STATIC when building the static versions of Libxml2 itself.  Then I have added 

#define LIBXML_STATIC

before including any of the Libxml2 include files in my applications.
Comment 1 GNOME Infrastructure Team 2021-07-05 13:25:47 UTC
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org.
As part of that, we are mass-closing older open tickets in bugzilla.gnome.org
which have not seen updates for a longer time (resources are unfortunately
quite limited so not every ticket can get handled).

If you can still reproduce the situation described in this ticket in a recent
and supported software version, then please follow
  https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines
and create a new ticket at
  https://gitlab.gnome.org/GNOME/libxml2/-/issues/

Thank you for your understanding and your help.