Building Distro Independent Linux Bundle

Version 1 (Redmine Admin, 11/23/2011 04:44 pm)

1 1
2 1
h1. Introduction 
3 1
4 1
In this document I will describe how to make a distribution independent QGIS application bundle. The idea is to make something that can be unzipped and exectuted in a user's home directory - it wont need root permissions since it doesnt go into /usr. Also the idea is not to have to make a separate RPM/DEB file for all of the 1000's of GNU/Linux distros out there. In order to achieve this we follow an approach similar to Mac OSX application bundles - we package all the dependencies into the bundle. You should try to follow this procedure on the oldest linux system you can get your hands on since glibc is backwards but not forward compatible. This means if you for example build on a glibc 2.4 based system, the bundle *won't work* on older glibc2.3 based systems. I'm going to run through this tutorial using dapper which is glibc2.3 based.
5 1
6 1
7 1
h1. Preparing your system 
8 1
9 1
I assume you have the gcc tools available on your system to compile c++ apps, and also that you have svn and cvs clients. I also assume you have read and write perms in /opt. Here are the commands to get the above if you dont have them:
10 1
11 1
<pre>
12 1
 sudo apt-get install build-essential
13 1
 sudo apt-get install subversion cvs cmake
14 1
</pre>
15 1
16 1
First lets create a working directory:
17 1
18 1
<pre>
19 1
 mkdir /opt/qgis_linux_bundle
20 1
</pre>
21 1
22 1
Now we are going to download and build a bunch of stuff in opt...
23 1
24 1
<pre>
25 1
 cd /opt
26 1
 wget http://geos.refractions.net/geos-2.2.3.tar.bz2
27 1
 wget http://www.gdal.org/dl/gdal-1.4.0.tar.gz
28 1
 wget http://ufpr.dl.sourceforge.net/sourceforge/expat/expat-2.0.0.tar.gz
29 1
 wget http://grass.itc.it/grass62/source/grass-6.2.1.tar.gz
30 1
 wget ftp://ftp.trolltech.com/qt/source/qt-x11-opensource-src-4.2.2.tar.gz
31 1
 wget ftp://ftp.gnu.org/gnu/gsl/gsl-1.8.tar.gz
32 1
 wget ftp://ftp.remotesensing.org/proj/proj-4.5.0.tar.gz 
33 1
 wget http://www.sqlite.org/sqlite-3.3.10.tar.gz
34 1
</pre>
35 1
36 1
37 1
h1. Build Expat 
38 1
39 1
<pre>
40 1
 tar xfz expat-2.0.0.tar.gz
41 1
 cd expat-2.0.0
42 1
 ./configure --prefix=/opt/qgis_linux_bundle/usr
43 1
 make
44 1
 make install
45 1
 cd ..
46 1
</pre>
47 1
48 1
49 1
h1. Build GEOS 
50 1
51 1
<pre>
52 1
 tar xfj geos-2.2.3.tar.bz2
53 1
 cd geos-2.2.3
54 1
 ./configure --prefix=/opt/qgis_linux_bundle/usr
55 1
 make
56 1
 make install
57 1
 cd ..
58 1
</pre>
59 1
60 1
61 1
h1. Build GDAL 
62 1
63 1
<pre>
64 1
 sudo apt-get build-dep libgdal1c2a 
65 1
 tar xfz gdal-1.4.0.tar.gz
66 1
 cd gdal-1.4.0
67 1
 ./configure --prefix=/opt/qgis_linux_bundle/usr --with-geos=/opt/qgis_linux_bundle/usr/bin/geos- config
68 1
 make
69 1
 sudo make install
70 1
 cd ..
71 1
</pre>
72 1
73 1
We need to use sudo for the last step since gdal tries to install python stuff into /usr which needs root privs.
74 1
75 1
76 1
h1. Build Qt4.2.2 
77 1
78 1
<pre>
79 1
 tar xfz qt-x11-opensource-src-4.2.2.tar.gz
80 1
 cd qt-x11-opensource-src-4.2.2
81 1
 ./configure -prefix /opt/qis_linux_bundle/usr/ -nomake examples 
82 1
 make 
83 1
 make install
84 1
 cd ..
85 1
</pre>
86 1
87 1
88 1
h1. Build GSL 
89 1
90 1
<pre>
91 1
 tar xfz gsl-1.8.tar.gz
92 1
 cd gsl-1.8
93 1
 ./configure --prefix /opt/qis_linux_bundle/usr/
94 1
 make
95 1
 make install
96 1
 cd ..
