Cross-compiling for Windows: Difference between revisions

From iMath
Jump to navigation Jump to search
Line 67: Line 67:
** 32 bit build: <code>make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" check</code>
** 32 bit build: <code>make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" check</code>
* All tests should pass successfully (note that on a 64-bit wine, the 32-bit tests will not execute)
* All tests should pass successfully (note that on a 64-bit wine, the 32-bit tests will not execute)
==== 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=i586-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


=== Compiling GiNaC ===
=== Compiling GiNaC ===

Revision as of 20:40, 7 February 2020

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. By default this will be a 64 bit version. If you need a 32-bit wine, use winearch='win32' winecfg.

Visual Studio 2017 (64 bit compiler, outputting 32 bit or 64 bit code)

  • Get a working Visual Studio installation under Windows (the community version is available for free, and works fine)
  • Set up the following file structure in your .wine/drive_c directory (for 32 bit wine, change Hostx64 to Hostx86 in the first two lines).
 vc/bin/x64 from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x64
 vc/bin/x86 from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x86
 vc/lib/x64 from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\lib\x64
 vc/lib/x86 from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\lib\x64
 vc/include from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include
 sdk/lib/ucrt/x64 from C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\ucrt\x64
 sdk/lib/ucrt/x86 from C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\ucrt\x86
 sdk/lib/um/x64 from C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x64
 sdk/lib/um/x86 from C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x86
 sdk/include/ucrt from C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\ucrt
 sdk/include/um from C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um
 sdk/include/shared from C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\shared
 sdk/include/ucrt/sys/time.h: link to ../time.h
  • If you change this structure you must also adapt the .configure calls later
  • If you are only targeting x64 or x86 you can omit the other architecture
  • Run wine regedit and add to your PATH:
    • 64 bit host, 64 bit target: C:\vc\bin\x64
    • 64 bit host, 32 bit target: C:\vc\bin\x86;C:\vc\bin\x64
  • ??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 and wine lib should now work.

Debug build

  • To get a debug build, use the flags -MDd -D_DEBUG for libraries
  • You will need to copy the debug versions of the standard libraries into the paths

Compiling CLN

For a 64 bit build, you need to have a recent CLN (>1.3.6). For best stability, please use this patched version.

Visual Studio 2017

  • For a 32 bit build, change the end of m4/intparam.m4 to look like this:
     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;]
     [if test $n = 0; then $2=; break; fi])
   n=`expr $n '+' 1`
 done
  • Run autoreconf -i
  • For a 32 bit build, edit the generated configure script, find the place void (*)(void) slot2 and change it to void (*slot2)(void)
  • Configure the build
    • 64 bit build: ./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64" CPPFLAGS="-MD -DNO_ASM -D__x86_64__ -EHsc -IC:/vc/include -IC:/vc/sdk/include/um -IC:/vc/sdk/include/ucrt -IC:/vc/sdk/include/shared" --host=amd64-mingw64msvc
    • 32 bit build: ./configure CC="wine cl" CXX="wine cl" CCAS="wine cl" LD="wine link" LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/vc/sdk/include/um -IC:/vc/sdk/include/ucrt -IC:/vc/sdk/include/shared" --host=i586-mingw32msvc
  • Edit libtool and find the two lines containing -OUT. Replace lib with wine lib
  • Edit the src/Makefile and find the line starting with .S.lo
  • Add the switch -TC before -c -o
  • Build
    • 64 bit build: make LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64"
    • 32 bit build: make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86"
  • Check
    • 64 bit build: make LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64" check
    • 32 bit build: make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" check
  • All tests should pass successfully (note that on a 64-bit wine, the 32-bit tests will not execute)

Compiling GiNaC

For a 64 bit build, you need to apply the patches in my github win64 branch.

