Friday, May 11, 2012

Issues I encountered when compiling LibXML2 as a shared library

I suppose most of you are aware that when you extract the libxml2 source, there is a folder called win32. Inside is a configure.js which works like a charm, and a makefile.mingw which is what I use.

The Makefile.mingw file needs to be manually edited with paths where the *.o file will reside, otherwise it will fail immediately.
Other than that, a static library is produced. So far so good, but I needed a shared library as well, one which wasn't produced with that specific Makefile.

I CD'ed back once, and used the default ./configure file, which produces not only a static library, but a shared one as well, and the size is even smaller than the one from the Makefile.mingw file in the win32 folder.
This is where the problems begin. Linking my application with either library caused a crash in my application.
The crash was specifically caused by the library being built with pthreads support(not with pthreads-win32 compatability apparently), instead of native thread support for Windows.

I then went to the XMLSOFT mail list, where I wrote about my issue and it was suggested to apply a patch to enable win32 thread support by default on Windows based machines.
After applying the patch, the output from the compilation suggested enabled native thread support, as did the config.log file, unfortunately the libraries built still caused a crash in libpthread-2.dll, apparently it was still built with pthreads support.

I then CD'ed into to the win32 folder and produced the stable static library, which although it increases the overall size of my app by at least 900KB, it causes no crash as it uses native Win32 threads.

As of writing this post, I've yet to find a solution.

Saturday, May 5, 2012

Issues you may encounter when compiling LibXML2

I did not encounter this error before, but on my second compilation months after, I got a weird error saying:
testThreads.c:110:6: error: conversion to non-scalar type requested

So wondering what is wrong, I immediately opened Google and looked on how to resolve it. I found it pretty fast.

pthread_t under Windows is a structure, so the operations performed in testThreads.c on pthread_t are invalid.

I found the fix here, but in case it gets deleted, I am also posting it here.

Open testThreads.c and scroll down to line 110. Change this line:
tid[i] = (pthread_t) -1;
to this
tid[i].p= NULL;

After this, re-issue `make` and all should be good to go.

An important thing to note, is that linking to libxml2.a, or -lxml2 when fed to GCC automatically produces a statically linked executable to libxml2 IF it was compiled from withing the win32 folder and using makefile.mingw, increasing your executable size by at least 900KB.

While static linking makes redistributing your application easier, it also increases the size of the executable unnecessarily. In order to compile your application without statically linking to libxml2 and assuming you have libxml2-2.dll and libxml2.dll.a, you need to change
-lxml2 to -lxml2.dll 

After that, you will need to redistribute your application with the libxml2-2.dll.

Shared library under windows seems to broken for now, so I wouldn't count on it at this point.

Statically linking pthreads-w32

Perhaps some of you are wondering why would anyone use POSIX threads under Windows? Simply put, because we can. In case you did not know, yes, there is a port of them for Windows, even pthreads-w64 for MinGW-W64.

Unfortunately, statically linking Pthreads to your app is much trickier than any other library I've encountered.
It requires what is called "Manual Initialization". It looked complicated, and I as a beginner couldn't yet follow those instructions, so I've never really bothered trying to do it.

The Pthreads-W32 port dev team have also provided information on how to do it. Just look at their README and their README on non-portable code(aka static linking).

How to statically link PCRE to your app in Windows with GCC

I usually face many problems when trying to statically link *some* library to my application, but thank god I almost always find a solution.

In order to statically link PCRE to your application in Windows using GCC, you must have a static version of it.
When you compile PCRE you usually end up with a libpcre-1.dll,libpcre.a,libpcre.dll.a files. You obviously wish to use LIBPCRE.A, which is the static version of PCRE.

You need to add this macro before you include pcre.h in your application:

#define PCRE_STATIC 1

So it looks like this:
#define PCRE_STATIC 1
#include <pcre.h>

After this, in your makefile, command line, Dev-CPP,Code::Blocks or whatever build options you need to add the following line:
-Wl,-Bstatic -lpcre

In case -lpcre is *NOT* the last library you include you may need to write it like so
-Wl,-Bstatic -lpcre -Wl,-Bdynamic
in order to ensure, that the linker doesn't try to statically link whatever libraries follow