97 1
</pre>
98 1
99 1
100 1
h1. Build proj4 
101 1
102 1
<pre>
103 1
 tar xfz proj-4.5.0.tar.gz
104 1
 cd proj-4.5.0
105 1
 ./configure --prefix /opt/qis_linux_bundle/usr/
106 1
 make
107 1
 make install
108 1
 cd ..
109 1
</pre>
110 1
111 1
112 1
h1. Build SQLITE 
113 1
114 1
<pre>
115 1
 tar xfz sqlite-3.3.10.tar.gz
116 1
 cd sqlite-3.3.10
117 1
 ./configure --prefix /opt/qis_linux_bundle/usr/
118 1
 make
119 1
 make install
120 1
 cd ..
121 1
</pre>
122 1
123 1
124 1
h1. Build GRASS 
125 1
126 1
*TODO_* Describe grass and gdal-grass support here
127 1
128 1
129 1
h1. Install cmake 
130 1
131 1
*Note:* Only needed for QGIS > 0.8.x
132 1
133 1
This doesnt go into the bundle dir but is needed to build QGIS, openModeller lib and openModeller Desktop
134 1
135 1
<pre>
136 1
 sudo apt-get install cmake
137 1
</pre>
138 1
139 1
140 1
h1. Install QGIS 
141 1
142 1
I assume you already have a checked out copy of QGIS sources
143 1
144 1
<pre>
145 1
 cd /opt
146 1
 svn co https://svn.qgis.org/repos/qgis/trunk/qgis qgis
147 1
 cd qgis
148 1
 mkdir build
149 1
 cd build
150 1
 cmake -DGDAL_CONFIG=/opt/omg_linux_bundle/usr/bin/gdal-config \
151 1
      -DGSL_CONFIG=/opt/omg_linux_bundle/usr/bin/gsl-config \
152 1
      -DSQLITE3_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
153 1
      -DSQLITE3_LIBRARY=/opt/omg_linux_bundle/usr/lib/libsqlite3.so \
154 1
      -DPROJ_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
155 1
      -DPROJ_LIBRARY=/opt/omg_linux_bundle/usr/lib/libproj.so \
156 1
      -DQT_QMAKE_EXECUTABLE=/opt/omg_linux_bundle/usr/bin/qmake \
157 1
      -DCMAKE_INSTALL_PREFIX=/opt/omg_linux_bundle/usr/ \
158 1
      -DGEOS_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
159 1
      -DGEOS_LIBRARY=/opt/omg_linux_bundle/usr/lib/libgeos.so \
160 1
      -DPEDANTIC=OFF \
161 1
      ..
162 1
 make install
163 1
  
164 1
</pre>
165 1
166 1
h1. Build openModeller 
167 1
168 1
This is an *optional* step for those wanting openModeller inside the bundle (==me!).
169 1
170 1
<pre>
171 1
 cd /opt
172 1
 svn co https://openmodeller.svn.sourceforge.net/svnroot/openmodeller/trunk/openmodeller   openmodeller
173 1
 cd openmodeller
174 1
 mkdir build
175 1
 cd build
176 1
 cmake -DGDAL_CONFIG=/opt/omg_linux_bundle/usr/bin/gdal-config \
177 1
      -DGSL_CONFIG=/opt/omg_linux_bundle/usr/bin/gsl-config \
178 1
      -DSQLITE3_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
179 1
      -DSQLITE3_LIBRARY=/opt/omg_linux_bundle/usr/lib/libsqlite3.so \
180 1
      -DPROJ_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
181 1
      -DPROJ_LIBRARY=/opt/omg_linux_bundle/usr/lib/libproj.so \
182 1
      -DQT_QMAKE_EXECUTABLE=/opt/omg_linux_bundle/usr/bin/qmake \
183 1
      -DCMAKE_INSTALL_PREFIX=/opt/omg_linux_bundle/usr/ \
184 1
      -DGEOS_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
185 1
      -DGEOS_LIBRARY=/opt/omg_linux_bundle/usr/lib/libgeos.so \
186 1
      -DPEDANTIC=OFF \
187 1
      ..
188 1
 make install
189 1
</pre>
190 1
191 1
192 1
h1. Install openModeller Desktop 
193 1
194 1
<pre>
195 1
 cd /opt
196 1
 svn co https://openmodeller.svn.sourceforge.net/svnroot/openmodeller/trunk /openModellerDesktop  openModellerDesktop
197 1
 cd openModellerDesktop
198 1
 mkdir build
199 1
 cd build
