GNOME Bugzilla – Bug 731432
Resolving "LNK4049: locally defined symbol "_xmlFree" imported" on Windows
Last modified: 2021-07-05 13:25:47 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.
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.