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