200 1
 cmake -DGDAL_CONFIG=/opt/omg_linux_bundle/usr/bin/gdal-config \
201 1
      -DGSL_CONFIG=/opt/omg_linux_bundle/usr/bin/gsl-config \
202 1
      -DSQLITE3_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
203 1
      -DSQLITE3_LIBRARY=/opt/omg_linux_bundle/usr/lib/libsqlite3.so \
204 1
      -DPROJ_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
205 1
      -DPROJ_LIBRARY=/opt/omg_linux_bundle/usr/lib/libproj.so \
206 1
      -DQT_QMAKE_EXECUTABLE=/opt/omg_linux_bundle/usr/bin/qmake \
207 1
      -DCMAKE_INSTALL_PREFIX=/opt/omg_linux_bundle/usr/ \
208 1
      -DGEOS_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/ \
209 1
      -DGEOS_LIBRARY=/opt/omg_linux_bundle/usr/lib/libgeos.so \
210 1
      -DQGIS_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/qgis/ \
211 1
      -DQGIS_LIBRARY="/opt/omg_linux_bundle/usr/lib/libqgis_core.so;/opt/omg_linux_bundle/usr/lib /libqgis_gui.so" \
212 1
      -DOM_INCLUDE_DIR=/opt/omg_linux_bundle/usr/include/openModeller \
213 1
      -DOM_LIBRARY=/opt/omg_linux_bundle/usr/lib/libopenmodeller.so \
214 1
      -DWITH_QGIS=ON \
215 1
      -DQGIS_FOUND=ON \
216 1
      -DPEDANTIC=OFF \
217 1
      ..
218 1
 make install
219 1
</pre>
220 1
221 1
*Note* See hack below if you run into errors finding libQtSvg.so.4
222 1
223 1
If you get this:
224 1
225 1
<pre>
226 1
 /usr/bin/ld: warning: libQtSvg.so.4, needed by /opt/omg_linux_bundle/usr/lib/libqgis_core.so, not  found (try using -rpath or -rpath-link)
227 1
 /opt/omg_linux_bundle/usr/lib/libqgis_core.so: undefined reference to  `QSvgRenderer::QSvgRenderer(QObject*)'
228 1
 /opt/omg_linux_bundle/usr/lib/libqgis_core.so: undefined reference to  `QSvgRenderer::~QSvgRenderer()'
229 1
 /opt/omg_linux_bundle/usr/lib/libqgis_core.so: undefined reference to `QSvgRenderer::render(QPainter*)'
230 1
 /opt/omg_linux_bundle/usr/lib/libqgis_core.so: undefined reference to `QSvgRenderer::load(QString  const&)'
231 1
 collect2: ld returned 1 exit status
232 1
 make[2]: *** [src/gui/CMakeFiles/CMakeRelink.dir/openModellerDesktop] Error 1
233 1
 make[1]: *** [src/gui/CMakeFiles/openModellerDesktop.dir/preinstall] Error 2
234 1
</pre>
235 1
236 1
You can make the following hack before running make install:
237 1
238 1
<pre>
239 1
 export LD_LIBRARY_PATH=/opt/omg_linux_bundle/usr/lib/
240 1
</pre>
241 1
242 1
*TODO* Fix build process so above is not needed
243 1
244 1
245 1
h1. Testing and copying over missing deps 
246 1
247 1
Ok now we are ready to do some testing. First put a script like the one below into the top of the bundle dir (I called it qgis.sh).
248 1
249 1
<pre>
250 1
 #!/bin/bash
251 1
 export LD_LIBRARY_PATH=`pwd`/usr/lib:`pwd`/usr/local/lib:`pwd`/usr/lib/qgis
252 1
 export PATH=`pwd`/usr/bin:`pwd`/usr/local/bin:$PATH
253 1
 export GISBASE=`pwd`/usr/grass-6.2.1
254 1
 qgis &
255 1
</pre>
256 1
257 1
Save it and make it executable:
258 1
259 1
<pre>
260 1
 chmod a+x qgis.sh
261 1
</pre>
262 1
263 1
264 1
h2. Live CD 
265 1
266 1
Ok now is a good time to pull out your live CD - Im going to use an ubuntu dapper live CD. Pop it in the drive and reboot. Mount the partition with your original /opt somewhere on your rebooted livecd:
267 1
268 1
<pre>
269 1
 sudo mount /dev/hda7 /media/
