Packaging and shipping is HARD

I have worked really hard on Marave, a full screen editor in the style of ommwriter, DarkRoom, WriteRoom, pyRoom, etc. I have worked very hard and I want users to use it.

Or not even that, I want them to have a chance of using it.

That means I want it to work on Windows (and maybe OSX some day, too, if someone helps me). Which means, I have to pakage it for windows.

Let's do a quick comparison here from the points of view of the user and the developer.

The User, In Linux

This is in Arch Linux, which is what I use, in other Linux variants it will be pretty much the same once Marave is a bit more well known.

yaourt -S marave-svn --noconfirm

That gets the code from SVN (right now it's the best way, later I will package releases, too), all required dependencies, builds and installs. It takes all of 15 seconds in my notebook.

After that, you have a fully working Marave.

In case it's not packaged for your distro, just install PyQt (which surely is) and run this command:

easy_install marave

The User, in Windows

You go to http://marave.googlecode.com, click on "Marave-0.5.win32.exe" (Not linked yet, it's not finished), then download a 10MB program. That is a 10MB program because windows doesn't believe in packages and dependencies. On Linux, a Marave package could be under 1MB (most of it images), and not be executable, just data.

Of course nowadays web browsers don't actually run programs on download, so... let's see it as a gallery!

110111105613-My-Desktop

Yes, save it.

11011111220-My-Desktop

Double click to open it

11011111417-My-Desktop

Yes, I agree

11011111514-My-Desktop

Sure, whatever

1101111167-My-Desktop

Nice...

11011111750-My-Desktop

Good to hear!

Now, this Marave that just got installed may or may not currently work because of a missing MSVCR90.DLL but that's for the next section...

The Developer, in Linux

First, here's the biggest problem a Linux packager can have:

Since Marave is a new app, and I develop it in the rather cutting-edge Arch Linux, it uses some newish features only available in recent versions of Qt. In fact, it doesn't work with PyQt < 4.6, which is not available in some slow distros, like Debian, or even in a not-latest Ubuntu.

Solution? Well, I could just ignore it, but what the heck, let's fix it instead!

Thanks to PyInstaller it's not even hard to do, here's the spec file:

a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'marave/main.py'],
            pathex=['/home/ralsina/trunk/trunk'])

pyz = PYZ(a.pure)
exe = EXE(pyz,
        a.scripts,
        exclude_binaries=1,
        name=os.path.join('build/pyi.linux2/main', 'marave.exe'),
        debug=False,
        strip=False,
        upx=True,
        console=0 )

coll = COLLECT( exe,
            a.binaries,
            [('radios.txt','marave/radios.txt','DATA')],
            Tree('marave/icons','icons'),
            Tree('marave/backgrounds','backgrounds'),
            Tree('marave/clicks','clicks'),
            Tree('marave/stylesheets','stylesheets'),
            Tree('marave/themes','themes'),
            a.zipfiles,
            a.datas,
            strip=False,
            upx=True,
            name=os.path.join('dist', 'marave'))

Use this, and PyInstaller will produce a nice folder full of everything Marave needs to run on any Linux.

OTOH, if you can rely on a recent PyQt being available, it's also simple. Here's a packaging configuration for a similar package in Arch Linux (I must confess not having done one for Marave yet). For other distributions it should be about as simple, if more verbose, and someone else probably does it for you:

