--- author: '' category: '' date: 2010/02/11 14:00 description: '' link: '' priority: '' slug: BB868 tags: arch linux, linux, marave, open source, programming, pyqt, python, qt title: Packaging and shipping is HARD type: text updated: 2010/02/11 14:00 url_type: '' --- 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! .. raw:: html 110111105613-My-Desktop Yes, save it. .. raw:: html 11011111220-My-Desktop Double click to open it .. raw:: html 11011111417-My-Desktop Yes, I agree .. raw:: html 11011111514-My-Desktop Sure, whatever .. raw:: html 1101111167-My-Desktop Nice... .. raw:: html 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: .. code-block:: python 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 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!