270 1
</pre>
271 1
272 1
So now my dapper partition is mounted in my livecd under /media
273 1
274 1
Now we try to run qgis. Missing library errors will appear and we will resolve them one at a time. I provide my resolution list here though it may not be what you need since it depends what libs are on your livecd. For this reason I recommend you use the most basic and oldest live cd you can get your hands on to test properly.
275 1
276 1
<pre>
277 1
 cd /media/opt/qgis_linux_bundle
278 1
 ./qgis.sh
279 1
</pre>
280 1
281 1
You will get a message like:
282 1
283 1
<pre>
284 1
 qgis: error while loading shared libraries: libpq.so.4: cannot open shared object file: No such file or  directory
285 1
</pre>
286 1
287 1
So copy in that lib:
288 1
289 1
<pre>
290 1
 sudo cp -d /media/usr/lib/libpq.so* .
291 1
</pre>
292 1
293 1
Then try to run qgis.sh again, deal with the error bu copying over the appropriate lib and so on until all missing libs are resolved and the application starts successfully. Here is my final copy list:
294 1
295 1
<pre>
296 1
 sudo cp -d /media/usr/lib/libpq.so* .
297 1
 sudo cp -d /media/usr/lib/libodbc.so* .
298 1
 sudo cp -d /media/usr/lib/libodbcinst.so* .
299 1
 sudo cp -d /media/usr/lib/libmfhdf.so* .
300 1
 sudo cp -d /media/usr/lib/libdf.so* .
301 1
 sudo cp -d /media/usr/lib/libungif.so* .
302 1
 sudo cp -d /media/usr/lib/libnetcdf.so* .
303 1
 sudo cp -d /media/usr/lib/libcfitsio.so* .
304 1
 sudo cp -d /media/usr/lib/libltdl.so* .
305 1
 sudo cp -d /media/dapper/usr/lib/libjasper-1.701.so.1* .
306 1
 sudo cp -d /media/dapper/usr/lib/libtiff.so* .
307 1
 sudo cp -d /media/dapper/usr/lib/libssl.so* .
308 1
 sudo cp -d /media/dapper/usr/lib/libcrypt.so* .
309 1
 sudo cp -d /media/dapper/usr/lib/libpython2.4.so* .
310 1
 sudo cp -d /media/dapper/usr/lib/libkrb5.so.3* .
311 1
 sudo cp -d /media/dapper/usr/lib/libk5crypto.so.3* .
312 1
 sudo cp -d /media/dapper/usr/lib/libkrb5support.so.* .
313 1
 sudo cp -d /media/dapper/usr/lib/libstdc++.so.6* .
314 1
 sudo cp -d /media/dapper/usr/lib/libpng12.so* .
315 1
 sudo cp -d /media/dapper/usr/lib/libcrypto.so* .
316 1
 sudo cp -d /media/dapper/lib/libgcc_s.so.1 .
317 1
</pre>
318 1
319 1
320 1
h1. Take the bundle on a diet 
321 1
322 1
Before we redistribute the bundle, it should go on a diet since there is a lot of stuff in there not needed by users at runtime. At the same time we dont want to trash our original since we need that stuff in there if we want to update it. 
323 1
324 1
Before I started I looked at the size of the dir:
325 1
326 1
<pre>
327 1
 du -sh qgis_linux_bundle/
328 1
 426M    qgis_linux_bundle/
329 1
</pre>
330 1
331 1
So lets first make a copy and then go ahead and get out the pruning shears....
332 1
333 1
<pre>
334 1
 cp qgis_linux_bundle qgis0.8-bundle
335 1
 cd qgis0.8-bundle/usr
336 1
</pre>
337 1
338 1
Heres what I took out (remember we are in the usr dir of our bundle now):
339 1
340 1
<pre>
341 1
 rm -rf include/ mkspecs translations q3porting.xml phrasebooks man info doc
342 1
 rm -rf lib/*debug*
343 1
 rm -rf lib/*.a
344 1
 rm -rf lib/*.la
345 1
 rm -rf lib/openmodeller/*.la
346 1
 rm -rf lib/openmodeller/*.a
347 1
 rm -rf lib/qgis/*.a
348 1
 rm -rf lib/qgis/*.la
349 1
 rm -rf bin/*.debug
350 1
</pre>
351 1
352 1
Lets see how much space it consumes now....
353 1
354 1
<pre>
355 1
 du -sh qgis0.8-bundle/
356 1
 150M    qgis0.8-bundle/
357 1
</pre>
358 1
359 1
Right so that looks much better...lets make a nice installer for it now....
360 1
361 1
362 1
h1. Creating a Installl Wizard using BitRock 
363 1
364 1
http://bitrock.com produce a crossplatform qt4 based installer.