Cross-compiling for Windows

From iMath
Jump to navigation Jump to search

Ubuntu, mingw32, wine and Microsoft Visual C++

General setup

It seems that an Office extension for Windows must be compiled with MSVC to be compatible. Here is a way to do this from within Ubuntu. Make sure you have mingw32 and wine installed. Then, get Microsoft Visual (Express) C++ to work under wine. Installing with vcsetup.exe, or installing Visual Studio is pretty hopeless and an overkill anyway. Instead, try this hack:

First make sure that your wine environment matches the Office you want to compile the extension for. If you are compiling for a 32-bit Office, you must install a 32-bit wine. If this does not happen automatically, use

 winearch='win32' winecfg

Visual Studio 2012

  • Get a working installation under Windows (the express version is available for free, and works fine)
  • After booting into Ubuntu, copy cl.exe, c1xx.dll, c1.dll, c2.dll, lib.exe, link.exe, mspdb100.dll, mspdb120.dll and clui.dll from the Windows Visual Express installation to .wine/drive_c/windows/system32/ or some other location in your PATH
  • Copy mt.exe from a Windows SDK installation to .wine/drive_c/windows/system32/ or some other location in your PATH
  • Get winetricks
  • Run winetricks vcrun2012. This will override msvcr120.dll with a Windows native version in the wine configuration

wine cl, wine link and wine lib should now work from a (Unix) terminal

Install the required libraries and include files somewhere (is there a better/standard location?)

mkdir ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 12/VC/lib/ ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 12/VC/include/ ~/.wine/drive_c/vc
cd ~/.wine/drive_c/vc/include
cp time.h sys
mkdir ~/.wine/drive_c/sdk
cp -aR /c/Programme/Microsoft\ SDKs/Windows/v7.1A/Lib/ ~/.wine/drive_c/sdk
cp -aR /c-ro/Programme/Microsoft\ SDKs/Windows/v7.0A/Include/ ~/.wine/drive_c/sdk

Visual Studio 2010

  • Get a working installation under Windows (the express version is available for free, and works fine)
  • After booting into Ubuntu, copy cl.exe, c1xx.dll, c1.dll, c2.dll, lib.exe, link.exe, mspdb100.dll and clui.dll from the Windows Visual Express installation to .wine/drive_c/windows/system32/ or some other location in your PATH
  • Copy mt.exe from a Windows SDK installation to .wine/drive_c/windows/system32/ or some other location in your PATH
  • Get winetricks
  • Run winetricks vcrun2010. This will override msvcr100.dll with a Windows native version in the wine configuration

wine cl, wine link and wine lib should now work from a (Unix) terminal

Install the required libraries and include files somewhere (is there a better/standard location?)

mkdir ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 10/VC/lib/ ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 10/VC/include/ ~/.wine/drive_c/vc
mkdir ~/.wine/drive_c/sdk
cp -aR /c/Programme/Microsoft\ SDKs/Windows/v7.0A/Lib/ ~/.wine/drive_c/sdk
cp -aR /c-ro/Programme/Microsoft\ SDKs/Windows/v7.0A/Include/ ~/.wine/drive_c/sdk

Compiling CLN

The latest CLN has patches applied so that it will compile with MSVC

  • Run ./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include" --host=i586-mingw32msvc
  • Edit libtool and find the two lines containing -OUT. Replace lib with wine lib
  • Run make LIB="C:/vc/lib;C:/sdk/lib"
  • make will stop and complain about missing files cl_asm.obj and cl_asm_GF2.obj
  • Depending on your CLN version, do one of the following
    • change to the src subdirectory
    • Remove cl_asm.lo and cl_asm_GF2.lo
    • Edit the Makefile and find the lines starting with cl_asm.lo: and cl_asm_GF2.lo:
    • Add the switch -TC before -c -o in the last line of the block. This will help MSVC recognize the .S extension as a valid C file
    • run make cl_asm.lo and make cl_asm_GF2.lo. This should create cl_asm.obj and cl_asm_GF2.obj
  • or (newer versions):
    • Edit the Makefile and find the line starting with .S.lo
    • Add the switch -TC before -c -o
  • Run make LIB="C:/vc/lib;C:/sdk/lib" to finish the compile
  • Run make LIB="C:/vc/lib;C:/sdk/lib" check, all tests should pass successfully

