Ref #559: Geeqie won't start if clutter fails to init
[geeqie.git] / web / geeqie-install-debian.sh
1 #!/bin/bash
2 version="2021-05-10"
3 description=$'
4 Geeqie is an image viewer.
5 This script will download, compile, and install Geeqie on Debian-based systems.
6 If run from a folder that already contains the Geeqie sources, the source
7 code will be updated from the repository.
8 Dialogs allow the user to install additional features.
9
10 Command line options are:
11 -v --version The version of this file
12 -h --help Output this text
13 -c --commit=ID Checkout and compile commit ID
14 -t --tag=TAG Checkout and compile TAG (e.g. v1.4 or v1.3)
15 -b --back=N Checkout commit -N (e.g. "-b 1" for last-but-one commit)
16 -d --debug=yes Compile with debug output
17 '
18
19 # Essential for compiling
20 essential_array=(
21 "git"
22 "build-essential"
23 "autoconf"
24 "libglib2.0-0"
25 "intltool"
26 "libtool"
27 "yelp-tools"
28 )
29
30 # Optional for both GTK2 and GTK3
31 optional_array=(
32 "LCMS (for color management)"
33 "liblcms2-dev"
34 "exiv2 (for exif handling)"
35 "libgexiv2-dev"
36 "lua (for --remote commands)"
37 "liblua5.1-0-dev"
38 "libffmpegthumbnailer (for mpeg thumbnails)"
39 "libffmpegthumbnailer-dev"
40 "libtiff (for tiff support)"
41 "libtiff-dev"
42 "libjpeg (for jpeg support)"
43 "libjpeg-dev"
44 "librsvg2 (for viewing .svg images)"
45 "librsvg2-common"
46 "libwmf (for viewing .wmf images)"
47 "libwmf0.2-7-gtk"
48 "exiftran (for image rotation)"
49 "exiftran"
50 "imagemagick (for image rotation)"
51 "imagemagick"
52 "ufraw (for RAW file handling)"
53 "ufraw"
54 "exiv2 command line (for jpeg export)"
55 "exiv2"
56 "jpgicc (for jpeg export color correction)"
57 "liblcms2-utils"
58 "markdown (for generating README help file)"
59 "markdown"
60 "gphoto2 (for tethered photography and camera download plugins)"
61 "gphoto2"
62 "libimage-exiftool-perl (for jpeg extraction plugin)"
63 "libimage-exiftool-perl"
64 "libheif (for HEIF support)"
65 "libheif-dev"
66 "libwebp (for WebP images)"
67 "libwebp-dev"
68 "libdjvulibre (for DjVu images)"
69 "libdjvulibre-dev"
70 "libopenjp2 (for JP2 images)"
71 "libopenjp2-7-dev"
72 "libraw (for CR3 images)"
73 "libraw-dev"
74 )
75
76 # Optional for GTK3 only
77 optional_gtk3_array=(
78 "libchamplain gtk (for GPS maps)"
79 "libchamplain-gtk-0.12-dev"
80 "libchamplain (for GPS maps)"
81 "libchamplain-0.12-dev"
82 "libpoppler (for pdf file preview)"
83 "libpoppler-glib-dev"
84 )
85
86 ####################################################################
87 # Get System Info
88 # Derived from: https://github.com/coto/server-easy-install (GPL)
89 ####################################################################
90 lowercase()
91 {
92         echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
93 }
94
95 systemProfile()
96 {
97         OS=`lowercase \`uname\``
98         KERNEL=`uname -r`
99         MACH=`uname -m`
100
101         if [ "${OS}" == "windowsnt" ]
102         then
103                 OS=windows
104         elif [ "${OS}" == "darwin" ]
105         then
106                 OS=mac
107         else
108                 OS=`uname`
109                 if [ "${OS}" = "SunOS" ]
110                 then
111                         OS=Solaris
112                         ARCH=`uname -p`
113                         OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
114                 elif [ "${OS}" = "AIX" ]
115                 then
116                         OSSTR="${OS} `oslevel` (`oslevel -r`)"
117                 elif [ "${OS}" = "Linux" ]
118                 then
119                         if [ -f /etc/redhat-release ]
120                         then
121                                 DistroBasedOn='RedHat'
122                                 DIST=`cat /etc/redhat-release |sed s/\ release.*//`
123                                 PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
124                                 REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
125                         elif [ -f /etc/SuSE-release ]
126                         then
127                                 DistroBasedOn='SuSe'
128                                 PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
129                                 REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
130                         elif [ -f /etc/mandrake-release ]
131                         then
132                                 DistroBasedOn='Mandrake'
133                                 PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
134                                 REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
135                         elif [ -f /etc/debian_version ]
136                         then
137                                 DistroBasedOn='Debian'
138                                 if [ -f /etc/lsb-release ]
139                                 then
140                                         DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F=  '{ print $2 }'`
141                                         PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  '{ print $2 }'`
142                                         REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  '{ print $2 }'`
143                                 fi
144                         fi
145                         if [ -f /etc/UnitedLinux-release ]
146                         then
147                                 DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
148                         fi
149                         OS=`lowercase $OS`
150                         DistroBasedOn=`lowercase $DistroBasedOn`
151                         readonly OS
152                         readonly DIST
153                         readonly DistroBasedOn
154                         readonly PSUEDONAME
155                         readonly REV
156                         readonly KERNEL
157                         readonly MACH
158                 fi
159         fi
160 }
161
162 install_essential()
163 {
164         arraylength=${#essential_array[@]}
165         for (( i=0; i<${arraylength}; i=i+1 ));
166         do
167                 package_query ${essential_array[$i]}
168                 if [ $? != 0 ]
169                 then
170                         package_install ${essential_array[$i]}
171                 fi
172         done
173
174         if [[ $1 == "GTK3" ]]
175         then
176                 package_query "libgtk-3-dev"
177                 if [ $? != 0 ]
178                 then
179                         package_install libgtk-3-dev
180                 fi
181         else
182                 package_query "libgtk2.0-dev"
183                 if [ $? != 0 ]
184                 then
185                         package_install libgtk2.0-dev
186                 fi
187         fi
188 }
189
190 install_options()
191 {
192         if [ -n "$options" ]
193         then
194                 OLDIFS=$IFS
195                 IFS='|'
196                 set $options
197                 while [ $# -gt 0 ];
198                 do
199                         package_install $1
200                         shift
201                 done
202                 IFS=$OLDIFS
203         fi
204 }
205
206 uninstall()
207 {
208         current_dir=$(basename $PWD)
209         if [[ $current_dir == "geeqie" ]]
210         then
211                 sudo --askpass make uninstall
212                 zenity --title="Uninstall Geeqie" --width=370 --text="WARNING.\nThis will delete folder:\n\n$PWD\n\nand all sub-folders!" --question --ok-label="Cancel" --cancel-label="OK" 2>/dev/null
213
214                 if [[ $? == 1 ]]
215                 then
216                         cd ..
217                         sudo --askpass rm -rf geeqie
218                 fi
219         else
220                 zenity --title="Uninstall Geeqie" --width=370 --text="This is not a geeqie installation folder!\n\n$PWD" --warning 2>/dev/null
221         fi
222
223         exit_install
224 }
225
226 package_query()
227 {
228         if [[ $DistroBasedOn == "debian" ]]
229         then
230                 res=$(dpkg-query --show --showformat='${Status}' $1 2>>$install_log)
231                 if [[ "$res" == "install ok installed"* ]]
232                 then
233                         status=0
234                 else
235                         status=1
236                 fi
237         fi
238         return $status
239 }
240
241 package_install()
242 {
243         if [[ $DistroBasedOn == "debian" ]]
244         then
245                 sudo --askpass apt-get --assume-yes install $@ >>$install_log 2>&1
246         fi
247 }
248
249 exit_install()
250 {
251         rm $install_pass_script >/dev/null 2>&1
252         #~ rm $install_log >/dev/null 2>&1
253
254         if [[ -p $zen_pipe ]]
255         then
256                 echo "100" > $zen_pipe
257                 echo "#End" > $zen_pipe
258         fi
259
260         zenity --title="$title" --width=370 --text=$'Geeqie is not installed\nLog file: '$install_log --info 2>/dev/null
261
262         rm $zen_pipe >/dev/null 2>&1
263
264         exit 1
265 }
266
267 # Entry point
268
269 # If uninstall has been run, maybe the current directory no longer exists
270 ls $PWD >/dev/null
271 if [[ $? != 0 ]]
272 then
273         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Folder $PWD does not exist!" 2>/dev/null
274
275         exit
276 fi
277
278 # Check system type
279 systemProfile
280 if [[ $DistroBasedOn != "debian" ]]
281 then
282         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Unknown operating system:\n
283 Operating System: $OS
284 Distribution: $DIST
285 Psuedoname: $PSUEDONAME
286 Revision: $REV
287 DistroBasedOn: $DistroBasedOn
288 Kernel: $KERNEL
289 Machine: $MACH" 2>/dev/null
290
291         exit
292 fi
293
294 # Parse the command line
295 OPTS=$(getopt -o vhc:t:b:d: --long version,help,commit:,tag:,back:,debug: -- "$@")
296 eval set -- "$OPTS"
297
298 while true;
299 do
300         case "$1" in
301         -v | --version )
302                 echo "$version"
303                 exit
304                 ;;
305         -h | --help )
306                 echo "$description"
307                 exit
308                 ;;
309         -c | --commit )
310                 COMMIT="$2"
311                 shift
312                 shift
313                 ;;
314         -t | --tag )
315                 TAG="$2"
316                 shift;
317                 shift
318                 ;;
319         -b | --back )
320                 BACK="$2"
321                 shift;
322                 shift
323                 ;;
324         -d | --debug )
325                 DEBUG="$2"
326                 shift;
327                 shift
328                 ;;
329         * ) break
330                 ;;
331         esac
332 done
333
334 # If a Geeqie folder already exists here, warn the user
335 if [ -d "geeqie" ]
336 then
337         zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nA sub-folder of that name already exists.\nPlease try another folder." 2>/dev/null
338
339         exit
340 fi
341
342 # If it looks like a Geeqie download folder, assume an update
343 if [ -d ".git" ] && [ -d "src" ] && [ -f "geeqie.1" ]
344 then
345         mode="update"
346 else
347         # If it looks like something else is already installed here, warn the user
348         if [ -d ".git" ] || [ -d "src" ]
349         then
350                 zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nIt looks like you are running this script from a folder which already has software installed.\n\nPlease try another folder." 2>/dev/null
351
352                 exit
353         else
354                 mode="install"
355         fi
356 fi
357
358 # Use GTK3 as default
359 gk2_installed=FALSE
360 gtk3_installed=TRUE
361
362 if [[ $mode == "install" ]]
363 then
364         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nIn this dialog you must select whether to compile\nfor GTK2 or GTK3.\nIf you want to use GPS maps or pdf preview,\nyou must choose GTK3.\nThe GTK2 version has a slightly different\nlook-and-feel compared to the GTK3 version,\nbut otherwise has the same features.\nYou may easily switch between the two after\ninstallation.\n\nIn subsequent dialogs you may choose which\noptional features to install."
365
366         title="Install Geeqie and dependencies"
367         install_option=TRUE
368 else
369         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will update the Geeqie source code and its\ndependencies, and will compile and install Geeqie.\n\nYou may also switch the installed version from\nGTK2 to GTK3 and vice versa.\n\nIn this dialog you must select whether to compile\nfor GTK2 or GTK3.\nIf you want to use GPS maps or pdf preview,\nyou must choose GTK3.\nThe GTK2 version has a slightly different\nlook-and-feel compared to the GTK3 version,\nbut otherwise has the same features.\n\nIn subsequent dialogs you may choose which\noptional features to install."
370
371         title="Update Geeqie and re-install"
372         install_option=FALSE
373
374         # When updating, use previous installation as default
375         if [[ -f config.log ]]
376         then
377                 grep gtk-2.0 config.log >/dev/null
378                 if [[ $? != 0 ]]
379                 then
380                         gtk2_installed=FALSE
381                         gtk3_installed=TRUE
382                 else
383                         gtk2_installed=TRUE
384                         gtk3_installed=FALSE
385                 fi
386         fi
387 fi
388
389 # Ask whether to install GTK2 or GTK3 or uninstall
390
391 gtk_version=$(zenity --title="$title" --width=370 --text="$message" --list --radiolist --column "" --column "" "$gtk3_installed" "GTK3 (required for GPS maps and pdf preview)" "$gtk2_installed" "GTK2" FALSE "Uninstall" --cancel-label="Cancel" --ok-label="OK" --hide-header 2>/dev/null)
392
393 if [[ $? == 1 ]]
394 then
395         exit
396 fi
397
398 # Environment variable SUDO_ASKPASS cannot be "zenity --password",
399 # so create a temporary script containing the command
400 install_pass_script=$(mktemp --tmpdir geeqie_install_XXXXXX.sh)
401 echo $'#!/bin/bash
402 zenity --password --title=\"'$title$'\" --width=370 2>/dev/null
403 if [[ $? > 0 ]]
404 then
405         exit 1
406 fi
407 \n' > $install_pass_script
408 chmod +x $install_pass_script
409 export SUDO_ASKPASS=$install_pass_script
410
411 if [[ $gtk_version == "Uninstall" ]]
412 then
413         uninstall
414         exit
415 fi
416
417 # Put the install log in tmp, to avoid writing to PWD during a new install
418 rm install.log 2>/dev/null
419 install_log=$(mktemp --tmpdir geeqie_install_XXXXXX.log)
420
421 sleep 100 | zenity --title="$title" --text="Checking for installed files" --width=370 --progress --pulsate 2>/dev/null &
422 zen_pid=$!
423
424 # Get the standard options that are not yet installed
425 arraylength=${#optional_array[@]}
426 for (( i=0; i<${arraylength}; i=i+2 ));
427 do
428         package_query ${optional_array[$i+1]}
429         if [ $? != 0 ]
430         then
431                 if [ -z "$option_string" ]
432                 then
433                         option_string="$install_option"$'\n'"${optional_array[$i]}"$'\n'"${optional_array[$i+1]}"
434                 else
435                         option_string="$option_string"$'\n'"$install_option"$'\n'"${optional_array[$i]}"$'\n'"${optional_array[$i+1]}"
436                 fi
437         fi
438 done
439
440 # If GTK3 required, get the GTK3 options not yet installed
441 if [[ "$gtk_version" == "GTK3"* ]]
442 then
443         arraylength=${#optional_gtk3_array[@]}
444         for (( i=0; i<${arraylength}; i=i+2 ));
445         do
446                 package_query ${optional_gtk3_array[$i+1]}
447                 if [ $? != 0 ]
448                 then
449                         if [ -z "$option_string" ]
450                         then
451                                 option_string="$install_option"$'\n'"${optional_gtk3_array[$i]}"$'\n'"${optional_gtk3_array[$i+1]}"
452                         else
453                                 option_string="$option_string"$'\n'"$install_option"$'\n'"${optional_gtk3_array[$i]}"$'\n'"${optional_gtk3_array[$i+1]}"
454                         fi
455                 fi
456         done
457 fi
458
459 kill $zen_pid 2>/dev/null
460
461 # Ask the user which options to install
462 if [ -n "$option_string" ]
463 then
464         options=$(echo "$option_string" | zenity --title="$title" --width=400 --height=500 --list --checklist --text 'Select which library files to install:' --column='Select' --column='Library files' --column='Library' --hide-column=3 --print-column=3 2>/dev/null)
465
466         if [[ $? == 1 ]]
467         then
468                 exit_install
469         fi
470 fi
471
472 # Start of Zenity progress section
473 zen_pipe=$(mktemp --dry-run --tmpdir geeqie_install_pipe_XXXXXX)
474 mkfifo $zen_pipe
475 (tail  -f $zen_pipe 2>/dev/null) | zenity --progress --title="$title" --width=370 --text="Installing options..." --auto-close --auto-kill --percentage=0 2>/dev/null &
476
477 echo "2" > $zen_pipe
478 echo "#Installing essential libraries..." > $zen_pipe
479
480 install_essential $gtk_version
481
482 echo "4" > $zen_pipe
483 echo "#Installing options..." > $zen_pipe
484
485 install_options
486
487 echo "6" > $zen_pipe
488 echo "#Installing extra loaders..." > $zen_pipe
489
490 echo "10" > $zen_pipe
491 echo "#Getting new sources from server..." > $zen_pipe
492
493 if [[ $mode == "install" ]]
494 then
495         ret=$(git clone git://www.geeqie.org/geeqie.git >>$install_log 2>&1)
496 else
497         git checkout master >>$install_log 2>&1
498         if [[ $? != 0 ]]
499         then
500                 git_error=$(tail -n5 $install_log 2>&1)
501                 zenity --title="$title" --width=370 --height=400 --error --text=$'Git error:\n\n'"$git_error" 2>/dev/null
502                 exit_install
503         fi
504         ret=$(git pull >>$install_log 2>&1)
505 fi
506
507 if [[ $? != 0 ]]
508 then
509         git_error=$(tail -n5 $install_log 2>&1)
510         zenity --title="$title" --width=370 --height=400 --error --text=$'Git error:\n\n'"$git_error" 2>/dev/null
511         exit_install
512 fi
513
514 echo "20" > $zen_pipe
515 echo "#Cleaning installed version..." > $zen_pipe
516
517 if [[ $mode == "install" ]]
518 then
519         cd geeqie
520 else
521         sudo --askpass make uninstall >>$install_log 2>&1
522         sudo --askpass make maintainer-clean >>$install_log 2>&1
523 fi
524
525 echo "30" > $zen_pipe
526 echo "#Checkout required version..." > $zen_pipe
527
528 if [[ "$BACK" ]]
529 then
530         ret=$(git checkout master~"$BACK" >>$install_log 2>&1)
531         if [[ $? != 0 ]]
532         then
533                 git_error=$(tail -n5 $install_log 2>&1)
534                 zenity --title="$title" --width=370 --height=400 --error --text=$'Git error:\n\n'"$git_error" 2>/dev/null
535                 exit_install
536         fi
537 elif [[ "$COMMIT" ]]
538 then
539         ret=$(git checkout "$COMMIT" >>$install_log 2>&1)
540         if [[ $? != 0 ]]
541         then
542                 git_error=$(tail -n5 $install_log 2>&1)
543                 zenity --title="$title" --width=370 --height=400 --error --text=$'Git error:\n\n'"$git_error" 2>/dev/null
544                 exit_install
545         fi
546 elif [[ "$TAG" ]]
547 then
548         ret=$(git checkout "$TAG" >>$install_log 2>&1)
549         if [[ $? != 0 ]]
550         then
551         echo "error"
552                 git_error=$(tail -n5 $install_log 2>&1)
553                 zenity --title="$title" --width=370 --height=400 --error --text=$'Git error:\n\n'"$git_error" 2>/dev/null
554                 exit_install
555                 exit
556         fi
557 fi
558 if [[ "$DEBUG" == "yes" ]]
559 then
560         debug_opt=""
561 else
562         debug_opt="--disable-debug-log"
563 fi
564
565 echo "40" > $zen_pipe
566 echo "#Creating configuration files..." > $zen_pipe
567
568 if [[ $gtk_version == "GTK3"* ]]
569 then
570         ./autogen.sh "$debug_opt" >>$install_log 2>&1
571 else
572         ./autogen.sh "$debug_opt" --disable-gtk3 >>$install_log 2>&1
573 fi
574
575 echo "60" > $zen_pipe
576 echo "#Compiling..." > $zen_pipe
577
578 export CFLAGS=$CFLAGS" -Wno-deprecated-declarations"
579 export CXXFLAGS=$CXXFLAGS" -Wno-deprecated-declarations"
580 make -j >>$install_log 2>&1
581
582 if [[ $? != 0 ]]
583 then
584         zenity --title="$title" --width=370 --height=400 --error --text=$'Compile error' 2>/dev/null
585         exit_install
586         exit
587 fi
588
589 echo "90 " > $zen_pipe
590 echo "#Installing Geeqie..." > $zen_pipe
591
592 sudo --askpass make install >>$install_log 2>&1
593
594 rm $install_pass_script
595 mv -f $install_log install.log;
596
597 echo "100 " > $zen_pipe
598 rm $zen_pipe
599
600 (for i in $(seq 0 4 100); do echo "$i"; sleep 0.1; done) | zenity --progress --title="$title" --width=370 --text="Geeqie installation complete...\n$zonedetect_message" --auto-close --percentage=0 2>/dev/null
601
602 exit