Visual Studio 2017

  • Copy libcln.lib into ~/.wine/drive_c/local/lib/x64 (or x86) and the CLN headers into ~/.wine/drive_c/local/include/x64/cln (or x86/cln)
  • Since MSVC does not set __cplusplus correctly (?), comment out the line AX_CXX_COMPILE_STDCXX([11]) in configure.ac
  • Run autoreconf -i in the source directory
  • Configure
    • 64 bit: ./configure CC="wine cl" CXX="wine cl" LD="wine link" CLN_CFLAGS=-IC:/local/include/x64 CLN_LIBS=C:/local/lib/x64/libcln.lib LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64" CPPFLAGS="-MD -DNO_ASM -D__x86_64__ -EHsc -IC:/vc/include -IC:/vc/sdk/include/um -IC:/vc/sdk/include/ucrt -IC:/local/include" --disable-shared --enable-static --host=amd64-mingw64msvc
    • 32 bit: ./configure CC="wine cl" CXX="wine cl" LD="wine link" CLN_CFLAGS=-IC:/local/include/x86 CLN_LIBS=C:/local/lib/x86/libcln.lib LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" CPPFLAGS="-MD -DNO_ASM -EHsc -IC:/vc/include -IC:/vc/sdk/include/um -IC:/vc/sdk/include/ucrt -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!
  • Build
    • 64 bit: make LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64"
    • 32 bit: make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86"
  • 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)
  • Change to the toplevel directory again and finish the build with the same make command as before
  • Check
    • 64 bit: make LIB="C:/vc/lib/x64;C:/vc/sdk/lib/um/x64;C:/vc/sdk/lib/ucrt/x64" check
    • 32 bit: make LIB="C:/vc/lib/x86;C:/vc/sdk/lib/um/x86;C:/vc/sdk/lib/ucrt/x86" check
  • All tests should pass successfully (note that on 64 bit wine the 32 bit tests will not execute)

Visual Studio 2015 (64 bit build)

  • 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" CLN_CFLAGS=-IC:/local/include CLN_LIBS=C:/local/lib/libcln.lib 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 -D__x86_64__ -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=amd64-mingw64msvc
  • 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/amd64;C:/sdk/lib8.1/winv6.3/um/x64;C:/sdk/lib10/10.0.10240.0/ucrt/x64;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)
  • Edit config/test-driver and find the line after Test script is run here. It should begin with wine "$@"
  • GiNaC now compiles and all 58 tests pass successfully with make LIB="C:/vc/lib/amd64;C:/sdk/lib8.1/winv6.3/um/x64;C:/sdk/lib10/10.0.10240.0/ucrt/x64;C:/local/lib" check

Visual Studio 2015 (32 bit build)

  • 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" CLN_CFLAGS=-IC:/local/include CLN_LIBS=C:/local/lib/libcln.lib 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
  • 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)
  • Edit config/test-driver and find the line after #Test script is run here. It should begin with wine "$@"
  • 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

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"

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. symlink into the sdk/bin directory) but not into ~/.wine/drive_c/windows/system32, because this will confuse the office. This is required for cppumaker.exe to run

Preparing VCL dialogs

Starting with iMath 2.2.6, the dialogs are being converted to VCL (VCL provides a graphical toolkit similar to gtk+, Qt, SWING etc). VCL dialogs are not (yet) available for Apache OpenOffice.

The Makefile activates VCL dialogs under the following conditions

  • Linux: LibreOffice build
  • Windows: LibreOffice build with version at least 6.0

If you experience problems with the VCL build, you can manually edit the Makefile and set USEVCL=0.

Since VCL is not yet integrated into the Office API, you need some special preparations.

  • Download the VCL include files for your version of the SDK (replace 6-0 with your version)

git clone --branch libreoffice-6-0 --single-branch --depth 1 git://anongit.freedesktop.org/libreoffice/core

  • Move or copy the directory core/include to vclinclude-6-0
  • Move or copy the file core/solenv/clang-cl/config_global.h to the src directory
    • This file appears to be empty, at least on my platform
  • Create the following file in vclinclude-6-0
/* config_host/config_vcl.h.  Generated from config_vcl.h.in by configure. */
/*
Settings about vcl
*/
#ifndef CONFIG_VCL_H
#define CONFIG_VCL_H
/* nature of the device pixel coordinate system
 * either use sal_Int32 or double for coordinates
 */
#define VCL_FLOAT_DEVICE_PIXEL 0
#endif

As you can see, this file was taken from an Office build. You might have to create a build to get the file matching your build system. Up to now, the version given above has worked, though.

Generating the link library for Windows

Windows cannot link directly against a .dll file. Therefore you need to create a .lib from it. Find mergedlo.dll in the Office program directory and perform the following steps:

wine dumpbin /exports mergedlo.dll | cut -c27- > mergedlo.def
wine lib /def:mergedlo.def /OUT:mergedlo.lib

Leave the result in the Office program directory.

Compiling iMath (32 bit build)

  • (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\ 5)
  • 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" --host=i586-mingw32msvc
  • 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

Compiling iMath (64 bit build)

  • 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\ 5)
  • 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" --host=amd64-mingw64msvc
  • 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