-
Notifications
You must be signed in to change notification settings - Fork 109
/
qbittorrent-nox-static.sh
2796 lines (2595 loc) · 171 KB
/
qbittorrent-nox-static.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env bash
#
# cSpell:includeRegExp #.*
#
# Copyright 2020 by userdocs and contributors
#
# SPDX-License-Identifier: Apache-2.0
#
# @author - userdocs
#
# @contributors IceCodeNew Stanislas boredazfcuk AdvenT. guillaumedsde inochisa angristan xNihil0 Jercik
#
# https://github.com/userdocs/qbittorrent-nox-static/graphs/contributors
#
# @credits - https://gist.github.com/notsure2 https://github.com/c0re100/qBittorrent-Enhanced-Edition
#
# Script Formatting - https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format
#
#################################################################################################################################################
# Script version = Major minor patch
#################################################################################################################################################
script_version="2.0.11"
#################################################################################################################################################
# Set some script features - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
#################################################################################################################################################
set -a
#################################################################################################################################################
# Unset some variables to set defaults.
#################################################################################################################################################
unset qbt_skip_delete qbt_git_proxy qbt_curl_proxy qbt_install_dir qbt_build_dir qbt_working_dir qbt_modules_test qbt_python_version
#################################################################################################################################################
# Color me up Scotty - define some color values to use as variables in the scripts.
#################################################################################################################################################
color_red="\e[31m" color_red_light="\e[91m"
color_green="\e[32m" color_green_light="\e[92m"
color_yellow="\e[33m" color_yellow_light="\e[93m"
color_blue="\e[34m" color_blue_light="\e[94m"
color_magenta="\e[35m" color_magenta_light="\e[95m"
color_cyan="\e[36m" color_cyan_light="\e[96m"
text_bold="\e[1m" text_dim="\e[2m" text_underlined="\e[4m" text_blink="\e[5m" text_newline="\n"
unicode_red_circle="\e[31m\U2B24\e[0m" unicode_red_light_circle="\e[91m\U2B24\e[0m"
unicode_green_circle="\e[32m\U2B24\e[0m" unicode_green_light_circle="\e[92m\U2B24\e[0m"
unicode_yellow_circle="\e[33m\U2B24\e[0m" unicode_yellow_light_circle="\e[93m\U2B24\e[0m"
unicode_blue_circle="\e[34m\U2B24\e[0m" unicode_blue_light_circle="\e[94m\U2B24\e[0m"
unicode_magenta_circle="\e[35m\U2B24\e[0m" unicode_magenta_light_circle="\e[95m\U2B24\e[0m"
unicode_cyan_circle="\e[36m\U2B24\e[0m" unicode_cyan_light_circle="\e[96m\U2B24\e[0m"
unicode_grey_circle="\e[37m\U2B24\e[0m" unicode_grey_light_circle="\e[97m\U2B24\e[0m"
color_end="\e[0m"
# Function to test color and show outputs in the terminal
_color_test() {
# Check if the terminal supports color output
if [[ -t 1 ]]; then
colour_array=("${color_red}red" "${color_red_light}light red" "${color_green}green" "${color_green_light}light green" "${color_yellow}yellow" "${color_yellow_light}light yellow" "${color_blue}blue" "${color_blue_light}ligh blue" "${color_magenta}magenta" "${color_magenta_light}light magenta" "${color_cyan}cyan" "${color_cyan_light}light cyan")
formatting_array=("${text_bold}Text Bold" "${text_dim}Text Dim" "${text_underlined}Text Underline" "${text_newline}New line" "${text_blink}Text Blink")
unicode_array=("${unicode_red_circle}" "${unicode_red_light_circle}" "${unicode_green_circle}" "${unicode_green_light_circle}" "${unicode_yellow_circle}" "${unicode_yellow_light_circle}" "${unicode_blue_circle}" "${unicode_blue_light_circle}" "${unicode_magenta_circle}" "${unicode_magenta_light_circle}" "${unicode_cyan_circle}" "${unicode_cyan_light_circle}" "${unicode_grey_circle}" "${unicode_grey_light_circle}")
printf '\n'
for colours in "${colour_array[@]}" "${formatting_array[@]}" "${unicode_array[@]}"; do
printf '%b\n' "${colours}${color_end}"
done
printf '\n'
exit
else
echo "The terminal does not support color output."
exit 1
fi
}
[[ "${1}" == "ctest" ]] && _color_test # ./scriptname.sh ctest
#######################################################################################################################################################
# Check we are on a supported OS and release.
#######################################################################################################################################################
get_os_info() { # Function to source /etc/os-release and get info from it on demand.
# shellcheck source=/dev/null
if source /etc/os-release &> /dev/null; then
printf "%s" "${!1%_*}" # the exansion part is specific to the Alpine VERSION_ID format 1.2.3_alpha but won't break anything in Debian based format. 12/24.04
else
printf "%s" "unknown" # This will make the script exit on the version check and provide useful reason.
fi
}
os_id="$(get_os_info ID)" # Get the ID for this this OS.
os_version_codename="$(get_os_info VERSION_CODENAME)" # Get the codename for this this OS. Note, Alpine does not have a unique codename.
os_version_id="$(get_os_info VERSION_ID)" # Get the version number for this codename, for example: 10, 20.04, 3.12.4
[[ "$(wc -w <<< "${os_version_id//\./ }")" -eq "2" ]] && alpine_min_version="310" # Account for variation in the versioning 3.1 or 3.1.0 to make sure the check works correctly
[[ "${os_id}" =~ ^(alpine)$ ]] && os_version_codename="alpine" # If alpine, set the codename to alpine. We check for min v3.10 later with codenames.
# Check against allowed codenames or if the codename is alpine version greater than 3.10
if [[ ! "${os_version_codename}" =~ ^(alpine|bullseye|bookworm|focal|jammy|noble)$ ]] || [[ "${os_version_codename}" =~ ^(alpine)$ && "${os_version_id//\./}" -lt "${alpine_min_version:-3100}" ]]; then
printf '\n%b\n\n' " ${unicode_red_circle} ${color_yellow} This is not a supported OS. There is no reason to continue.${color_end}"
printf '%b\n\n' " id: ${text_dim}${color_yellow_light}${os_id}${color_end} codename: ${text_dim}${color_yellow_light}${os_version_codename}${color_end} version: ${text_dim}${color_red_light}${os_version_id}${color_end}"
printf '%b\n\n' " ${unicode_yellow_circle} ${text_dim}These are the supported platforms${color_end}"
printf '%b\n' " ${color_magenta_light}Debian${color_end} - ${color_blue_light}bullseye${color_end} - ${color_blue_light}bookworm${color_end}"
printf '%b\n' " ${color_magenta_light}Ubuntu${color_end} - ${color_blue_light}focal${color_end} - ${color_blue_light}jammy${color_end} - ${color_blue_light}noble${color_end}"
printf '%b\n\n' " ${color_magenta_light}Alpine${color_end} - ${color_blue_light}3.10.0${color_end} ${text_dim}or greater${color_end}"
exit 1
fi
#######################################################################################################################################################
# Source env vars from a file if it exists but it will be overridden by switches and flags passed to the script
#######################################################################################################################################################
if [[ -f "${PWD}/.qbt_env" ]]; then
printf '\n%b\n' " ${unicode_magenta_circle} Sourcing .qbt_env file"
# shellcheck source=/dev/null
source "${PWD}/.qbt_env"
fi
#######################################################################################################################################################
# Multi arch stuff
#######################################################################################################################################################
# Define all available multi arches we use from here https://github.com/userdocs/qbt-musl-cross-make#readme
declare -gA multi_arch_options
multi_arch_options[default]="skip"
multi_arch_options[armel]="armel"
multi_arch_options[armhf]="armhf"
multi_arch_options[armv7]="armv7"
multi_arch_options[aarch64]="aarch64"
multi_arch_options[x86_64]="x86_64"
multi_arch_options[x86]="x86"
multi_arch_options[s390x]="s390x"
multi_arch_options[powerpc]="powerpc"
multi_arch_options[ppc64el]="ppc64el"
multi_arch_options[mips]="mips"
multi_arch_options[mipsel]="mipsel"
multi_arch_options[mips64]="mips64"
multi_arch_options[mips64el]="mips64el"
multi_arch_options[riscv64]="riscv64"
#######################################################################################################################################################
# This function sets some default values we use but whose values can be overridden by certain flags or exported as variables before running the script
#######################################################################################################################################################
_set_default_values() {
# For docker deploys to not get prompted to set the timezone.
export DEBIAN_FRONTEND="noninteractive" && TZ="Europe/London"
# The default build configuration is qmake + qt5, qbt_build_tool=cmake or -c will make qt6 and cmake default
qbt_build_tool="${qbt_build_tool:-cmake}"
# Default to empty to use host native build tools. This way we can build on native arch on a supported OS and skip cross build toolchains
qbt_cross_name="${qbt_cross_name:-default}"
# Default to host - we are not really using this for anything other than what it defaults to so no need to set it.
qbt_cross_target="${qbt_cross_target:-${os_id}}"
# yes to create debug build to use with gdb - disables stripping - for some reason libtorrent b2 builds are 200MB or larger. qbt_build_debug=yes or -d
qbt_build_debug="${qbt_build_debug:-no}"
# github actions workflows - use https://github.com/userdocs/qbt-workflow-files/releases/latest instead of direct downloads from various source locations.
# Provides an alternative source and does not spam download hosts when building matrix builds.
qbt_workflow_files="${qbt_workflow_files:-no}"
# github actions workflows - use the workflow files saved as artifacts instead of downloading from workflow files or host per matrix
qbt_workflow_artifacts="${qbt_workflow_artifacts:-no}"
# Provide a git username and repo in this format - username/repo
# In this repo the structure needs to be like this /patches/libtorrent/1.2.11/patch and/or /patches/qbittorrent/4.3.1/patch
# your patch file will be automatically fetched and loaded for those matching tags.
qbt_patches_url="${qbt_patches_url:-userdocs/qbittorrent-nox-static}"
# Default to this version of libtorrent is no tag or branch is specified. qbt_libtorrent_version=1.2 or -lt v1.2.18
qbt_libtorrent_version="${qbt_libtorrent_version:-2.0}"
# Use release Jamfile unless we need a specific fix from the relevant RC branch.
# Using this can also break builds when non backported changes are present which will require a custom jamfile
qbt_libtorrent_master_jamfile="${qbt_libtorrent_master_jamfile:-no}"
# Strip symbols by default as we need full debug builds to be useful gdb to backtrace so stripping is a sensible default optimisation.
qbt_optimise_strip="${qbt_optimise_strip:-yes}"
# Github actions specific - Build revisions - The workflow will set this dynamically so that the urls are not hardcoded to a single repo
qbt_revision_url="${qbt_revision_url:-userdocs/qbittorrent-nox-static}"
# Provide a path to check for cached local git repos and use those instead. Priority over workflow files.
qbt_cache_dir="${qbt_cache_dir%/}"
# Env setting for the icu tag
qbt_skip_icu="${qbt_skip_icu:-yes}"
# Env setting for the boost tag
qbt_boost_tag="${qbt_boost_tag:-}"
# Env setting for the libtorrent tag
qbt_libtorrent_tag="${qbt_libtorrent_tag:-}"
# Env setting for the Qt tag
qbt_qt_tag="${qbt_qt_tag:-}"
# Env setting for the qbittorrent tag
qbt_qbittorrent_tag="${qbt_qbittorrent_tag:-}"
# We are only using python3 but it's easier to just change this if we need to for some reason.
qbt_python_version="3"
# The Alpine repository we use for package sources
CDN_URL="http://dl-cdn.alpinelinux.org/alpine/edge/main" # for alpine
# Define our list of available modules in an array.
qbt_modules=("all" "install" "glibc" "zlib" "iconv" "icu" "openssl" "boost" "libtorrent" "double_conversion" "qtbase" "qttools" "qbittorrent")
# Create this array empty. Modules listed in or added to this array will be removed from the default list of modules, changing the behaviour of all or install
delete=()
# Create this array empty. Packages listed in or added to this array will be removed from the default list of packages, changing the list of installed dependencies
delete_pkgs=()
# Dynamic tests to change settings based on the use of qmake,cmake,strip and debug
if [[ "${qbt_build_debug}" = "yes" ]]; then
qbt_optimise_strip="no"
qbt_cmake_debug='ON'
qbt_libtorrent_debug='debug-symbols=on'
qbt_qbittorrent_debug='--enable-debug'
else
qbt_cmake_debug='OFF'
fi
# staticish builds
if [[ ${qbt_static_ish:=no} == "yes" ]]; then
qbt_ldflags_static=""
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then delete+=("glibc"); fi
if [[ ${qbt_cross_name} != "default" ]]; then
printf '\n%b\n\n' " ${unicode_red_light_circle} You cannot use the ${color_blue_light}-si${color_end} flag with cross compilation${color_end}"
exit 1
fi
else
qbt_ldflags_static="-static"
fi
# Dynamic tests to change settings based on the use of qmake,cmake,strip and debug
if [[ "${qbt_optimise_strip}" = "yes" && "${qbt_build_debug}" = "no" ]]; then
qbt_strip_qmake='strip'
qbt_strip_flags='-s'
else
qbt_strip_qmake='-nostrip'
qbt_strip_flags=''
fi
# Dynamic tests to change settings based on the use of qmake,cmake,strip and debug
case "${qbt_qt_version}" in
5)
if [[ "${qbt_build_tool}" != 'cmake' ]]; then
qbt_build_tool="qmake"
qbt_use_qt6="OFF"
fi
;;&
6)
qbt_build_tool="cmake"
qbt_use_qt6="ON"
;;&
"")
[[ "${qbt_build_tool}" == 'cmake' ]] && qbt_qt_version="6" || qbt_qt_version="5"
;;&
*)
[[ ! "${qbt_qt_version}" =~ ^(5|6)$ ]] && qbt_workflow_files="no"
[[ "${qbt_build_tool}" == 'qmake' && "${qbt_qt_version}" =~ ^6 ]] && qbt_build_tool="cmake"
[[ "${qbt_build_tool}" == 'cmake' && "${qbt_qt_version}" =~ ^5 ]] && qbt_build_tool="cmake" qbt_qt_version="6"
[[ "${qbt_build_tool}" == 'cmake' && "${qbt_qt_version}" =~ ^6 ]] && qbt_use_qt6="ON"
;;
esac
# If we are cross building then bootstrap the cross build tools we ned for the target arch else set native arch and remove the debian cross build tools
if [[ "${multi_arch_options[${qbt_cross_name}]}" == "${qbt_cross_name}" ]]; then
_multi_arch info_bootstrap
else
cross_arch="$(uname -m)"
delete_pkgs+=("crossbuild-essential-${cross_arch}")
fi
# if Alpine then delete modules we don't use and set the required packages array
if [[ "${os_id}" =~ ^(alpine)$ ]]; then
delete+=("glibc")
[[ -z "${qbt_cache_dir}" ]] && delete_pkgs+=("coreutils" "gpg")
qbt_required_pkgs=("autoconf" "automake" "bash" "bash-completion" "build-base" "coreutils" "curl" "git" "gpg" "pkgconf" "libtool" "perl" "python${qbt_python_version}" "python${qbt_python_version}-dev" "py${qbt_python_version}-numpy" "py${qbt_python_version}-numpy-dev" "linux-headers" "ttf-freefont" "graphviz" "cmake" "re2c")
fi
# if debian based then set the required packages array
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
[[ -z "${qbt_cache_dir}" ]] && delete_pkgs+=("autopoint" "gperf")
qbt_required_pkgs=("autopoint" "gperf" "gettext" "texinfo" "gawk" "bison" "build-essential" "crossbuild-essential-${cross_arch}" "curl" "pkg-config" "automake" "libtool" "git" "openssl" "perl" "python${qbt_python_version}" "python${qbt_python_version}-dev" "python${qbt_python_version}-numpy" "unzip" "graphviz" "re2c")
fi
# remove this module by default unless provided as a first argument to the script.
if [[ "${1}" != 'install' ]]; then
delete+=("install")
fi
# Don't remove the icu module if it was provided as a positional parameter.
# else skip icu by default unless the -i flag is provided.
if [[ "${qbt_skip_icu}" != 'yes' && "${*}" =~ ([[:space:]]|^)"icu"([[:space:]]|$) ]]; then
qbt_skip_icu="no"
elif [[ "${qbt_skip_icu}" != "no" ]]; then
delete+=("icu")
fi
# Configure default dependencies and modules if cmake is not specified
if [[ "${qbt_build_tool}" != 'cmake' ]]; then
delete+=("double_conversion")
delete_pkgs+=("unzip" "ttf-freefont" "graphviz" "cmake" "re2c")
else
[[ "${qbt_skip_icu}" != "no" ]] && delete+=("icu")
fi
# The default is 17 but can be manually defined via the env qbt_standard - this will be overridden by the _set_cxx_standard function in specific cases
qbt_standard="${qbt_standard:-17}" qbt_cxx_standard="c++${qbt_standard}"
# Set the working dir to our current location and all things well be relative to this location.
qbt_working_dir="$(pwd)"
# Used with printf. Use the qbt_working_dir variable but the ${HOME} path is replaced with a literal ~
qbt_working_dir_short="${qbt_working_dir/${HOME}/\~}"
# Install relative to the script location.
qbt_install_dir="${qbt_working_dir}/qbt-build"
# Used with printf. Use the qbt_install_dir variable but the ${HOME} path is replaced with a literal ~
qbt_install_dir_short="${qbt_install_dir/${HOME}/\~}"
# Get the local users $PATH before we isolate the script by setting HOME to the install dir in the _set_build_directory function.
qbt_local_paths="$PATH"
}
#######################################################################################################################################################
# This function will check for a list of defined dependencies from the qbt_required_pkgs array. Apps like python3-dev are dynamically set
#######################################################################################################################################################
_check_dependencies() {
printf '\n%b\n\n' " ${unicode_blue_light_circle} ${text_bold}Checking if required core dependencies are installed${color_end}"
# remove packages in the delete_pkgs from the qbt_required_pkgs array
for target in "${delete_pkgs[@]}"; do
for i in "${!qbt_required_pkgs[@]}"; do
if [[ "${qbt_required_pkgs[i]}" == "${target}" ]]; then
unset 'qbt_required_pkgs[i]'
fi
done
done
# Rebuild array to sort index from 0
qbt_required_pkgs=("${qbt_required_pkgs[@]}")
# This checks over the qbt_required_pkgs array for the OS specified dependencies to see if they are installed
for pkg in "${qbt_required_pkgs[@]}"; do
if [[ "${os_id}" =~ ^(alpine)$ ]]; then
pkgman() { apk info -e "${pkg}"; }
fi
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
pkgman() { dpkg -s "${pkg}"; }
fi
if pkgman > /dev/null 2>&1; then
printf '%b\n' " ${unicode_green_circle} ${pkg}"
else
if [[ -n "${pkg}" ]]; then
deps_installed="no"
printf '%b\n' " ${unicode_red_circle} ${pkg}"
qbt_checked_required_pkgs+=("$pkg")
fi
fi
done
# Check if user is able to install the dependencies, if yes then do so, if no then exit.
if [[ "${deps_installed}" == "no" ]]; then
if [[ "$(id -un)" == 'root' ]]; then
printf '\n%b\n\n' " ${unicode_blue_light_circle} ${color_green}Updating${color_end}"
if [[ "${os_id}" =~ ^(alpine)$ ]]; then
apk update --repository="${CDN_URL}"
apk upgrade --repository="${CDN_URL}"
apk fix
fi
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
apt-get update -y
apt-get upgrade -y
apt-get autoremove -y
fi
[[ -f /var/run/reboot-required ]] && {
printf '\n%b\n\n' " ${color_red}This machine requires a reboot to continue installation. Please reboot now.${color_end}"
exit
}
printf '\n%b\n\n' " ${unicode_blue_light_circle}${color_green} Installing required dependencies${color_end}"
if [[ "${os_id}" =~ ^(alpine)$ ]]; then
if ! apk add "${qbt_checked_required_pkgs[@]}" --repository="${CDN_URL}"; then
printf '\n'
exit 1
fi
fi
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
if ! apt-get install -y "${qbt_checked_required_pkgs[@]}"; then
printf '\n'
exit 1
fi
fi
printf '\n%b\n' " ${unicode_green_circle}${color_green} Dependencies installed!${color_end}"
deps_installed="yes"
else
printf '\n%b\n' " ${text_bold}Please request or install the missing core dependencies before using this script${color_end}"
if [[ "${os_id}" =~ ^(alpine)$ ]]; then
printf '\n%b\n\n' " ${color_red_light}apk add${color_end} ${qbt_checked_required_pkgs[*]}"
fi
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
printf '\n%b\n\n' " ${color_red_light}apt-get install -y${color_end} ${qbt_checked_required_pkgs[*]}"
fi
exit
fi
fi
# All dependency checks passed print
if [[ "${deps_installed}" != "no" ]]; then
printf '\n%b\n' " ${unicode_green_circle}${text_bold} Dependencies: All checks passed, continuing to build${color_end}"
fi
}
#######################################################################################################################################################
# This function converts a version string to a number for comparison purposes.
#######################################################################################################################################################
_semantic_version() {
local test_array
read -ra test_array < <(printf "%s" "${@//./ }")
printf "%d%03d%03d%03d" "${test_array[@]}"
}
#######################################################################################################################################################
# _print_env
#######################################################################################################################################################
_print_env() {
printf '\n%b\n\n' " ${unicode_yellow_circle} Default env settings${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_libtorrent_version=\"${color_green_light}${qbt_libtorrent_version}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_qt_version=\"${color_green_light}${qbt_qt_version}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_build_tool=\"${color_green_light}${qbt_build_tool}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_cross_name=\"${color_green_light}${qbt_cross_name}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_patches_url=\"${color_green_light}${qbt_patches_url}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_skip_icu=\"${color_green_light}${qbt_skip_icu}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_boost_tag=\"${color_green_light}${github_tag[boost]}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_libtorrent_tag=\"${color_green_light}${github_tag[libtorrent]}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_qt_tag=\"${color_green_light}${github_tag[qtbase]}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_qbittorrent_tag=\"${color_green_light}${github_tag[qbittorrent]}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_libtorrent_master_jamfile=\"${color_green_light}${qbt_libtorrent_master_jamfile}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_workflow_files=\"${color_green_light}${qbt_workflow_files}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_workflow_artifacts=\"${color_green_light}${qbt_workflow_artifacts}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_cache_dir=\"${color_green_light}${qbt_cache_dir}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_optimise_strip=\"${color_green_light}${qbt_optimise_strip}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_build_debug=\"${color_green_light}${qbt_build_debug}${color_yellow_light}\"${color_end}"
printf '%b\n' " ${color_yellow_light} qbt_standard=\"${color_green_light}${qbt_standard}${color_yellow_light}\"${color_end}"
printf '%b\n\n' " ${color_yellow_light} qbt_static_ish=\"${color_green_light}${qbt_static_ish}${color_yellow_light}\"${color_end}"
}
#######################################################################################################################################################
# These functions set the cxx standard dynmically based on the libtorrent versions, qt version and qbittorrent combinations
#######################################################################################################################################################
_qt_std_cons() {
[[ "${qbt_qt_version}" == "6" ]] && cxx_check="yes"
printf '%s' "${cxx_check:-no}"
}
_libtorrent_std_cons() {
[[ "${github_tag[libtorrent]}" =~ ^(RC_1_2|RC_2_0)$ ]] && cxx_check="yes"
[[ "${github_tag[libtorrent]}" =~ ^v1\.2\. && "$(_semantic_version "${github_tag[libtorrent]/v/}")" -ge "$(_semantic_version "1.2.20")" ]] && cxx_check="yes"
[[ "${github_tag[libtorrent]}" =~ ^v2\.0\. && "$(_semantic_version "${github_tag[libtorrent]/v/}")" -ge "$(_semantic_version "2.0.10")" ]] && cxx_check="yes"
printf '%s' "${cxx_check:-no}"
}
_qbittorrent_std_cons() {
[[ "${github_tag[qbittorrent]}" == "master" ]] && cxx_check="yes"
[[ "${github_tag[qbittorrent]}" =~ ^release- && "$(_semantic_version "${github_tag[qbittorrent]/release-/}")" -ge "$(_semantic_version "4.6.0")" ]] && cxx_check="yes"
printf '%s' "${cxx_check:-no}"
}
_set_cxx_standard() {
if [[ $(_qt_std_cons) == "yes" && $(_libtorrent_std_cons) == "yes" && $(_qbittorrent_std_cons) == "yes" ]]; then
if [[ "${os_version_codename}" =~ ^(alpine|bookworm|jammy|noble)$ ]]; then
qbt_standard="20" qbt_cxx_standard="c++${qbt_standard}"
fi
fi
}
#######################################################################################################################################################
# These functions set some build conditions dynmically based on the libtorrent versions, qt version and qbittorrent combinations
#######################################################################################################################################################
_qbittorrent_build_cons() {
[[ "${github_tag[qbittorrent]}" == "master" ]] && disable_qt5="yes"
[[ "${github_tag[qbittorrent]}" == "v5_0_x" ]] && disable_qt5="yes"
[[ "${github_tag[qbittorrent]}" =~ ^release- && "$(_semantic_version "${github_tag[qbittorrent]/release-/}")" -ge "$(_semantic_version "5.0.0")" ]] && disable_qt5="yes"
printf '%s' "${disable_qt5:-no}"
}
_set_build_cons() {
if [[ $(_qbittorrent_build_cons) == "yes" && "${qbt_qt_version}" == "5" ]]; then
printf '\n%b\n\n' " ${text_blink}${unicode_red_light_circle}${color_end} ${color_yellow}qBittorrent ${color_magenta}${github_tag[qbittorrent]}${color_yellow} does not support ${color_red}Qt5${color_yellow}. Please use ${color_green}Qt6${color_yellow} or a qBittorrent ${color_green}v4${color_yellow} tag.${color_end}"
if [[ -d "${release_info_dir}" ]]; then touch "${release_info_dir}/disable-qt5"; fi # qbittorrent v5 transtion - workflow specific
exit # non error exit to not upset github actions - just skip the step
fi
}
#######################################################################################################################################################
# This is a command test function: _cmd exit 1
#######################################################################################################################################################
_cmd() {
if ! "${@}"; then
printf '\n%b\n\n' " The command: ${color_red_light}${*}${color_end} failed"
exit 1
fi
}
#######################################################################################################################################################
# This is a command test function to test build commands for failure
#######################################################################################################################################################
_post_command() {
outcome=("${PIPESTATUS[@]}")
[[ -n "${1}" ]] && command_type="${1}"
if [[ "${outcome[*]}" =~ [1-9] ]]; then
printf '\n%b\n' " ${unicode_red_circle}${color_red} Error:${color_end} The ${command_type:-tested} command produced an exit code greater than 0 - Check the logs ${color_end}"
printf '\n%b\n' " ${unicode_yellow_circle}${color_yellow} Warning:${color_end} Developers can be easily startled or confused by wild issues, if you are seeing this warning and cannot resolve the issue yourself, please open an issue at this repo first:"
printf '\n%b\n\n' " ${unicode_blue_circle}${color_blue_light} https://github.com/userdocs/qbittorrent-nox-static/issues ${color_end}"
exit 1
fi
}
#######################################################################################################################################################
# This function is to test a directory exists before attempting to cd and fail with and exit code if it doesn't.
#######################################################################################################################################################
_pushd() {
if ! pushd "$@" &> /dev/null; then
printf '\n%b\n' "This directory does not exist. There is a problem"
printf '\n%b\n\n' "${color_red_light}${1}${color_end}"
exit 1
fi
}
_popd() {
if ! popd &> /dev/null; then
printf '%b\n' "This directory does not exist. There is a problem"
exit 1
fi
}
#######################################################################################################################################################
# This function makes sure the log directory and path required exists for tee
#######################################################################################################################################################
_tee() {
[[ "$#" -eq 1 && "${1%/*}" =~ / ]] && mkdir -p "${1%/*}"
[[ "$#" -eq 2 && "${2%/*}" =~ / ]] && mkdir -p "${2%/*}"
command tee "$@"
}
#######################################################################################################################################################
# error functions
#######################################################################################################################################################
_error_tag() {
[[ "${github_tag[*]}" =~ error_tag ]] && {
printf '\n'
exit
}
}
#######################################################################################################################################################
# _curl test download functions - default is no proxy - _curl is a test function and _curl_curl is the command function
#######################################################################################################################################################
_curl_curl() {
"$(type -P curl)" -sNL4fq --connect-timeout 5 --retry 5 --retry-delay 5 --retry-max-time 25 "${qbt_curl_proxy[@]}" "${@}"
}
_curl() {
if ! _curl_curl "${@}"; then
return 1
fi
}
#######################################################################################################################################################
# git test download functions - default is no proxy - git is a test function and _git_git is the command function
#######################################################################################################################################################
_git_git() {
"$(type -P git)" "${qbt_git_proxy[@]}" "${@}"
}
_git() {
if [[ "${2}" == '-t' ]]; then
git_test_cmd=("${1}" "${2}" "${3}")
else
[[ "${9}" =~ https:// ]] && git_test_cmd=("${9}") # 9th place in our download folder function for qttools
[[ "${11}" =~ https:// ]] && git_test_cmd=("${11}") # 11th place in our download folder function
fi
if ! _curl -fIL "${git_test_cmd[@]}" &> /dev/null; then
printf '\n%b\n\n' " ${color_yellow}Git test 1: There is an issue with your proxy settings or network connection${color_end}"
exit
fi
status="$(
_git_git ls-remote -qht --refs --exit-code "${git_test_cmd[@]}" &> /dev/null
printf "%s" "${?}"
)"
if [[ "${2}" == '-t' && "${status}" -eq '0' ]]; then
printf '%b\n' "${3}"
elif [[ "${2}" == '-t' && "${status}" -ge '1' ]]; then
printf '%b\n' 'error_tag'
else
if ! _git_git "${@}"; then
printf '\n%b\n\n' " ${color_yellow}Git test 2: There is an issue with your proxy settings or network connection${color_end}"
exit
fi
fi
}
_test_git_ouput() {
if [[ "${1}" == 'error_tag' ]]; then
printf '\n%b\n' " ${text_blink}${unicode_red_light_circle}${color_end} ${color_yellow}The provided ${2} tag ${color_red}${3}${color_end}${color_yellow} is not valid${color_end}"
fi
}
#######################################################################################################################################################
# Boost URL test function
#######################################################################################################################################################
_boost_url() {
if [[ "${github_tag[boost]}" =~ \.beta ]]; then
local boost_asset="${github_tag[boost]/\.beta/\.b}"
local boost_asset_type="beta"
else
local boost_asset="${github_tag[boost]}"
local boost_asset_type="release"
fi
local boost_url_array=(
"https://boostorg.jfrog.io/artifactory/main/${boost_asset_type}/${github_tag[boost]/boost-/}/source/${boost_asset//[-\.]/_}.tar.gz"
"https://archives.boost.io/${boost_asset_type}/${github_tag[boost]/boost-/}/source/${boost_asset//[-\.]/_}.tar.gz"
)
for url in "${boost_url_array[@]}"; do
if _curl -sfLI "${url}" &> /dev/null; then
boost_url_status="200"
source_archive_url[boost]="${url}"
source_default[boost]="file"
break
else
boost_url_status="403"
source_default[boost]="folder"
fi
done
}
#######################################################################################################################################################
# Debug stuff
#######################################################################################################################################################
_debug() {
if [[ "${script_debug_urls}" == "yes" ]]; then
mapfile -t github_url_sorted < <(printf '%s\n' "${!github_url[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}github_url${color_end}"
for n in "${github_url_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${github_url[$n]}${color_end}" #: ${github_url[$n]}"
done
mapfile -t github_tag_sorted < <(printf '%s\n' "${!github_tag[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}github_tag${color_end}"
for n in "${github_tag_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${github_tag[$n]}${color_end}" #: ${github_url[$n]}"
done
mapfile -t app_version_sorted < <(printf '%s\n' "${!app_version[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}app_version${color_end}"
for n in "${app_version_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${app_version[$n]}${color_end}" #: ${github_url[$n]}"
done
mapfile -t source_archive_url_sorted < <(printf '%s\n' "${!source_archive_url[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}source_archive_url${color_end}"
for n in "${source_archive_url_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${source_archive_url[$n]}${color_end}" #: ${github_url[$n]}"
done
mapfile -t qbt_workflow_archive_url_sorted < <(printf '%s\n' "${!qbt_workflow_archive_url[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}qbt_workflow_archive_url${color_end}"
for n in "${qbt_workflow_archive_url_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${qbt_workflow_archive_url[$n]}${color_end}" #: ${github_url[$n]}"
done
mapfile -t source_default_sorted < <(printf '%s\n' "${!source_default[@]}" | sort)
printf '\n%b\n\n' " ${unicode_magenta_circle} ${color_yellow_light}source_default${color_end}"
for n in "${source_default_sorted[@]}"; do
printf '%b\n' " ${color_green_light}$n${color_end}: ${color_blue_light}${source_default[$n]}${color_end}" #: ${github_url[$n]}"
done
printf '\n%b\n' " ${unicode_magenta_circle} ${color_yellow_light}Tests${color_end}"
printf '\n%b\n' " ${color_green_light}boost_url_status:${color_end} ${color_blue_light}${boost_url_status}${color_end}"
printf '%b\n' " ${color_green_light}test_url_status:${color_end} ${color_blue_light}${test_url_status}${color_end}"
printf '\n'
exit
fi
}
#######################################################################################################################################################
# This function sets some compiler flags globally - b2 settings are set in the ~/user-config.jam set in the _installation_modules function
#######################################################################################################################################################
_custom_flags_set() {
CXXFLAGS="${qbt_optimize/*/${qbt_optimize} }-std=${qbt_cxx_standard} ${qbt_ldflags_static} -w -Wno-psabi -I${include_dir}"
CPPFLAGS="${qbt_optimize/*/${qbt_optimize} }${qbt_ldflags_static} -w -Wno-psabi -I${include_dir}"
LDFLAGS="${qbt_optimize/*/${qbt_optimize} }${qbt_ldflags_static} ${qbt_strip_flags} -L${lib_dir} -pthread -z max-page-size=65536"
}
_custom_flags_reset() {
CXXFLAGS="${qbt_optimize/*/${qbt_optimize} } -w -std=${qbt_cxx_standard}"
CPPFLAGS="${qbt_optimize/*/${qbt_optimize} } -w"
LDFLAGS=""
}
#######################################################################################################################################################
# This function installs a completed static build of qbittorrent-nox to the /usr/local/bin for root or ${HOME}/bin for non root
#######################################################################################################################################################
_install_qbittorrent() {
if [[ -f "${qbt_install_dir}/completed/qbittorrent-nox" ]]; then
if [[ "$(id -un)" == 'root' ]]; then
mkdir -p "/usr/local/bin"
cp -rf "${qbt_install_dir}/completed/qbittorrent-nox" "/usr/local/bin"
else
mkdir -p "${HOME}/bin"
cp -rf "${qbt_install_dir}/completed/qbittorrent-nox" "${LOCAL_USER_HOME}/bin"
fi
printf '\n%b\n' " ${unicode_blue_light_circle} qbittorrent-nox has been installed!${color_end}"
printf '\n%b\n' " Run it using this command:"
[[ "$(id -un)" == 'root' ]] && printf '\n%b\n\n' " ${color_green}qbittorrent-nox${color_end}" || printf '\n%b\n\n' " ${color_green}~/bin/qbittorrent-nox${color_end}"
exit
else
printf '\n%b\n\n' " ${unicode_red_circle} qbittorrent-nox has not been built to the defined install directory:"
printf '\n%b\n' "${color_green}${qbt_install_dir_short}/completed${color_end}"
printf '\n%b\n\n' "Please build it using the script first then install"
exit
fi
}
#######################################################################################################################################################
# Script Version check
#######################################################################################################################################################
_script_version() {
script_version_remote="$(_curl -sL "${script_url}" | sed -rn 's|^script_version="(.*)"$|\1|p')"
if [[ "$(_semantic_version "${script_version}")" -lt "$(_semantic_version "${script_version_remote}")" ]]; then
printf '\n%b\n' " ${text_blink}${unicode_red_circle}${color_end} Script update available! Versions - ${color_yellow_light}local:${color_red_light}${script_version}${color_end} ${color_yellow_light}remote:${color_green_light}${script_version_remote}${color_end}"
printf '\n%b\n' " ${unicode_green_circle} curl -sLo ${BASH_SOURCE[0]} https://git.io/qbstatic${color_end}"
elif [[ "$(_semantic_version "${script_version}")" -gt "$(_semantic_version "${script_version_remote}")" ]]; then
printf '\n%b\n' " ${unicode_green_circle} Script version: ${color_red_light}${script_version}-dev${color_end}"
else
printf '\n%b\n' " ${unicode_green_circle} Script version: ${color_green_light}${script_version}${color_end}"
fi
}
#######################################################################################################################################################
# URL test for normal use and proxy use - make sure we can reach google.com before processing the URL functions
#######################################################################################################################################################
_test_url() {
test_url_status="$(_curl -o /dev/null --head --write-out '%{http_code}' "https://github.com")"
if [[ "${test_url_status}" -eq "200" ]]; then
printf '\n%b\n' " ${unicode_green_circle} Test URL = ${color_green}passed${color_end}"
else
printf '\n%b\n\n' " ${unicode_red_circle} ${color_yellow}Test URL failed:${color_end} ${color_yellow_light}There could be an issue with your proxy settings or network connection${color_end}"
exit
fi
}
#######################################################################################################################################################
# This function sets the build and installation directory. If the argument -b is used to set a build directory that directory is set and used.
# If nothing is specified or the switch is not used it defaults to the hard-coded path relative to the scripts location - qbittorrent-build
#######################################################################################################################################################
_set_build_directory() {
if [[ -n "${qbt_build_dir}" ]]; then
if [[ "${qbt_build_dir}" =~ ^/ ]]; then
qbt_install_dir="${qbt_build_dir}"
qbt_install_dir_short="${qbt_install_dir/${HOME}/\~}"
else
qbt_install_dir="${qbt_working_dir}/${qbt_build_dir}"
qbt_install_dir_short="${qbt_working_dir_short}/${qbt_build_dir}"
fi
fi
# Set lib and include directory paths based on install path.
include_dir="${qbt_install_dir}/include"
lib_dir="${qbt_install_dir}/lib"
# Define some build specific variables
LOCAL_USER_HOME="${HOME}" # Get the local user's home dir path before we contain HOME to the build dir.
HOME="${qbt_install_dir}"
PATH="${qbt_install_dir}/bin${PATH:+:${qbt_local_paths}}"
PKG_CONFIG_PATH="${lib_dir}/pkgconfig"
}
#######################################################################################################################################################
# This function is where we set your URL and github tag info that we use with other functions.
#######################################################################################################################################################
_set_module_urls() {
# Update check url for the _script_version function
script_url="https://raw.githubusercontent.com/userdocs/qbittorrent-nox-static/master/qbittorrent-nox-static.sh"
##########################################################################################################################################################
# Create all the arrays now
##########################################################################################################################################################
declare -gA github_url github_tag app_version source_archive_url qbt_workflow_archive_url qbt_workflow_override source_default
##########################################################################################################################################################
# Configure the github_url associative array for all the applications this script uses and we call them as ${github_url[app_name]}
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
github_url[cmake_ninja]="https://github.com/userdocs/qbt-cmake-ninja-crossbuilds.git"
github_url[glibc]="https://sourceware.org/git/glibc.git"
else
github_url[ninja]="https://github.com/userdocs/qbt-ninja-build.git"
fi
github_url[zlib]="https://github.com/zlib-ng/zlib-ng.git"
github_url[iconv]="https://git.savannah.gnu.org/git/libiconv.git"
github_url[icu]="https://github.com/unicode-org/icu.git"
github_url[double_conversion]="https://github.com/google/double-conversion.git"
github_url[openssl]="https://github.com/openssl/openssl.git"
github_url[boost]="https://github.com/boostorg/boost.git"
github_url[libtorrent]="https://github.com/arvidn/libtorrent.git"
github_url[qtbase]="https://github.com/qt/qtbase.git"
github_url[qttools]="https://github.com/qt/qttools.git"
github_url[qbittorrent]="https://github.com/qbittorrent/qBittorrent.git"
##########################################################################################################################################################
# Configure the github_tag associative array for all the applications this script uses and we call them as ${github_tag[app_name]}
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
github_tag[cmake_ninja]="$(_git_git ls-remote -q -t --refs "${github_url[cmake_ninja]}" | awk '{sub("refs/tags/", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
if [[ "${os_version_codename}" =~ ^(bullseye|focal)$ ]]; then
github_tag[glibc]="glibc-2.31"
elif [[ "${os_version_codename}" =~ ^(bookworm|jammy)$ ]]; then
github_tag[glibc]="glibc-2.38"
else # "$(_git_git ls-remote -q -t --refs https://sourceware.org/git/glibc.git | awk '/\/tags\/glibc-[0-9]\.[0-9]{2}$/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[glibc]="glibc-2.40"
fi
else
github_tag[ninja]="$(_git_git ls-remote -q -t --refs "${github_url[ninja]}" | awk '/v/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
fi
github_tag[zlib]="develop"
#github_tag[iconv]="$(_git_git ls-remote -q -t --refs "${github_url[iconv]}" | awk '{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[iconv]="v$(_curl "https://github.com/userdocs/qbt-workflow-files/releases/latest/download/dependency-version.json" | sed -rn 's|(.*)"iconv": "(.*)",|\2|p')"
github_tag[icu]="$(_git_git ls-remote -q -t --refs "${github_url[icu]}" | awk '/\/release-/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[double_conversion]="$(_git_git ls-remote -q -t --refs "${github_url[double_conversion]}" | awk '/v/{sub("refs/tags/", "");sub("(.*)(v6|rc|alpha|beta)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[openssl]="$(_git_git ls-remote -q -t --refs "${github_url[openssl]}" | awk '/openssl/{sub("refs/tags/", "");sub("(.*)(v6|rc|alpha|beta)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n1)"
github_tag[boost]=$(_git_git ls-remote -q -t --refs "${github_url[boost]}" | awk '{sub("refs/tags/", "");sub("(.*)(rc|alpha|beta|-bgl)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)
github_tag[libtorrent]="$(_git_git ls-remote -q -t --refs "${github_url[libtorrent]}" | awk '/'"v${qbt_libtorrent_version}"'/{sub("refs/tags/", "");sub("(.*)(-[^0-9].*)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[qtbase]="$(_git_git ls-remote -q -t --refs "${github_url[qtbase]}" | awk '/'"v${qbt_qt_version}"'/{sub("refs/tags/", "");sub("(.*)(-a|-b|-r)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[qttools]="$(_git_git ls-remote -q -t --refs "${github_url[qttools]}" | awk '/'"v${qbt_qt_version}"'/{sub("refs/tags/", "");sub("(.*)(-a|-b|-r)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
github_tag[qbittorrent]="$(_git_git ls-remote -q -t --refs "${github_url[qbittorrent]}" | awk '{sub("refs/tags/", "");sub("(.*)(-[^0-9].*|rc|alpha|beta)(.*)", ""); print $2 }' | awk '!/^$/' | sort -rV | head -n 1)"
##########################################################################################################################################################
# Configure the app_version associative array for all the applications this script uses and we call them as ${app_version[app_name]}
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
app_version[cmake_debian]="${github_tag[cmake_ninja]%_*}"
app_version[ninja_debian]="${github_tag[cmake_ninja]#*_}"
app_version[glibc]="${github_tag[glibc]#glibc-}"
else
app_version[cmake]="$(apk info -d cmake | awk '/cmake-/{sub("(cmake-)", "");sub("(-r)", ""); print $1 }' | sort -r | head -n1)"
app_version[ninja]="${github_tag[ninja]#v}"
fi
app_version[zlib]="$(_curl "https://raw.githubusercontent.com/zlib-ng/zlib-ng/${github_tag[zlib]}/zlib.h.in" | sed -rn 's|#define ZLIB_VERSION "(.*)"|\1|p' | sed 's/\.zlib-ng//g')"
app_version[iconv]="${github_tag[iconv]#v}"
app_version[icu]="${github_tag[icu]#release-}"
app_version[double_conversion]="${github_tag[double_conversion]#v}"
app_version[openssl]="${github_tag[openssl]#openssl-}"
app_version[boost]="${github_tag[boost]#boost-}"
app_version[libtorrent]="${github_tag[libtorrent]#v}"
app_version[qtbase]="$(printf '%s' "${github_tag[qtbase]#v}" | sed 's/-lts-lgpl//g')"
app_version[qttools]="$(printf '%s' "${github_tag[qttools]#v}" | sed 's/-lts-lgpl//g')"
app_version[qbittorrent]="${github_tag[qbittorrent]#release-}"
##########################################################################################################################################################
# Configure the source_archive_url associative array for all the applications this script uses and we call them as ${source_archive_url[app_name]}
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
source_archive_url[cmake_ninja]="https://github.com/userdocs/qbt-cmake-ninja-crossbuilds/releases/latest/download/${os_id}-${os_version_codename}-cmake-$(dpkg --print-architecture).tar.xz"
source_archive_url[glibc]="https://ftpmirror.gnu.org/gnu/libc/${github_tag[glibc]}.tar.xz"
fi
source_archive_url[zlib]="https://github.com/zlib-ng/zlib-ng/archive/refs/heads/develop.tar.gz"
source_archive_url[iconv]="https://mirrors.dotsrc.org/gnu/libiconv/$(grep -Eo 'libiconv-([0-9]{1,3}[.]?)([0-9]{1,3}[.]?)([0-9]{1,3}?)\.tar.gz' <(_curl https://mirrors.dotsrc.org/gnu/libiconv/) | sort -V | tail -1)"
source_archive_url[icu]="https://github.com/unicode-org/icu/releases/download/${github_tag[icu]}/icu4c-${app_version[icu]/-/_}-src.tgz"
source_archive_url[double_conversion]="https://github.com/google/double-conversion/archive/refs/tags/${github_tag[double_conversion]}.tar.gz"
source_archive_url[openssl]="https://github.com/openssl/openssl/releases/download/${github_tag[openssl]}/${github_tag[openssl]}.tar.gz"
_boost_url # function to test and set the boost url and more
source_archive_url[libtorrent]="https://github.com/arvidn/libtorrent/releases/download/${github_tag[libtorrent]}/libtorrent-rasterbar-${github_tag[libtorrent]#v}.tar.gz"
read -ra qt_version_short_array <<< "${app_version[qtbase]//\./ }"
qt_version_short="${qt_version_short_array[0]}.${qt_version_short_array[1]}"
if [[ "${qbt_qt_version}" =~ ^6 ]]; then
source_archive_url[qtbase]="https://download.qt.io/official_releases/qt/${qt_version_short}/${app_version[qtbase]}/submodules/qtbase-everywhere-src-${app_version[qtbase]}.tar.xz"
source_archive_url[qttools]="https://download.qt.io/official_releases/qt/${qt_version_short}/${app_version[qttools]}/submodules/qttools-everywhere-src-${app_version[qttools]}.tar.xz"
else
source_archive_url[qtbase]="https://download.qt.io/official_releases/qt/${qt_version_short}/${app_version[qtbase]}/submodules/qtbase-everywhere-opensource-src-${app_version[qtbase]}.tar.xz"
source_archive_url[qttools]="https://download.qt.io/official_releases/qt/${qt_version_short}/${app_version[qttools]}/submodules/qttools-everywhere-opensource-src-${app_version[qttools]}.tar.xz"
fi
source_archive_url[qbittorrent]="https://github.com/qbittorrent/qBittorrent/archive/refs/tags/${github_tag[qbittorrent]}.tar.gz"
##########################################################################################################################################################
# Configure the qbt_workflow_archive_url associative array for all the applications this script uses and we call them as ${qbt_workflow_archive_url[app_name]}
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
qbt_workflow_archive_url[cmake_ninja]="${source_archive_url[cmake_ninja]}"
qbt_workflow_archive_url[glibc]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/glibc.${github_tag[glibc]#glibc-}.tar.xz"
fi
qbt_workflow_archive_url[zlib]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/zlib.tar.xz"
qbt_workflow_archive_url[iconv]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/iconv.tar.xz"
qbt_workflow_archive_url[icu]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/icu.tar.xz"
qbt_workflow_archive_url[double_conversion]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/double_conversion.tar.xz"
qbt_workflow_archive_url[openssl]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/openssl.tar.xz"
qbt_workflow_archive_url[boost]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/boost.tar.xz"
qbt_workflow_archive_url[libtorrent]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/libtorrent.${github_tag[libtorrent]/v/}.tar.xz"
qbt_workflow_archive_url[qtbase]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/qt${qbt_qt_version:0:1}base.tar.xz"
qbt_workflow_archive_url[qttools]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/qt${qbt_qt_version:0:1}tools.tar.xz"
qbt_workflow_archive_url[qbittorrent]="https://github.com/userdocs/qbt-workflow-files/releases/latest/download/qbittorrent.tar.xz"
##########################################################################################################################################################
# Configure workflow override options
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
qbt_workflow_override[cmake_ninja]="no"
qbt_workflow_override[glibc]="no"
fi
qbt_workflow_override[zlib]="no"
qbt_workflow_override[iconv]="no"
qbt_workflow_override[icu]="no"
qbt_workflow_override[double_conversion]="no"
qbt_workflow_override[openssl]="no"
qbt_workflow_override[boost]="no"
qbt_workflow_override[libtorrent]="no"
qbt_workflow_override[qtbase]="no"
qbt_workflow_override[qttools]="no"
qbt_workflow_override[qbittorrent]="no"
##########################################################################################################################################################
# Configure the default source type we use for the download function
##########################################################################################################################################################
if [[ "${os_id}" =~ ^(debian|ubuntu)$ ]]; then
source_default[cmake_ninja]="file"
source_default[glibc]="file"
fi
source_default[zlib]="file"
source_default[iconv]="file"
source_default[icu]="file"
source_default[double_conversion]="file"
source_default[openssl]="file"
source_default[boost]="file"
source_default[libtorrent]="file"
source_default[qtbase]="file"
source_default[qttools]="file"
source_default[qbittorrent]="file"
##########################################################################################################################################################
#
##########################################################################################################################################################
return
}
#######################################################################################################################################################
# This function verifies the module names from the array qbt_modules in the default values function.
#######################################################################################################################################################
_installation_modules() {
# Delete modules - using the the delete array to unset them from the qbt_modules array
for target in "${delete[@]}"; do
for deactivated in "${!qbt_modules[@]}"; do
[[ "${qbt_modules[${deactivated}]}" == "${target}" ]] && unset 'qbt_modules[${deactivated}]'
done
done
unset target deactivated
# For any modules params passed, test that they exist in the qbt_modules array or set qbt_modules_test to fail
for passed_params in "${@}"; do
if [[ ! "${qbt_modules[*]}" =~ (^|[^[:alpha:]])${passed_params}([^[:alpha:]]|$) ]]; then
qbt_modules_test="fail"
fi
done
unset passed_params
if [[ "${qbt_modules_test}" != 'fail' && "${#}" -ne '0' ]]; then
if [[ "${1}" == "all" ]]; then
# If all is passed as a module and once the params check = pass has triggered this condition, remove to from the qbt_modules array to leave only the modules to be activated
unset 'qbt_modules[0]'
# Rebuild the qbt_modules array so it is indexed starting from 0 after we have modified and removed items from it previously.
qbt_modules=("${qbt_modules[@]}")
else # Only activate the module passed as a param and leave the rest defaulted to skip
unset 'qbt_modules[0]'
read -ra qbt_modules_skipped <<< "${qbt_modules[@]}"
declare -gA skip_modules
for selected in "${@}"; do
for full_list in "${!qbt_modules_skipped[@]}"; do
[[ "${selected}" == "${qbt_modules_skipped[full_list]}" ]] && qbt_modules_skipped[full_list]="${color_magenta_light}${selected}${color_end}"
done
done
unset selected
qbt_modules=("${@}")
fi
for modules_skip in "${qbt_modules[@]}"; do
skip_modules["${modules_skip}"]="no"
done
unset modules_skip
# Create the directories we need.
mkdir -p "${qbt_install_dir}/logs"
mkdir -p "${PKG_CONFIG_PATH}"
mkdir -p "${qbt_install_dir}/completed"
# Set some python variables we need.
python_major="$(python"${qbt_python_version}" -c "import sys; print(sys.version_info[0])")"
python_minor="$(python"${qbt_python_version}" -c "import sys; print(sys.version_info[1])")"
python_short_version="${python_major}.${python_minor}"
printf '%b\n' "using gcc : : : <cflags>${qbt_optimize/*/${qbt_optimize} }-std=${qbt_cxx_standard} <cxxflags>${qbt_optimize/*/${qbt_optimize} }-std=${qbt_cxx_standard} ;${text_newline}using python : ${python_short_version} : /usr/bin/python${python_short_version} : /usr/include/python${python_short_version} : /usr/lib/python${python_short_version} ;" > "${HOME}/user-config.jam"
# printf the build directory.
printf '\n%b\n' " ${unicode_yellow_circle}${text_bold} Install Prefix${color_end} : ${color_cyan_light}${qbt_install_dir_short}${color_end}"
# Some basic help
printf '\n%b\n' " ${unicode_yellow_circle}${text_bold} Script help${color_end} : ${color_cyan_light}${qbt_working_dir_short}/$(basename -- "$0")${color_end} ${color_blue_light}-h${color_end}"
fi
}
#######################################################################################################################################################