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