Cross building Xalan and Xerces for Mingw on Linux
Here is how to cross-build Xerces-c 2.8 and Xalan-c 3.11-dev on Debian Wheezy, for Mingw 32bit.
Xerces
I first built Xerces this way:
apt-get install mingw-w64 apt-get source libxerces-c2-dev cd xerces-c2-2.8.0+deb1/src/xercesc export XERCESCROOT=$PWD/../.. ./runConfigure -p mingw-msys -C--host -Ci686-w64-mingw32 make
Unfortunnatly it doesn’t create any import library (libXXXX.dll.a). Mingw support linking without import library but it’s dead slow (5 minutes by executables with Xerces and Xalan). Creating an import library is easy but require to pass 2 arguments to the linker, the name of the dll and the name of the import libary. The xerces-c build machinery pass only one argument so we would need to modify each Makefile to support import library creation. A dirty workaround is to create a linker wrapper which automatically add the import library name to the link command line:
#! /usr/bin/env python
import sys
import subprocess
for i in xrange(len(sys.argv)):
if sys.argv[i] == '-o':
output_index=i+1
break
sys.argv.append("-Wl,--out-implib,%s.a" % sys.argv[output_index])
sys.argv[0]="i686-w64-mingw32-c++"
sys.argv.insert(1, "-shared")
print " ".join(sys.argv)
subprocess.call(sys.argv)
Save this file to src/xercesc/dllwrap then change Makefile.incl this as following:
--- src/xercesc/Makefile.incl 2007-08-30 14:10:20.000000000 +0200
+++ src/xercesc/Makefile.incl 2011-08-26 09:40:20.332772932 +0200
@@ -463,7 +463,7 @@
PLATFORM_COMPILE_OPTIONS = -D${PLATFORM} -fexceptions -D__GNUWIN32__ -DWIN32 -D_WINDOWS -DNDEBUG -DPLATFORM_WIN32
ifeq (${LIBTYPE},shared)
- MAKE_SHARED = dllwrap --export-all-symbols --driver-name ${CXX} ${LDFLAGS}
+ MAKE_SHARED = $(dir $(lastword $(MAKEFILE_LIST)))/dllwrap ${LDFLAGS}
MAKE_SHARED_C = ${CC} -D${PLATFORM} ${LDFLAGS}
else
PLATFORM_COMPILE_OPTIONS += -DXML_LIBRARY # switch off import/export
Re-run runConfigure and make, and the import library will be created.
Xalan
The current version of Xalan (1.10) doesn’t support Mingw so we need to use the development version.
git clone https://github.com/apache/xalan-c.git
During the build Xalan create and execute the MsgCreator command. As we are on Linux we need first to create this command for our guest OS. An other way would be to use wine (I did not tried).
git clone xalan-c xalan-c-linux cd xalan-c-linux export XALANCROOT=$PWD export XERCESCROOT=/a/path/to/xerces-c2-2.8.0+deb1 ./runConfigure -p linux make
Now let’s copy the executable to the mingw build dir.
cp bin/MsgCreator /a/path/to/xalan-c/bin
Prepare the environment:
cd /tmp/xalan-c export XALANCROOT=$PWD export XERCESCROOT=/tmp/xerces-c2-2.8.0+deb1
Use the same workaround than in Xerces:
--- a/Makefile.incl.in
+++ b/Makefile.incl.in
@@ -136,9 +136,9 @@ ifeq ($(PLATFORM), MINGW)
LDFLAGS += -Wl,--allow-multiple-definition
LINK = $(CXX) -D${PLATFORM} ${LDFLAGS}
- MAKE_SHARED = dllwrap --export-all-symbols --driver-name c++ ${LDFLAGS}
+ MAKE_SHARED = $(dir $(lastword $(MAKEFILE_LIST)))/dllwrap ${LDFLAGS}
- MAKE_SHARED_LOC = dllwrap --export-all-symbols --driver-name c++ ${LDFLAGS}
+ MAKE_SHARED_LOC = $(dir $(lastword $(MAKEFILE_LIST)))/dllwrap ${LDFLAGS}
LOC_OTHER_LINK_PARAMETERS = $(XERCES_LIB)
Xalan port to mingw is not yet finished (see the bug bug report). One thing which is missing is the support for dllexport/dllimport directives. Without this directive we would get huge library very slow to link. The following patch add support for dllexport/dllimport (It also break portability so it’s not suitable for upstream integration).
diff --git a/runConfigure b/runConfigure index 5e40257..cdbc255 100755 --- a/runConfigure +++ b/runConfigure @@ -654,7 +654,7 @@ fi # Set the extra C and C++ compiler flags # -CXXFLAGS="$compileroptions $debugflag $transcodingDefines $threadingDefines $bitstobuildDefines " +CXXFLAGS="$compileroptions $debugflag $transcodingDefines $threadingDefines $bitstobuildDefines -DXALAN_BUILD_DLL" export CXXFLAGS CFLAGS="$compileroptions $debugflag $transcodingDefines $threadingDefines $bitstobuildDefines " diff --git a/src/xalanc/Include/GCCDefinitions.hpp b/src/xalanc/Include/GCCDefinitions.hpp index c43e9df..a1bf300 100644 --- a/src/xalanc/Include/GCCDefinitions.hpp +++ b/src/xalanc/Include/GCCDefinitions.hpp @@ -26,8 +26,8 @@ // These defines provide the platform specific keywords that they need // to do this. // --------------------------------------------------------------------------- -#define XALAN_PLATFORM_EXPORT -#define XALAN_PLATFORM_IMPORT +#define XALAN_PLATFORM_EXPORT __declspec(dllexport) +#define XALAN_PLATFORM_IMPORT __declspec(dllimport) #define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT #define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT diff --git a/src/xalanc/XPathCAPI/XPathCAPI.h b/src/xalanc/XPathCAPI/XPathCAPI.h index b754c00..95bb097 100644 --- a/src/xalanc/XPathCAPI/XPathCAPI.h +++ b/src/xalanc/XPathCAPI/XPathCAPI.h @@ -20,7 +20,7 @@ -#if defined(_MSC_VER) +#if defined(_MSC_VER || __MINGW32__) #if defined(XALAN_BUILD_DLL)
Next steps are almost the same than with Xerces. For one reason we need to add -c and -x flags which were not needed for Xerces.
./runConfigure -p mingw-msys -c i686-w64-mingw32-gcc -x i686-w64-mingw32-g++ -C--host -Ci686-w64-mingw32 make