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