[wix-devs] Running WiX on Linux using Mono

Simon Tatham anakin at pobox.com
Sat Jun 17 14:37:17 PDT 2017


Hello wix-devs,

I've been using WiX for a while to build Windows installers for free
software I maintain (most importantly, PuTTY). Recently I've been making
an effort to avoid having Windows involved in my Windows build process
(mostly as a means of avoiding malware risks, although the extra speed
is nice too). So I'm using clang for a C compiler; I've arranged a
method of generating CHM help files without hhc.exe - and I've also
found a way to run WiX under Mono, using assorted pieces of Linux free
software to substitute for the tasks that WiX normally expects to
delegate to Windows facilities like MSI.DLL.

My current system for running WiX under Mono involves a set of Linux
shared library files that Mono loads in place of WiX's own
'winterop.dll' and friends. Using this setup, I'm able to use the
unmodified candle.exe and light.exe from the standard WiX 3 distribution
- no need to recompile the CLR parts at all. If anyone's interested in
looking at it in its current state, it's available here:

  https://git.tartarus.org/?p=simon/wix-on-linux.git;a=summary

But this system is not completely ideal, and I'd prefer to see if I can
get some changes into WiX itself to make this easier. I've already
raised this question in the bug tracker and posted some analysis there:

  https://github.com/wixtoolset/issues/issues/4381

and it was suggested that I should come here and ask for advice on the
possible high-level approaches, before I do a really thorough writeup of
a detailed plan.

What I'd personally like most would be if I could continue running the
official distribution of the CLR parts of WiX, out of the box, without
having to rebuild from source on Linux. So my first proposal would be to
add some fallback code on the C# side, to be used if the native-code
DLLs like winterop.dll can't be loaded. This fallback code would:

 - implement equivalent code to MsiGetFileVersion and MsiGetFileHash
   directly in C#, by digging through PE executables' resource sections
   for the former and MD5-hashing files for the latter.

 - implement CAB-building directly in C#, using Deflate compression,
   which I found to be easy enough given the published format
   documentation.

 - construct the actual MSI file by spawning GNOME 'msibuild', if it can
   find it on $PATH. msibuild expects a collection of .idt and .cab
   files as input, which is just what WiX has lying around anyway.

If people don't like the last one of those points (perhaps it's too
Linux-specific, whereas it might be nicer to be even more platform-
independent if we're going in this direction at all), another
possibility might be to add a command-line option to light.exe which
makes it write out a collection of .idt and .cab files and _terminate_ -
leaving the end user to find their own way to put them together into an
MSI. Then the Linux-based user would have to write a makefile flow that
went candle -> light -> msibuild (not much more inconvenient than plain
candle -> light), and users elsewhere would be able to come up with
other plans if they could think of any.

A third possibility would be to essentially import my current solution
directly into the WiX code base (with a lot of cleanup, of course!),
without bothering to translate it out of C into C#, so that the WiX
distribution would contain a libwinterop.so alongside its existing
winterop.dll. I think that's probably less convenient for everyone (in
particular, it adds a new OS requirement to WiX's own build
arrangements, which my preferred solution avoids), but it is a
possibility.

Of course, the last option is that none of this goes into wix at all and
I carry on maintaining my current collection of Linux native-code
libraries myself, and essentially function as a downstream of WiX for
people wanting to use it on Mono. If there's no interest in taking any
of these changes upstream, then that's what I'll have to do. (But in
that situation I'll still hope to at least get in a bug fix or two
upstream - e.g. there's an annoying issue involving the path-handling
code not quite understanding Linux path syntax, which I currently have
to work around in an ugly way with LD_PRELOAD.)

What do people think? Would any changes along these lines be welcome at
all? If so, which of these options sounds good? Have I missed any
possibilities?

Cheers,
Simon

-- 
for k in [pow(x,37,0x1a1298d262b49c895d47f) for x in [0x50deb914257022de7fff,
0x213558f2215127d5a2d1, 0x90c99e86d08b91218630, 0x109f3d0cfbf640c0beee7,
0xc83e01379a5fbec5fdd1, 0x19d3d70a8d567e388600e, 0x534e2f6e8a4a33155123]]:
 print "".join([chr(32+3*((k>>x)&1))for x in range(79)]) # <anakin at pobox.com>


More information about the wix-devs mailing list