A client wanted their own custom QGIS build which included some patches and a selection of additional python plugins that were to be available from point of installation. Additionally we wanted to brand the installer with their logo and the splash screen too so that users realise they are using a custom build. The actual build process under windows using msvc is fairly
straightforward (see the INSTALL document in the root of QGIS source tree) so I won’t discuss that here. Rather I am going to show you an approach for building such a custom installer.
Creating a branch
Since we live in git land now, the first thing I am going to do is create a branch for my client’s customisations. If any changes in that branch are useful to the master branch, I will cherry pick them across later using git cherry-pick.
git checkout -b sansa-branch
Now apply all your code level customisations to the sources in your branch and go ahead and compile everything to make sure it builds, links and installs.
Customising the installer sidebars
The installer sidebars can be altered in the gimp – simply edit :
You can open it directly (no need to untar it first). Then use the gimp project to create new versions of:
Make sure to keep the image dimensions the same. Those can be commited to your local branch:
git commit -m "Customised sidebar images" \ ms-windows/Installer-Files/WelcomeFinishPage.bmp \ ms-windows/Installer-Files/UnWelcomeFinishPage.bmp
Customising the Splash Screen
The splash screen master can be found here:
Once again, you can open this directly in the gimp and edit it according to your needs. When you are ready to save the final splash, resize it to 600×287 pixels first. Be careful to also preserve the
transparency in the corners properly or otherwise you will see artifacts when you start QGIS which won’t look nice. The saved splash should be saved as:
Creating a package tree
There are two ways you can go here…
You can take an existing build of QGIS, extract it under windows, copy your build outputs from msvc over the apps/qgis or apps/qgis-dev directory and then copy the whole lot over to linux. When it is in your linux box, place it under:
In this case the contents under unpacked should be what was originally under your c:\Program Files\Quantum GIS directory.
One important thing to note is that there are various batch files that are run after QGIS installs. After they are run they are renamed to have a .done extension after them. We need to remove this extension so that they get run after your custom QGIS installer has run. Here are a few lines of bash that do just that:
mv postinstall.bat.done postinstall.bat
for FILE in *.done; do mv $FILE \ $(basename $FILE .done); done cd ../../../..
You can run the creatensis.pl script like this and specify a shortname e.g. qgis or qgis-dev.
cd osgeo4w ./creatensis.pl --shortname=qgis
It will take a while to run if you have a slow connection like I do, After it is done, place the build outputs from msvc into the file tree at:
So in my case, msvc installed the QGIS I built into c:\program files\qgis1.7.0 – which now becomes the unpacked/apps/qgis directory.
Understanding the batch files
Another important thing to understand is how the various batch files are called within your package tree. Immediately after installation, the postinstall.bat program is run. Its main job is to set a bunch of environment variables and then call a some subsidiary scripts living in the etc/postinstall directory. One common issue is that you create your installer, install it on a windows machine, and then nothing happens when you click the icon. Usually this will be caused by a mismatch between you qgis launcher script name and the shortcut that was created to call it. The naming convention used in osgeo4w is to install the current stable version of qgis under apps/qgis and the latest development build under apps/qgis-dev. Typically you will only want to ship one or the other to your users – that is an installer based on the current stable release, or one based on the current QGIS trunk. Either way what is important is that everything gets named consistently. For this article, I will use a shortname of ‘qgis’ throughout. So you should check your postinstall.bat to make sure that its calling an appropriate qgis postinstall script. For example mine looked like this:
echo Running postinstall qgis-dev.bat...
%COMSPEC% /c etc\postinstall\qgis-dev.bat>>postinstall.log 2>&1 ren etc\postinstall\qgis-dev.bat qgis-dev.bat.done>>postinstall.log 2>&1
But I am standardising on using apps/qgis for my qgis directory, so I need to change it to look like this:
echo Running postinstall qgis-dev.bat...
%COMSPEC% /c etc\postinstall\qgis.bat>>postinstall.log 2>&1 ren etc\postinstall\qgis.bat qgis.bat.done>>postinstall.log 2>&1
Similarly you need to check in etc/postinstall to make sure that the qgis.bat scrip referred to here exists:
[unpacked] ls etc/postinstall/
grass.bat msvcrt.bat msys.bat openssl.bat pyqt4.bat qgis-dev.bat qt4-libs.bat sip.bat
You can see once again the name doesn’t gel, so I will rename mine to ’qgis.bat’:
mv etc/postinstall/qgis-dev.bat etc/postinstall/qgis.bat
Lastly, are the actual contents of that batch file consistent?
textreplace -std -t bin\qgis-dev.bat
xxmklink "%OSGEO4W_STARTMENU%\Quantum GIS (1.7.0).lnk" ...
"%OSGEO4W_ROOT%\bin\qgis-dev.bat" " " \ "Quantum GIS - Desktop GIS (1.7.0)" ...
xxmklink "%ALLUSERSPROFILE%\Desktop\Quantum GIS (1.7.0).lnk" ... "%OSGEO4W_ROOT%\bin\qgis-dev.bat" " " \ "Quantum GIS - Desktop GIS (1.7.0)" ...
set O4W_ROOT=%OSGEO4W_ROOT% set OSGEO4W_ROOT=%OSGEO4W_ROOT:\=\\%
textreplace -std -t "%O4W_ROOT%\apps\qgis-dev\bin\qgis.reg"
"%WINDIR%\regedit" /s "%O4W_ROOT%\apps\qgis-dev\bin\qgis.reg"
They are not so I will update them to correct that:
textreplace -std -t bin\qgis.bat
"%OSGEO4W_STARTMENU%\Quantum GIS (1.7.0).lnk" ...
"%OSGEO4W_ROOT%\bin\qgis.bat" " " ... "Quantum GIS - Desktop GIS (1.7.0)" 1 ... "%OSGEO4W_ROOT%\apps\qgis\icons\QGIS.ico"
xxmklink "%ALLUSERSPROFILE%\Desktop\Quantum GIS (1.7.0).lnk" \
"%OSGEO4W_ROOT%\bin\qgis.bat" " " ... "Quantum GIS - Desktop GIS (1.7.0)" ... 1 "%OSGEO4W_ROOT%\apps\qgis\icons\QGIS.ico"
set O4W_ROOT=%OSGEO4W_ROOT% set OSGEO4W_ROOT=%OSGEO4W_ROOT:\=\\%
textreplace -std -t "%O4W_ROOT%\apps\qgis\bin\qgis.reg"
"%WINDIR%\regedit" /s "%O4W_ROOT%\apps\qgis\bin\qgis.reg"
Whether or not you actually need to tweak these scripts is largely dependent on your starting point. I can only say I had lots of issues because I had mismatches between references to qgis and qgis-dev to it is useful to understand the sequence of events. The last script we edited will ultimately create the shortcut icon on the users desktop and menu system.
You also need to check that the preremove scripts are similarly consistent, so check these scripts are there and internally correct:
Lastly you should remove bin/qgis.bat if it is present and check that bin/qgis.bat.templ is there. If it is named as qgis-dev.bat.templ rather than qgis then rename accordingly to qgis.bat.templ. Now check inside this script to make sure everything is consistent there too. The following diagram describes these processes visually.
Customising what gets shipped.
Here is the opportunity to add some customisations to the installer contents. For example I wanted to include ecw and sid support in my installer, as well as a bunch of the nicer python plugins that are out there. Simply copy the files you need into the correct place in the unpacked directory tree. For example, I took a range of python plugins from my ~/.qgis/python/plugins/ directory and placed them in:
cp -r ~/.qgis/python/plugins/bcccoltbl1/ .
cp -r ~/.qgis/python/plugins/cadtools/ .
cp -r ~/.qgis/python/plugins/metatools/ .
cp -r ~/.qgis/python/plugins/numericalDigitize/ .
cp -r ~/.qgis/python/plugins/numericalVertexEdit .
cp -r ~/.qgis/python/plugins/openlayers .
cp -r ~/.qgis/python/plugins/openlayersov .
cp -r ~/.qgis/python/plugins/postgis_manager . cp -r ~/.qgis/python/plugins/QGISFileBrowser .
cp -r ~/.qgis/python/plugins/qgsAffine .
cp -r ~/.qgis/python/plugins/rawrasterfileimport .
cp -r ~/.qgis/python/plugins/shadedrelief .
cp -r ~/.qgis/python/plugins/tablemanager .
cp -r ~/.qgis/python/plugins/topocolour .
cp -r ~/.qgis/python/plugins/valuetool .
Building an installer
Now we get to the part you have been waiting for – building an installer. There is a convenience script here that will do most of the work for you:
<qgis source tree root>/ms-windows/quickpackage.sh
Before you run the script, you should check that the shortname inside this file matches the one we used in the steps above (in this case ’qgis’ rather than ‘qgis-dev’).
makensis \ -DVERSION_NUMBER='1.7.0' \ -DVERSION_NAME='Wroclaw' \ -DSVN_REVISION='0' \ -DQGIS_BASE='Quantum GIS' \ -DINSTALLER_NAME='QGIS-1-7-0-Sansa-Edition-Setup.exe' \ -DDISPLAYED_NAME='Quantum GIS 1.7.0' \ -DBINARY_REVISION=1 \ -DINSTALLER_TYPE=OSGeo4W \ -DPACKAGE_FOLDER=osgeo4w/unpacked \ -DSHORTNAME=qgis \ QGIS-Installer.nsi
You can also use the opportunity to customise the name of the installer and the name of the version and release number of QGIS if you like (though I don’t recommend that latter two much as they provide a good point of reference to users). When you are finished, simply run the quickpackage script and wait a while:
After a few minutes the script will come to an end and you should have a nice shiny new QGIS-1-7-0-Sansa-Edition-Setup.exe (or whatever you called it) created in the ms-windows directory. Now its simple a matter of installing it in a clean windows machine to test it, running it through a virus checker and then putting it online for people to enjoy.
With all the flexibility that QGIS offers, being open source and ‘out there’ for anyone to hack on, its easy to take what the project provides and rebrand it substantially:
- you can create a custom icon theme
- you can remove unwanted user interface elements
- you can replace help text, about text etc
- you can rename the application itself to something else
- you can change the application icon
and so on and so on. One thing you may not do is claim the fundamental work to be your own. Any time you make a publically available custom version of QGIS, be sure to remember that you need to redistribute the full source code (including all your customisations) with it in order to comply with the letter and spirit of the GPL.
One final thing to mention is that at the Lisbon hackfest, Martin Dobias and Radim Blazek demonstrated a really slick and easy to use framework for creating stripped down versions of the QGIS user interface. It introduces the idea of profiles that you can nominate at application start up. So a school teacher may for example provide her students with just the few icons and tools they need to complete a particular exercise. Look out for that in a future version of QGIS I guess…..
If anyone is interested in having custom branded versions of QGIS for use within their organisation, we (linfiniti) will be happy to help - just pop us an email.