# Contributor: Roberto Alsina <[email protected]>
pkgname=python-rst2pdf
pkgver=0.12.1
pkgrel=4
pkgdesc="Create PDFs from simple text markup, no LaTeX required."
arch=('i686' 'x86_64')
url="http://rst2pdf.googlecode.com"
license=('custom')
depends=('python' 'setuptools' 'docutils' 'pygments' 'python-reportlab' 'python-simplejson' 'pil')
source=(http://rst2pdf.googlecode.com/files/rst2pdf-$pkgver.tar.gz LICENSE.txt)
optdepends=('uniconvertor: vector images support'
            'python-svglib: SVG support'
            'python-wordaxe: hyphenation'
            'pythonmagick: PDF images support')
build() {
cd $startdir/src/rst2pdf-$pkgver
python setup.py install --root=$startdir/pkg || return 1
install -D ../LICENSE.txt $startdir/pkg/usr/share/licenses/python-rst2pdf/COPYING
install -D doc/rst2pdf.1 $startdir/pkg/usr/share/man/man1/rst2pdf.1
}
md5sums=('ea6beda9a46f34ba42c4c94d48cc607a'
        '416f8046c66b9476cdbacda69a673afe')

And that's all you need to know about the process of packaging your app for Linux. It's easy to do, and most of the time, easy to do right!

Now, let's go to our final section...

Windows for the developer

First, remember that of relying on the system's version of Qt? Forget it, there is no system version available. And no python either. And noone is going to install it or your app, so it's "ship everything yourself" mode, or nothing.

But anyway, PyInstaller works for Windows too! So, using the same spec file, it works. Right?

Well, no beause of two problems.

Problem 1: You need an installer

Users are not going to open a zip somewhere, then do a shortcut to the binary on Windows, so you need to do some operations, and that means an installer.

Here's what I came up with to use NSIS, a free installer creator for Windows:

;--------------------------------
;Include Modern UI

!include "MUI2.nsh"

;--------------------------------
;General

;Name and file
Name "Marave"
OutFile "Marave-0.5.win32.exe"

;Default installation folder
InstallDir "$LOCALAPPDATA\Marave"

;Get installation folder from registry if available
InstallDirRegKey HKCU "Software\Marave" ""

;Request application privileges for Windows Vista
RequestExecutionLevel user

;--------------------------------
;Interface Settings

!define MUI_ABORTWARNING

;--------------------------------
;Pages

!insertmacro MUI_PAGE_LICENSE "LICENSE"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

;--------------------------------
;Languages

!insertmacro MUI_LANGUAGE "English"

;--------------------------------
;Installer Sections

Section "Install"

SetOutPath "$INSTDIR"
File /r "dist\marave"


;Store installation folder
WriteRegStr HKCU "Software\Marave" "" $INSTDIR

;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"

;Create shortcuts
CreateDirectory $SMPROGRAMS\Marave
CreateShortCut "$SMPROGRAMS\Marave\Marave.lnk" "$INSTDIR\marave\marave.exe" ; use defaults for parameters, icon, etc.
CreateShortCut "$SMPROGRAMS\Marave\Uninstall Marave.lnk" "$INSTDIR\Uninstall.exe" ; use defaults for parameters, icon, etc.

SectionEnd


;--------------------------------
;Uninstaller Section

Section "Uninstall"

Delete "$INSTDIR\Uninstall.exe"
RMDir /r "$INSTDIR"

DeleteRegKey /ifempty HKCU "Software\Marave"

SectionEnd

It's comparable to the effort of building a packaging file, really, except every time you want to test it... you install it. There is no way (AFAICS) to see what's inside the installer except running it!

When things fail, you get no error messages, at least not the kind that is useful for a developer, the guy that needs to know what went wrong.

And after it's finished, you may end with a non-working program because of...

Problem 2: system libraries don't exist

Python 2.6 binaries are built using Visual Studio. That means they require the Visual Studio Runtime, specifically MSVCR90.DLL. That contains what on Linux would be considered part of libc. (linux guy: imagine apps that depend on a specific libc... hard to do!)

On Linux that's part of the system. Further, if you wanted, you can redistribute it. On Windows... well, it's a bit different.

  1. It's part of the "Visual C++ redistributables"

  2. Installing that doesn't guarantee it will work (yes, I have tried)

  3. The license for those 'redistributables' says you can't make them available for download.

    I have been told that including that in your installer is fine and dandy, but how is that not making them available for download?

So what can you do when you need a library and can't ship it and the user won't install it?

Well, that's why there is no Windows binary of Marave yet. Of course if anyone can help, I'd be really, really happy!

Comments

Comments powered by Disqus