Tech update: LibreOffice cross compile MSI installer generation

Table of Contents

I’m working on allowing a Windows Installer (.msi) for LibreOffice to be built when cross compiling under Linux. So far, it has been a broad spanning project and has covered:

  • Windows, MSI and Cabinet APIs (C, SQL, Wine, winegcc)
  • LibreOffice build system (Perl, autotools)

Project status as of posting:

  • Developing on openSUSE 12.1 (x86_64) to target Windows (i686).
  • .msi files can be created and taken apart with the cross MSI tools (cgit) msidb and msiinfo.
  • Cabinet files can be extracted but not created. However, parsing Diamond Directive file (.ddf) format is supported through makecab (this is required when the LO build system creates a cabinet).
  • Remaining: hook up MSI transforms and patches (msitran and msimsp); fit the tools into the build system; clean up and maintenance.

The MSDN documentation for the win32 native tools has been linked to where appropriate.

1.1 Cross compiling LibreOffice

Luckily, LibreOffice cross compile support is already very good. README.cross in the LibreOffice root directory has far more information. Assuming you have checked out LibreOffice and have all the MinGW dependencies, cross compiling can be as simple as changing <lo_root>/autogen.lastrun to read:

CC=ccache i686-w64-mingw32-gcc
CXX=ccache i686-w64-mingw32-g++
CC_FOR_BUILD=ccache gcc
CXX_FOR_BUILD=ccache g++
–with-distro=LibreOfficeMinGW

This references <lo_root>/distro-configs/LibreOfficeMinGW.conf. This folder
contains various configurations for compiling under different circumstances. I
also found it helpful to add this line to LibreOfficeMinGW.conf to make life
simpler:

–without-java

1.2 Building the installer

The installer build logic can be found in <lo_root>/solenv/bin/modules/installer/windows. It makes use of several Microsoft utilities to eventually output an MSI file. Some of these utilities are already distributed by Wine.
Provided by Wine:
expand.exe – Used to unpack cabinet files.
cscript.exe – Command line script host.
Also expected:
msidb.exe – Manipulates installer database tables and streams.
msiinfo.exe – Manipulates installer meta data (summary information).
makecab.exe – Compresses files into cabinets.
msimsp.exe – Creates patch packages.
msitran.exe – Generates and applies database transforms.

Wine already exposes most of the required functionality via the API exposed by msi.dll (MSDN, Wine) and cabinet.dll (MSDN, Wine). My work has been focussed on writing command line utilities that support the interface expected by the LibreOffice build scripts.

  • solenv/bin/make_installer.pl is a very large Perl script that connects up the Perl modules which build the installer. The .pm files relevant to cross MSI building are listed below.
  • solenv/bin/modules/installer/control.pm performs “nativeness” logic such as checking if the environment is Cygwin and whether the required utilities are in the system path.
  • solenv/bin/modules/installer/windows/admin.pm (expand.exe*, msidb.exe, msiinfo.exe)
  • solenv/bin/modules/installer/windows/mergemodule.pm (expand.exe*, msidb.exe)
  • solenv/bin/modules/installer/windows/msiglobal.pm (msidb.exe, msiinfo.exe, cscript.exe*, msitran.exe**, makecab.exe**)
  • solenv/bin/modules/installer/windows/msp.pm (msidb.exe, msimsp.exe**)
  • solenv/bin/modules/installer/windows/update.pm (msidb.exe)
  • * Distributed by Wine
    ** In progress

1.3 Cross MSI tool development

The code for these tools can be found in the the feature/crossmsi branch of libreoffice. It currently resides in setup_native/source/win32/wintools in the tree.

To test the tools individually, grab the dev Makefile and make from the tool’s directory. You can then pass the -? or /? command for usage. I would suggest disabling Wine’s debug logs unless you specifically need them:

$ export WINEDEBUG=-all

  • msidb (MSDN msidb, LibreOffice msidb, dev Makefile)

    Usage: msidb [options] [tables]

    Options:
    -d <path> Fully qualified path to MSI database file
    -f <wdir> Path to the text archive folder
    -c Create or overwrite with new database and import tables
    -i <tables> Import tables from text archive files – use * for all
    -e <tables> Export tables to files archive in directory – use * for all
    -x <stream> Saves stream as <stream>.idb in <wdir>
    -a <file> Adds stream from file to database
    -r <storage> Adds storage to database as substorage

  • msiinfo (MSDN msiinfo, LibreOffice msiinfo, dev Makefile)

    Usage: msiinfo {database} [[-b]-d] {options} {data}

    Options:
    -c <cp> Specify codepage
    -t <title> Specify title
    -j <subject> Specify subject
    -a <author> Specify author
    -k <keywords> Specify keywords
    -o <comment> Specify comments
    -p <template> Specify template
    -l <author> Specify last author
    -v <revno> Specify revision number
    -s <date> Specify last printed date
    -r <date> Specify creation date
    -q <date> Specify date of last save
    -g <pages> Specify page count
    -w <words> Specify word count
    -h <chars> Specify character count
    -n <appname> Specify application which created the database
    -u <security> Specify security (0: none, 2: read only 3: read only (enforced)

  • makecab (MSDN makecab, LibreOffice makecab, dev Makefile)

    Usage: makecab [/V[n]] /F directive_file

    Options:
    /F directives – A file with MakeCAB directives.
    /V[n] – Verbosity level (1..3)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>