Archive

Posts Tagged ‘xerces’

Cross building Xalan and Xerces for Mingw on Debian (2014 update)

May 19, 2014 Leave a comment

This is an update of this post.

dllwrap

Both xerces and xalan make files call dllwrap which cannot be found in a cross build environment. The real name of this command is <prefix>-dllwrap (ex: x86_64-w64-mingw32-dllwrap). I tried to create a dllwrap symlink, but I was not able to make dllwrap working at all. I fell back to the ld –out-implib flag which is what CMake use when creating dll with mingw. To do so without modifying xerces and xalan make files I created this wrapper:

#! /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]="x86_64-w64-mingw32-c++"
sys.argv.insert(1, "-shared")
sys.argv.remove('--export-all-symbols')
sys.argv.remove('--driver-name')
sys.argv.remove('c++')
print " ".join(sys.argv)
subprocess.call(sys.argv)

Then I just need to name this file dllwrap and ensure it’s in the PATH.

Xerces

The build instructions says to use set LDFLAGS=-no-undefined but even if this option is for libtool it’s also pass to g++ which will stop because it doesn’t know this option. A workaround is to run configure with -no-undefined then to manually change the Makefile after:

apt-get install g++-mingw-w64-x86-64
git clone https://github.com/apache/xerces-c.git
cd xerces-c
git checkout Xerces-C_3_1_1
./reconf
./configure --host x86_64-w64-mingw32 --prefix=/tmp/xerces-c-3.1.1
find . -name Makefile -exec sed -i 's/^LDFLAGS =/LDFLAGS = -no-undefined/g' {} \;
make && make install

Xalan

As mingw now provide the localtime_r function I needed to apply the following patch:

index c43e9df..47aa9b2 100644
--- a/src/xalanc/Include/GCCDefinitions.hpp
+++ b/src/xalanc/Include/GCCDefinitions.hpp
@@ -48,7 +48,6 @@
 #endif
 
 #if defined(__MINGW32__)
-#define XALAN_NO_REENTRANT_TIME_FUNCTIONS
 #define XALAN_WINDOWS_DIR_FUNCTIONS
 #define WINDOWS_THREAD_FUNCTIONS
 #else

Then the build is straightforward:

apt-get install g++-mingw-w64-x86-64
git clone https://github.com/apache/xalan-c.git
cd xalan-c
git checkout Xalan-C_1_11_0
export XALANCROOT=$PWD
export PATH=$PWD:$PATH
export XERCESCROOT=/tmp/xerces-c-3.1.1
./runConfigure -p cygwin -C--host -Cx86_64-w64-mingw32 -x x86_64-w64-mingw32-g++ -c x86_64-w64-mingw32-gcc -C--prefix=/tmp/xalanc-3.11
make

make install fail in bin/ because it doesn’t know how to handle the .exe extension but that’s enough for my usage.

Advertisements

Cross building Xalan and Xerces for Mingw on Linux

August 19, 2011 1 comment

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