Difference between revisions of "Cross-compiling for Windows"

From iMath
Jump to: navigation, search
(Compiling iMath (64 bit build))
m (Compiling CLN)
Line 39: Line 39:
 
=== Compiling CLN ===
 
=== Compiling CLN ===
  
For a 64 bit build, you need to have a recent CLN (>1.3.6). For best stability, please use this [https://github.com/jrheinlaender/cln/tree/wx64 patched version].
+
For a 64 bit build, you need to have a recent [https://www.ginac.de/CLN/ CLN] (>1.3.6). For best stability, please use this [https://github.com/jrheinlaender/cln/tree/wx64 patched version].
  
 
==== Visual Studio 2017 ====
 
==== Visual Studio 2017 ====

Revision as of 08:19, 8 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 a recent version of GiNaC (>1.7.8).

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 or replace it with AX_CXX_COMPILE_STDCXX([11], [ext], [optional])
  • 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)

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

Copy libginac.lib into ~/.wine/drive_c/local/lib/x64 (or x86) and the GiNaC headers (also from the parser subdirectory) into ~/.wine/drive_c/local/include/x64/ginac (or x86/ginac)

  • 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
  • 32 bit build: Run ./configure CC="wine cl" CXX="wine cl" LD="wine cl" --host=i586-mingw32msvc
  • 64 bit build: 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