Cross-compiling for Windows: Difference between revisions

From iMath
Jump to navigation Jump to search
(Updated documentation for 64bit build)
Line 81: Line 81:
=== Compiling CLN ===
=== Compiling CLN ===


==== Visual Studio 2015 ====
==== Visual Studio 2015 (64 bit build) ====


* Change the end of m4/intparam.m4 to look like this, and re-run autoreconf -i.
* Change the end of m4/intparam.m4 to look like this, and re-run autoreconf -i.
Line 99: Line 99:
* Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" check, all tests should pass successfully
* Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" check, all tests should pass successfully


==== Visual Studio 2015 (32 bit build) ====
* Change the end of m4/intparam.m4 to look like this, and re-run autoreconf -i.
    AC_TRY_COMPILE([
#include <stddef.h>
struct alignof_helper { char slot1; $1 slot2; };
], [typedef int verify[2*(offsetof(struct alignof_helper, slot2) == $n) - 1];],
      [$2=$n; break;]
* Edit the generated configure script, find the place <code>void (*)(void) slot2</code> and change it to <code>void (*slot2)(void)</code>
* Run <code>./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include8.1/um -IC:/sdk/include8.1/shared -IC:/sdk/include10/10.0.10240.0/ucrt" --host=x86-mingw32msvc</code>
* Edit libtool and find the two lines containing <code>-OUT</code>. Replace <code>lib</code> with <code>wine lib</code>
* Run <code>make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86"</code>
* make will stop and complain about missing files cl_asm.obj and cl_asm_GF2.obj
* Edit the src/Makefile and find the line starting with <code>.S.lo</code>
* Add the switch -TC before -c -o
* Run <code>make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86"</code> to finish the compile
* Run <code>make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" check</code>, all tests should pass successfully


==== Visual Studio 2012 or older ====
==== Visual Studio 2012 or older ====

Revision as of 20:45, 22 February 2018

Ubuntu, 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 a recent wine installed. Then, get Microsoft Visual 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

For a 64-bit wine, use

 winearch='win64' winecfg

Visual Studio 2015 (32 bit compiler, outputting 64 bit code)

  • Get a working Visual Studio installation under Windows (the community version is available for free, and works fine)
  • After booting into Ubuntu, create the directory .wine/drive_c/bin and copy the following files into it
 .../Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe, cl.exe, c1xx.dll, c1.dll, c2.dll, lib.exe, link.exe
 .../Microsoft Visual Studio 14.0/VC/bin/mspdb140.dll
 .../Microsoft Visual Studio 14.0/VC/redist/x86/Microsoft.VC140.CRT/msvcp140.dll
 .../Microsoft Visual Studio 14.0/VC/redist/x86/Microsoft.VC140.CRT/vcruntime140.dll
 .../Microsoft Visual Studio 14.0/VC/bin/x86_amd64/1031/clui.dll (creating directory bin/1031 in wine)
  • Use regedit to add the bin/ directory to the PATH
  • Copy mt.exe from a Windows SDK installation to .wine/drive_c/bin/
  • Get winetricks (you need a recent version)
  • Run winetricks vcrun2015. This will override msvcp140.dll with a Windows native version in the wine configuration

wine cl, wine link, wine lib and wine mt should now work from a (Unix) terminal. The compiler should output something like

 ...Version 19.00.24215.1 for x64

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 14/VC/lib/ ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 14/VC/include/ ~/.wine/drive_c/vc
mkdir ~/.wine/drive_c/sdk
cp -aR /c/Programme/Windows\ Kits/8.1/Lib/ ~/.wine/drive_c/sdk/lib8.1
cp -aR /c/Programme/Windows\ Kits/8.1/Include/ ~/.wine/drive_c/sdk/include8.1
cp -aR /c/Programme/Windows\ Kits/10/Lib/ ~/.wine/drive_c/sdk/lib10
cp -aR /c/Programme/Windows\ Kits/10/Include/ ~/.wine/drive_c/sdk/include10
cp ~/.wine/drive_c/sdk/include10/10.0.10240.0/ucrt/time.h ~/.wine/drive_c/sdk/include10/10.0.10240.0/ucrt/sys

Visual Studio 2015 (32 bit compiler outputting 32 bit code)

The C++ compiler needs at least wine version 1.8 to work.

  • Get a working installation under Windows (the community 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, mspdb140.dll and clui.dll from the Windows Visual Studio 2015 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 (you need a recent version)
  • Run winetricks vcrun2015. This will override msvcp140.dll with a Windows native version in the wine configuration

wine cl, wine link, wine lib and wine mt 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 14/VC/lib/ ~/.wine/drive_c/vc
cp -aR /c/Programme/Microsoft Visual Studio 14/VC/include/ ~/.wine/drive_c/vc
mkdir ~/.wine/drive_c/sdk
cp -aR /c/Programme/Windows\ Kits/8.1/Lib/ ~/.wine/drive_c/sdk/lib8.1
cp -aR /c/Programme/Windows\ Kits/8.1/Include/ ~/.wine/drive_c/sdk/include8.1
cp -aR /c/Programme/Windows\ Kits/10/Lib/ ~/.wine/drive_c/sdk/lib10
cp -aR /c/Programme/Windows\ Kits/10/Include/ ~/.wine/drive_c/sdk/include10
cp ~/.wine/drive_c/sdk/include10/10.0.10240.0/ucrt/time.h ~/.wine/drive_c/sdk/include10/10.0.10240.0/ucrt/sys

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

Compiling CLN

Visual Studio 2015 (64 bit build)

  • Change the end of m4/intparam.m4 to look like this, and re-run autoreconf -i.
    AC_TRY_COMPILE([
#include <stddef.h>
struct alignof_helper { char slot1; $1 slot2; };
], [typedef int verify[2*(offsetof(struct alignof_helper, slot2) == $n) - 1];],
      [$2=$n; break;]
  • Edit the generated configure script, find the place void (*)(void) slot2 and change it to void (*slot2)(void)
  • Run ./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib/amd64;C:/sdk/lib8.1/winv6.3/um/x64;C:/sdk/lib10/10.0.10240.0/ucrt/x64" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include8.1/um -IC:/sdk/include8.1/shared -IC:/sdk/include10/10.0.10240.0/ucrt" --host=amd64-mingw64msvc
  • Edit libtool and find the two lines containing -OUT. Replace lib with wine lib
  • Run make LIB="C:/vc/lib/amd64;C:/sdk/lib8.1/winv6.3/um/x64;C:/sdk/lib10/10.0.10240.0/ucrt/x64"
  • make will stop and complain about missing files cl_asm.obj and cl_asm_GF2.obj
  • Edit the src/Makefile and find the line starting with .S.lo
  • Add the switch -TC before -c -o
  • Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" to finish the compile
  • Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" check, all tests should pass successfully

Visual Studio 2015 (32 bit build)

  • Change the end of m4/intparam.m4 to look like this, and re-run autoreconf -i.
    AC_TRY_COMPILE([
#include <stddef.h>
struct alignof_helper { char slot1; $1 slot2; };
], [typedef int verify[2*(offsetof(struct alignof_helper, slot2) == $n) - 1];],
      [$2=$n; break;]
  • Edit the generated configure script, find the place void (*)(void) slot2 and change it to void (*slot2)(void)
  • Run ./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include8.1/um -IC:/sdk/include8.1/shared -IC:/sdk/include10/10.0.10240.0/ucrt" --host=x86-mingw32msvc
  • Edit libtool and find the two lines containing -OUT. Replace lib with wine lib
  • Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86"
  • make will stop and complain about missing files cl_asm.obj and cl_asm_GF2.obj
  • Edit the src/Makefile and find the line starting with .S.lo
  • Add the switch -TC before -c -o
  • Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" to finish the compile
  • Run make LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" check, all tests should pass successfully

Visual Studio 2012 or older

  • 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
  • Edit the src/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

Visual Studio 2015

  • Copy libcln.lib into ~/.wine/drive_c/local/lib and the CLN headers into ~/.wine/drive_c/local/include/cln
  • Unpack the source code
  • Since MSVC does not set __cplusplus correctly (?), comment out the line AX_CXX_COMPILE_STDCXX([11]) in configure.ac
  • Run autoreconf -i in the new directory that was created.
  • You can now run ./configure CC="wine cl" CXX="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/sdk/include8.1/um -IC:/sdk/include10/10.0.10240.0/ucrt -IC:/local/include" --disable-shared --enable-static --host=i586-mingw32msvc
  • Remove #include <unistd.h> from excompiler.cpp since it is unnecessary and does not exist in Windows
  • 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/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86;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/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86;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!

Visual Studio 2012 or older

  • 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.
  • 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

Important note: The EQC library code has been integrated into iMath 2.1.5 and higher, so compiling EQC separately becomes superfluous.

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).

Visual Studio 2015

  • Run autoreconf -i and /configure CC="wine cl" CXX="wine cl" LD="wine link" MANIFEST_TOOL="wine mt" LIB="C:/vc/lib;C:/sdk/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86" CPPFLAGS="-DEBUG -MD -EHsc -IC:/vc/include -IC:/sdk/include8.1/um -IC:/sdk/include10/10.0.10240.0/ucrt -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/lib8.1/winv6.3/um/x86;C:/sdk/lib10/10.0.10240.0/ucrt/x86;C:/local/lib"

Visual Studio 2012 or older

  • 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, then install it into a clean wine.
  • Remember to install 64-bit versions of the Office and SDK if you set up a 64-bit Visual C++ environment
  • 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 (for Apache OpenOffice, create a file called config.guess in the sdk subdirectory with contents echo wine; exit 0)
  • 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" "$@"
  • 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

Compiling iMath

  • (Only for iMath versions before 2.1.5) 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