Compiling GiNaC

  • Copy libcln.lib into ~/.wine/drive_c/local/lib and the CLN headers into ~/.wine/drive_c/local/include/cln
  • Unpack the source code and run autoreconf -i in the new directory that was created. As of version 1.6.0, the GiNaC MSVC support branch has been merged with the master branch, so you can use that.
  • You can now run ./configure CC="wine cl" CXX="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include -IC:/local/include" --disable-shared --enable-static --host=i586-mingw32msvc
  • Edit the libtool created by configure:
    • The line starting with old_archive_cmds must read "wine lib -OUT:\$oldlib\$oldobjs\$old_deplibs". Note that this line occurs twice in the file!
  • In the check (and other subdirectories), when linking fails edit the Makefile and add the following to the command starting with CXXLINK: libcln.lib. This is necessary because the package config file cln.pc is in Unix format and cl cannot find the library as specified there
  • Run make LIB="C:/vc/lib;C:/sdk/lib;C:/local/lib"
  • On Windows compilation will fail in the ginsh subdirectory. Simply cd to this directory and run make -t (since we won't be needing ginsh)
  • GiNaC now compiles and all 58 tests pass successfully with make LIB="C:/vc/lib;C:/sdk/lib;C:/local/lib" check
  • If instead you get unhandled exception errors, try moving the definition of lst::info() from the .cpp file to the .h file (and don't ask me why this should make a difference). This only seems to happen when you compile with the -MT flag!

Compiling EQC

Copy libginac.lib into ~/.wine/drive_c/local/lib and the GiNaC headers into ~/.wine/drive_c/local/include/ginac (make sure you also get the headers from the parser subdirectory and put them into the /local/include/ginac directory).

  • Before starting, be sure to run make distclean
  • Run autoreconf -i and ./configure CC="wine cl" CXX="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;c:/sdk/lib" CPPFLAGS="-DEBUG -MD -EHsc -IC:/vc/include -IC:/sdk/include -IC:/local/include" --host=i586-mingw32msvc
  • Find two lines with ...lib -OUT... in libtool and change them to ...wine lib -OUT...
  • To get EQC to link successfully, you need to edit the src/Makefile and add the following to the command starting with CXXLINK: libcln.lib libginac.lib.
  • Run make LIB="C:/vc/lib;C:/sdk/lib;C:/local/lib"
  • If you get zillions of multiply-defined symbol errors, try replacing -MD with -MT when running configure (do a distclean before you re-run configure)

Preparing the Office SDK

  • Install Office and the Office SDK into wine using the standard Windows installation files. Try to run ~/.wine/drive_c/Program Files/<YOUR_OFFICE>/program/soffice.exe, if this doesn't start (cannot determine user interface language), then install it into a clean wine.
  • LibreOffice 3.4 requires installing the Visual C++ 2008 runtime libraries with winetricks vcrun2008
  • In the SDK base directory (e.g. ~/.wine/drive_c/Program Files/<YOUR_OFFICE>/sdk), edit settings/dk.mk and change the platform PLATFORM=wine.
  • Edit settings/settings.mk and add a section for wine. The iMath source subdirectory src/wine-sdk-config contains a sample that works for me, but keep in mind that the settings.mk file varies between SDK versions.
  • Go to sdk/bin and create an executable called cppumaker with content wine "$OO_SDK_HOME/bin/cppumaker.exe" "$@"
  • Go to URE/bin and do ln -s /usr/lib/ure/bin/regmerge ..
  • Install the Office DLLs where wine can find them (e.g. into the sdk/bin directory) but not into ~/.wine/drive_c/windows/system32, because this will confuse the office ("Cannot determine user interface language" error)

Compiling iMath

  • Copy libeqc.lib into ~/.wine/drive_c/local/lib and all the headers from the src subdirectory into ~/.wine/drive_c/local/include/libeqc
  • Because GNU make has problems with spaces in paths, it is strongly advisable to create a symlink to ~/.wine/drive_c/Program\ Files and any other directory that has spaces (e.g. LibreOffice\ 4)
  • Edit the config.wine file matching your Office installation in the directory src/wine-sdk-config. Set BASE= to match your wine installation directory. Edit the relevant entries at the top of the file using the symlinked directory names without spaces
  • Source this config.wine.xxx file
  • Run autoreconf -i
  • Run ./configure CC="wine cl" CXX="wine cl" LD="wine cl" MANIFEST_TOOL="wine mt" --host=i586-mingw32msvc --build=i686-pc-linux-gnu
  • Change into the source directory
  • Run make. This will produce an error about mt.exe at the end of the process. Just run make again and the extension is created in the iMathout directory