This is an addendum to my cross-gtk page.

Example: cross-building a DLL for libxml2-2.6.14

Preliminary: we first ensure that no import lib symlinks in our cross lib directory point to Microsoft-style .lib files. We use .a import libs if available; failing that, we use DLLs.

Then we cross-configure the libxml2 build:

cross-configure --without-python --without-ftp --without-http \
    --without-readline --disable-ipv6 --disable-static 

Things go nicely until link time, when we get the following message from libtool:

*** Warning: linker path does not have real file for library -lz.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because I did check the linker path looking for a file starting
*** with libz and none of the candidates passed a file format test
*** using a file magic. Last file checked: 
/opt/cross-tools/lib/gcc/mingw32/3.4.0/../../../../mingw32/lib//zlib1.dll

And we get the same message for iconv.dll.

Why?

The "file format test" mentioned in the warning proceeds in this case via the shell function (embedded in libtool), "win32_libid". This function calls (in my case, at any rate) file -L to query the candidate lib files. Running this manually we see:

waverley:~$ file --version
file-4.10
magic file from /usr/share/file/magic

waverley:~$ file -L /opt/cross-tools/mingw32/lib/zlib1.dll            
/opt/cross-tools/mingw32/lib/zlib1.dll: \
MS-DOS executable (EXE), OS/2 or MS Windows

This response (we get the same with iconv.dll) seems wrong, since it is not flagging the file as a shared library of any sort. I'm not sure if the problem is with the magic database used by the file program, or with the build of the DLLs in question. These two DLLs are built by third parties: zlib1.dll is in the official Windows DLL distribution from gzip.org and iconv.dll is from libiconv-1.9.1.bin.woe32.zip on ftp.gnu.org. I'm reluctant to get into compiling them myself, since these are the versions used by Tor Lillqvist in his GTK build (and the make for Windows looks scary).

With other DLLs on my system, file gives a more appropriate response. Here is one I made myself:

waverley:~$ file -L stats/esl/win32/runtime/misc-dll/libgmp-3.dll 
stats/esl/win32/runtime/misc-dll/libgmp-3.dll: \
MS Windows PE Intel 80386 console DLL 

And one of Tor's:

waverley:~$ file ~/src/winbuild/windist/gretl/libglib-2.0-0.dll
/home/cottrell/src/winbuild/windist/gretl/libglib-2.0-0.dll: \
MS Windows PE Intel 80386 console DLL

Anyway, based on the output from file, libtool has got the idea that zlib1.dll and iconv.dll are not DLLs. We have two options at this point: (1) hack libtool, or (2) make our own .a import libraries.

To hack libtool I added the lines marked with "+" in the function win32_libid:

  *executable*) # but shell scripts are "executable" too...
    case $win32_fileres in
    *MS\ Windows\ PE\ Intel*)
      win32_libid_type="x86 DLL"
      ;;
+   *MS-DOS\ executable*) # ugh! some DLLs built on Windows
+     win32_libid_type="x86 DLL"
+     ;;
    esac

The hack ensures that the rogue DLLs are recognized. The build proceeds and we get a libxml2-2.dll with accompanying import library libxml2.dll.a.

The other means to the same end is to process the Microsoft-style .lib files supplied with the zlib and iconv packages, generating .a libraries that work with gcc. We then link to these instead of the DLLs. The tool for this job is reimp: the command reimp foo.lib produces an import library libfoo.a that should work. Reimp is maintained by J. R. Fonseca. I can't get his download link to work. Here is a local copy of the source: reimp.tgz.

Allin Cottrell, October 2004