-
Notifications
You must be signed in to change notification settings - Fork 61
/
candi.sh
executable file
·1215 lines (1023 loc) · 39.7 KB
/
candi.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
set -a
# Copyright (C) 2013-2017 by Uwe Koecher, Bruno Turcksin, Timo Heister, #
# the candi authors AND by the DORSAL Authors, cf. AUTHORS file for details. #
# #
# This file is part of CANDI. #
# #
# CANDI is free software: you can redistribute it and/or modify #
# it under the terms of the GNU Lesser General Public License as #
# published by the Free Software Foundation, either #
# version 3 of the License, or (at your option) any later version. #
# #
# CANDI is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with CANDI. If not, see <http://www.gnu.org/licenses/>. #
# REMARK: CANDI (Compile & Install) is a majorly tweaked and extended #
# software based on DORSAL. #
# The origin is DORSAL (also licensed under the LGPL): #
# https://bitbucket.org/fenics-project/dorsal/src #
# master c667be2 2013-11-27 #
################################################################################
# The Unix date command does not work with nanoseconds, so use
# the GNU date instead. This is available in the 'coreutils' package
# from MacPorts.
if builtin command -v gdate > /dev/null; then
DATE_CMD=$(which gdate)
else
DATE_CMD=$(which date)
fi
# Start global timer
TIC_GLOBAL="$(${DATE_CMD} +%s)"
# unset CMAKE_GENERATOR because we assume the default (make) to be used
unset CMAKE_GENERATOR
################################################################################
# Parse command line input parameters
PREFIX=~/dealii-candi
JOBS=1
CMD_PACKAGES=""
USER_INTERACTION=ON
while [ -n "$1" ]; do
param="$1"
case $param in
-h|--help)
echo "candi (Compile & Install)"
echo ""
echo "Usage: $0 [options]"
echo "Options:"
echo " -p <path>, --prefix=<path> set a different prefix path (default $PREFIX)"
echo " -j <N>, -j<N>, --jobs=<N> compile with N processes in parallel (default ${JOBS})"
echo " --platform=<platform> force usage of a particular platform file"
echo " --packages=\"pkg1 pkg2\" install the given list of packages instead of the default set in candi.cfg"
echo " -y, --yes, --assume-yes automatic yes to prompts"
echo ""
echo "The configuration including the choice of packages to install is stored in candi.cfg, see README.md for more information."
exit 0
;;
#####################################
# Prefix path
-p)
shift
PREFIX="${1}"
;;
-p=*|--prefix=*)
PREFIX="${param#*=}"
;;
#####################################
# overwrite package list
--packages=*)
CMD_PACKAGES="${param#*=}"
;;
#####################################
# Number of maximum processes to use
--jobs=*)
JOBS="${param#*=}"
;;
# Make styled processes with or without space
-j)
shift
JOBS="${1}"
;;
-j*)
JOBS="${param#*j}"
;;
#####################################
# Specific platform
-pf=*|--platform=*)
GIVEN_PLATFORM="${param#*=}"
;;
#####################################
# Assume yes to prompts
-y|--yes|--assume-yes)
USER_INTERACTION=OFF
;;
*)
echo "invalid command line option <$param>. See -h for more information."
exit 1
esac
shift
done
# Check the input argument of the install path and (if used) replace the tilde
# character '~' by the users home directory ${HOME}. Afterwards clear the
# PREFIX input variable.
PREFIX_PATH=${PREFIX/#~\//$HOME\/}
unset PREFIX
RE='^[0-9]+$'
if [[ ! "${JOBS}" =~ ${RE} || ${JOBS}<1 ]] ; then
echo "ERROR: invalid number of build processes '${JOBS}'"
exit 1
fi
################################################################################
# Set download tool
# Set given DOWNLOADER as preferred tool
DOWNLOADERS="${DOWNLOADER}"
# Check if the curl download is available
if builtin command -v curl > /dev/null; then
# Set curl as the prefered download tool, if nothing else is specified
DOWNLOADERS="${DOWNLOADERS} curl"
fi
# Check if the wget download is available
if builtin command -v wget > /dev/null; then
# Set wget as the prefered download tool, if nothing else is specified
DOWNLOADERS="${DOWNLOADERS} wget"
fi
if [ -z "${DOWNLOADERS}" ]; then
echo "Please install wget or curl."
exit 1
fi
################################################################################
# Colours for progress and error reporting
BAD="\033[1;31m"
GOOD="\033[1;32m"
WARN="\033[1;35m"
INFO="\033[1;34m"
BOLD="\033[1m"
################################################################################
# Ensure that no PETSc environment variables are set.
unset PETSC_DIR
unset PETSC_ARCH
################################################################################
# Define candi helper functions
prettify_dir() {
# Make a directory name more readable by replacing homedir with "~"
echo ${1/#$HOME\//~\/}
}
cecho() {
# Display messages in a specified colour
COL=$1; shift
echo -e "${COL}$@\033[0m"
}
cls() {
if [ ${USER_INTERACTION} = ON ]; then
# clear screen
COL=$1; shift
echo -e "${COL}$@\033c"
fi
}
default () {
# Export a variable, if it is not already set
VAR="${1%%=*}"
VALUE="${1#*=}"
eval "[[ \$$VAR ]] || export $VAR='$VALUE'"
}
quit_if_fail() {
# Exit with some useful information if something goes wrong
STATUS=$?
if [ ${STATUS} -ne 0 ]; then
cecho ${BAD} 'Failure with exit status:' ${STATUS}
cecho ${BAD} 'Exit message:' $1
exit ${STATUS}
fi
}
################################################################################
#verify_archive():
# return -1: internal error
# return 0: CHECKSUM is matching (archive found & verified)
# return 1: No checksum provided (archive found, but unable to verify)
# return 2: ARCHIVE_FILE not found (archive NOT found)
# return 3: CHECKSUM mismatch (archive file corrupted)
# return 4: Not able to compute checksum (archive found, but unable to verify)
# return 5: Checksum algorithm not found (archive found, but unable to verify)
# This function tries to verify the downloaded archive by determing and
# comparing checksums. For a specific package several checksums might be
# defined. Based on the length of the given checksum the underlying algorithm
# is determined. The first matching checksum verifies the archive.
verify_archive() {
ARCHIVE_FILE=$1
# Make sure the archive was downloaded
if [ ! -e ${ARCHIVE_FILE} ]; then
return 2
fi
# empty file?
if [ ! -s ${ARCHIVE_FILE} ]; then
return 2
fi
# Check CHECKSUM has been specified for the package
if [ -z "${CHECKSUM}" ]; then
cecho ${WARN} "No checksum for ${ARCHIVE_FILE}"
return 1
fi
# Skip verifying archive, if CHECKSUM=skip
if [ "${CHECKSUM}" = "skip" ]; then
cecho ${WARN} "Skipped checksum check for ${ARCHIVE_FILE}"
return 1
fi
cecho ${INFO} "Verifying ${ARCHIVE_FILE}"
for CHECK in ${CHECKSUM}; do
# Verify CHECKSUM using md5/sha1/sha256
if [ ${#CHECK} = 32 ]; then
ALGORITHM="md5"
if builtin command -v md5sum > /dev/null; then
CURRENT=$(md5sum ${ARCHIVE_FILE} | awk '{print $1}')
elif builtin command -v md5 > /dev/null; then
CURRENT="$(md5 -q ${ARCHIVE_FILE})"
else
cecho ${BAD} "Neither md5sum nor md5 were found in the PATH"
return 4
fi
elif [ ${#CHECK} = 40 ]; then
ALGORITHM="sha1"
if builtin command -v sha1sum > /dev/null; then
CURRENT=$(sha1sum ${ARCHIVE_FILE} | awk '{print $1}')
elif builtin command -v shasum > /dev/null; then
CURRENT=$(shasum -a 1 ${ARCHIVE_FILE} | awk '{print $1}')
else
cecho ${BAD} "Neither sha1sum nor shasum were found in the PATH"
return 4
fi
elif [ ${#CHECK} = 64 ]; then
ALGORITHM="sha256"
if builtin command -v sha256sum > /dev/null; then
CURRENT=$(sha256sum ${ARCHIVE_FILE} | awk '{print $1}')
elif builtin command -v shasum > /dev/null; then
CURRENT=$(shasum -a 256 ${ARCHIVE_FILE} | awk '{print $1}')
else
cecho ${BAD} "Neither sha256sum nor shasum were found in the PATH"
return 4
fi
else
cecho ${BAD} "Checksum algorithm could not be determined"
exit 5
fi
test "${CHECK}" = "${CURRENT}"
if [ $? = 0 ]; then
cecho ${GOOD} "${ARCHIVE_FILE}: OK(${ALGORITHM})"
return 0
else
cecho ${BAD} "${ARCHIVE_FILE}: FAILED(${ALGORITHM})"
cecho ${BAD} "${CURRENT} does not match given checksum ${CHECK}"
fi
done
unset ALGORITHM
cecho ${BAD} "${ARCHIVE_FILE}: FAILED"
cecho ${BAD} "Checksum does not match any in ${CHECKSUM}"
return 3
}
download_archive () {
ARCHIVE_FILE=$1
# Prepend MIRROR to SOURCE (to prefer) mirror source download
if [ ! -z "${MIRROR}" ]; then
SOURCE="${MIRROR} ${SOURCE}"
fi
for DOWNLOADER in ${DOWNLOADERS[@]}; do
for source in ${SOURCE}; do
# verify_archive:
# * Skip loop if the ARCHIVE_FILE is already downloaded
# * Remove corrupted ARCHIVE_FILE
verify_archive ${ARCHIVE_FILE}
archive_state=$?
if [ ${archive_state} = 0 ]; then
cecho ${INFO} "${ARCHIVE_FILE} already downloaded and verified."
return 0;
elif [ ${archive_state} = 1 ] || [ ${archive_state} = 4 ]; then
cecho ${WARN} "${ARCHIVE_FILE} already downloaded, but unable to be verified."
return 0;
elif [ ${archive_state} = 3 ]; then
cecho ${BAD} "${ARCHIVE_FILE} in your download folder is corrupted"
# Remove the file and check if that was successful
rm -f ${ARCHIVE_FILE}
if [ $? = 0 ]; then
cecho ${INFO} "Corrupted ${ARCHIVE_FILE} has been removed!"
else
cecho ${BAD} "Corrupted ${ARCHIVE_FILE} could not be removed."
cecho ${INFO} "Please remove the file ${DOWNLOAD_PATH}/${ARCHIVE_FILE} on your own!"
exit 1;
fi
fi
unset archive_state
# Set up complete url
url=${source}${ARCHIVE_FILE}
cecho ${INFO} "Trying to download ${url}"
# Download.
# If curl or wget is failing, continue this loop for trying an other mirror.
if [ ${DOWNLOADER} = "curl" ]; then
curl -f -L -k -O ${url} || continue
elif [ ${DOWNLOADER} = "wget" ]; then
wget --no-check-certificate ${url} -O ${ARCHIVE_FILE} || continue
else
cecho ${BAD} "candi: Unknown downloader: ${DOWNLOADER}"
exit 1
fi
unset url
# Verify the download
verify_archive ${ARCHIVE_FILE}
archive_state=$?
if [ ${archive_state} = 0 ] || [ ${archive_state} = 1 ] || [ ${archive_state} = 4 ]; then
# If the download was successful, and the CHECKSUM is matching, skipped, or not possible
return 0;
fi
unset archive_state
done
done
# Unfortunately it seems that (all) download tryouts finally failed for some reason:
verify_archive ${ARCHIVE_FILE}
quit_if_fail "Error verifying checksum for ${ARCHIVE_FILE}\nMake sure that you are connected to the internet."
}
package_fetch () {
cecho ${GOOD} "Fetching ${PACKAGE} ${VERSION}"
# Fetch the package appropriately from its source
if [ ${PACKING} = ".tar.bz2" ] || [ ${PACKING} = ".tar.gz" ] || [ ${PACKING} = ".tbz2" ] || [ ${PACKING} = ".tgz" ] || [ ${PACKING} = ".tar.xz" ] || [ ${PACKING} = ".zip" ]; then
cd ${DOWNLOAD_PATH}
download_archive ${NAME}${PACKING}
quit_if_fail "candi: download_archive ${NAME}${PACKING} failed"
elif [ ${PACKING} = "git" ]; then
# Go into the unpack dir
cd ${UNPACK_PATH}
# Clone the git repository if not existing locally
if [ ! -d ${EXTRACTSTO} ]; then
git clone ${SOURCE}${NAME} ${EXTRACTSTO}
quit_if_fail "candi: git clone ${SOURCE}${NAME} ${EXTRACTSTO} failed"
fi
# Checkout the desired version
cd ${EXTRACTSTO}
git checkout ${VERSION} --force
quit_if_fail "candi: git checkout ${VERSION} --force failed"
# Switch to the tmp dir
cd ..
elif [ ${PACKING} = "hg" ]; then
cd ${UNPACK_PATH}
# Suitably clone or update hg repositories
if [ ! -d ${NAME} ]; then
hg clone ${SOURCE}${NAME}
else
cd ${NAME}
hg pull --update
cd ..
fi
elif [ ${PACKING} = "svn" ]; then
cd ${UNPACK_PATH}
# Suitably check out or update svn repositories
if [ ! -d ${NAME} ]; then
svn co ${SOURCE} ${NAME}
else
cd ${NAME}
svn up
cd ..
fi
elif [ ${PACKING} = "bzr" ]; then
cd ${UNPACK_PATH}
# Suitably branch or update bzr repositories
if [ ! -d ${NAME} ]; then
bzr branch ${SOURCE}${NAME}
else
cd ${NAME}
bzr pull
cd ..
fi
fi
# Quit with a useful message if something goes wrong
quit_if_fail "Error fetching ${PACKAGE} ${VERSION} using ${PACKING}."
}
package_unpack() {
# First make sure we're in the right directory before unpacking
cd ${UNPACK_PATH}
FILE_TO_UNPACK=${DOWNLOAD_PATH}/${NAME}${PACKING}
# Only need to unpack archives
if [ ${PACKING} = ".tar.bz2" ] || [ ${PACKING} = ".tar.gz" ] || [ ${PACKING} = ".tbz2" ] || [ ${PACKING} = ".tgz" ] || [ ${PACKING} = ".tar.xz" ] || [ ${PACKING} = ".zip" ]; then
cecho ${GOOD} "Unpacking ${NAME}${PACKING}"
# Make sure the archive was downloaded
if [ ! -e ${FILE_TO_UNPACK} ]; then
cecho ${BAD} "${FILE_TO_UNPACK} does not exist. Please download first."
exit 1
fi
# remove old unpack (this might be corrupted)
if [ -d "${EXTRACTSTO}" ]; then
rm -rf ${EXTRACTSTO}
quit_if_fail "Removing of ${EXTRACTSTO} failed."
fi
# Unpack the archive only if it isn't already
# Unpack the archive in accordance with its packing
if [ ${PACKING} = ".tar.bz2" ] || [ ${PACKING} = ".tbz2" ]; then
tar xjf ${FILE_TO_UNPACK}
elif [ ${PACKING} = ".tar.gz" ] || [ ${PACKING} = ".tgz" ]; then
tar xzf ${FILE_TO_UNPACK}
elif [ ${PACKING} = ".tar.xz" ]; then
tar xJf ${FILE_TO_UNPACK}
elif [ ${PACKING} = ".zip" ]; then
unzip ${FILE_TO_UNPACK}
fi
fi
# Apply patches with git cherry-pick of commits given by ${CHERRYPICKCOMMITS}
if [ ${PACKING} = "git" ] && [ ! -z "${CHERRYPICKCOMMITS}" ]; then
cecho ${INFO} "candi: git cherry-pick -X theirs ${CHERRYPICKCOMMITS}"
cd ${UNPACK_PATH}/${EXTRACTSTO}
git cherry-pick -X theirs ${CHERRYPICKCOMMITS}
quit_if_fail "candi: git cherry-pick -X theirs ${CHERRYPICKCOMMITS} failed"
fi
# Apply patches
cd ${UNPACK_PATH}/${EXTRACTSTO}
package_specific_patch
# Quit with a useful message if something goes wrong
quit_if_fail "Error unpacking ${FILE_TO_UNPACK}."
unset FILE_TO_UNPACK
}
package_build() {
# Get things ready for the compilation process
cecho ${GOOD} "Building ${PACKAGE} ${VERSION}"
if [ ! -d "${UNPACK_PATH}/${EXTRACTSTO}" ]; then
cecho ${BAD} "${EXTRACTSTO} does not exist -- please unpack first."
exit 1
fi
# Set the BUILDDIR if nothing else was specified
default BUILDDIR=${BUILD_PATH}/${NAME}
# Clean the build directory if specified
if [ -d ${BUILDDIR} ] && [ ${CLEAN_BUILD} = ON ]; then
rm -rf ${BUILDDIR}
fi
# Create build directory if it does not exist
if [ ! -d ${BUILDDIR} ]; then
mkdir -p ${BUILDDIR}
fi
# Move to the build directory
cd ${BUILDDIR}
# Carry out any package-specific setup
package_specific_setup
quit_if_fail "There was a problem in build setup for ${PACKAGE} ${VERSION}."
cd ${BUILDDIR}
# Use the appropriate build system to compile and install the
# package
for cmd_file in candi_configure candi_build; do
echo "#!/usr/bin/env bash" >${cmd_file}
chmod a+x ${cmd_file}
# Write variables to files so that they can be run stand-alone
declare -x| grep -v "!::"| grep -v "ProgramFiles(x86)" >>${cmd_file}
# From this point in candi_*, errors are fatal
echo "set -e" >>${cmd_file}
done
if [ ${BUILDCHAIN} = "autotools" ]; then
if [ -f ${UNPACK_PATH}/${EXTRACTSTO}/configure ]; then
echo ${UNPACK_PATH}/${EXTRACTSTO}/configure ${CONFOPTS} --prefix=${INSTALL_PATH} >>candi_configure
fi
for target in "${TARGETS[@]}"; do
echo make ${MAKEOPTS} -j ${JOBS} $target >>candi_build
done
elif [ ${BUILDCHAIN} = "cmake" ]; then
rm -f ${BUILDDIR}/CMakeCache.txt
rm -rf ${BUILDDIR}/CMakeFiles
echo cmake ${CONFOPTS} -DCMAKE_INSTALL_PREFIX=${INSTALL_PATH} ${UNPACK_PATH}/${EXTRACTSTO} >>candi_configure
for target in "${TARGETS[@]}"; do
echo make ${MAKEOPTS} -j ${JOBS} $target >>candi_build
done
elif [ ${BUILDCHAIN} = "python" ]; then
echo cp -rf ${UNPACK_PATH}/${EXTRACTSTO}/* . >>candi_configure
echo ${PYTHON_INTERPRETER} setup.py install --prefix=${INSTALL_PATH} >>candi_build
elif [ ${BUILDCHAIN} = "scons" ]; then
echo cp -rf ${UNPACK_PATH}/${EXTRACTSTO}/* . >>candi_configure
for target in "${TARGETS[@]}"; do
echo scons -j ${JOBS} ${CONFOPTS} prefix=${INSTALL_PATH} $target >>candi_build
done
elif [ ${BUILDCHAIN} = "custom" ]; then
# Write the function definition to file
declare -f package_specific_build >>candi_build
echo package_specific_build >>candi_build
elif [ ${BUILDCHAIN} = "ignore" ]; then
cecho ${INFO} "Info: ${PACKAGE} has forced BUILDCHAIN=${BUILDCHAIN}."
else
cecho ${BAD} "candi: internal error: BUILDCHAIN=${BUILDCHAIN} for ${PACKAGE} unknown."
exit 1
fi
echo "touch candi_successful_build" >> candi_build
# Run the generated build scripts
if [ ${BASH_VERSINFO} -ge 3 ]; then
set -o pipefail
./candi_configure 2>&1 | tee candi_configure.log
else
./candi_configure
fi
quit_if_fail "There was a problem configuring ${PACKAGE} ${VERSION}."
if [ ${BASH_VERSINFO} -ge 3 ]; then
set -o pipefail
./candi_build 2>&1 | tee candi_build.log
else
./candi_build
fi
quit_if_fail "There was a problem building ${PACKAGE} ${VERSION}."
# Carry out any package-specific post-build instructions
package_specific_install
quit_if_fail "There was a problem in post-build instructions for ${PACKAGE} ${VERSION}."
}
package_register() {
# Set any package-specific environment variables
package_specific_register
quit_if_fail "There was a problem setting environment variables for ${PACKAGE} ${VERSION}."
}
package_conf() {
# Write any package-specific environment variables to a config file,
# i.e. e.g. a modulefile or source-able *.conf file
package_specific_conf
quit_if_fail "There was a problem creating the configfiles for ${PACKAGE} ${VERSION}."
}
guess_platform() {
# Try to guess the name of the platform we're running on
if [ -f /usr/bin/cygwin1.dll ]; then
echo cygwin
elif [ -x /usr/bin/sw_vers ]; then
local MACOS_PRODUCT_NAME=$(sw_vers -productName)
local MACOS_VERSION=$(sw_vers -productVersion)
if [ "${MACOS_PRODUCT_NAME}" == "macOS" ]; then
echo macos
else
case ${MACOS_VERSION} in
10.11*) echo macos_elcapitan;;
10.12*) echo macos_sierra;;
10.13*) echo macos_highsierra;;
10.14*) echo macos_mojave;;
10.15*) echo macos_catalina;;
11.4*) echo macos_bigsur;;
11.5*) echo macos_bigsur;;
esac
fi
elif [ ! -z "${CRAYOS_VERSION}" ]; then
echo cray
elif [ -f /etc/os-release ]; then
local OS_ID=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
local OS_VERSION_ID=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
local OS_MAJOR_VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"' | grep -oE '[0-9]+' | head -n 1)
local OS_NAME=$(grep -oP '(?<=^NAME=).+' /etc/os-release | tr -d '"')
local OS_PRETTY_NAME=$(grep -oP '(?<=^PRETTY_NAME=).+' /etc/os-release | tr -d '"')
if [ "${OS_ID}" == "fedora" ]; then
echo fedora
elif [ "${OS_ID}" == "centos" ]; then
echo centos${OS_VERSION_ID}
elif [ "${OS_ID}" == "almalinux" ]; then
echo almalinux${OS_MAJOR_VERSION}
elif [ "${OS_ID}" == "rhel" ]; then
echo rhel${OS_MAJOR_VERSION}
elif [ "$OS_ID" == "debian" ]; then
echo debian
elif [ "$OS_ID" == "ubuntu" ]; then
echo ubuntu
elif [ "${OS_NAME}" == "openSUSE Leap" ]; then
echo opensuse15
elif [ "${OS_PRETTY_NAME}" == "Arch Linux" ]; then
echo arch
elif [ "${OS_PRETTY_NAME}" == "Manjaro Linux" ]; then
echo arch
fi
fi
}
guess_ostype() {
# Try to guess the operating system type (ostype)
if [ -f /usr/bin/cygwin1.dll ]; then
echo cygwin
elif [ -x /usr/bin/sw_vers ]; then
echo macos
elif [ -x /etc/os-release ]; then
echo linux
fi
}
guess_architecture() {
# Try to guess the architecture of the platform we are running on
ARCH=unknown
if [ -x /usr/bin/uname -o -x /bin/uname ]
then
ARCH=`uname -m`
fi
}
################################################################################
### candi script
################################################################################
cls
echo "*******************************************************************************"
cecho ${GOOD} "This is candi (compile and install)"
echo
# Keep the current work directory of candi.sh
# WARNING: You should NEVER override this variable!
export ORIG_DIR=`pwd`
################################################################################
# Read configuration variables from candi.cfg
source candi.cfg
# For changes specific to your local setup or for debugging, use local.cfg
if [ -f local.cfg ]; then
source local.cfg
fi
# If any variables are missing, set them to defaults
default PROJECT=deal.II-toolchain
default DOWNLOAD_PATH=${PREFIX_PATH}/tmp/src
default UNPACK_PATH=${PREFIX_PATH}/tmp/unpack
default BUILD_PATH=${PREFIX_PATH}/tmp/build
default INSTALL_PATH=${PREFIX_PATH}
default CONFIGURATION_PATH=${INSTALL_PATH}/configuration
default CLEAN_BUILD=OFF
default DEVELOPER_MODE=OFF
default PACKAGES_OFF=""
if [ -n "$CMD_PACKAGES" ]; then
PACKAGES=$CMD_PACKAGES
fi
################################################################################
# Check if project was specified correctly
if [ -d ${PROJECT} ]; then
if [ -d ${PROJECT}/platforms -a -d ${PROJECT}/packages ]; then
cecho ${INFO} "Project: ${PROJECT}: Found configuration."
else
cecho ${BAD} "Please contact the authors, if you have not changed candi!"
cecho ${INFO} "candi: Internal error:"
cecho ${INFO} "No subdirectories 'platforms' and 'packages' in ${PROJECT}."
exit 1
fi
else
cecho ${BAD} "Please contact the authors, if you have not changed candi!"
cecho ${INFO} "candi: Internal error:"
cecho ${INFO} "Error: No project configuration directory found for project ${PROJECT}."
echo "Please check if you have specified right project name in candi.cfg"
echo "Please check if you have directory called ${PROJECT}"
echo "with subdirectories ${PROJECT}/platforms and ${PROJECT}/packages"
exit 1
fi
################################################################################
# Operating system (PLATFORM) check
if [ -z "${GIVEN_PLATFORM}" ]; then
# No platform is forced to use, try to find a platform file.
PLATFORM_SUPPORTED=${PROJECT}/platforms/supported/`guess_platform`.platform
PLATFORM_CONTRIBUTED=${PROJECT}/platforms/contributed/`guess_platform`.platform
PLATFORM_DEPRECATED=${PROJECT}/platforms/deprecated/`guess_platform`.platform
if [ -e ${PLATFORM_SUPPORTED} ]; then
PLATFORM=${PLATFORM_SUPPORTED}
cecho ${INFO} "using ./${PLATFORM}."
elif [ -e ${PLATFORM_CONTRIBUTED} ]; then
PLATFORM=${PLATFORM_CONTRIBUTED}
cecho ${INFO} "using ./${PLATFORM}."
cecho ${WARN} "Warning: Platform is not officially supported but may still work!"
elif [ -e ${PLATFORM_DEPRECATED} ]; then
PLATFORM=${PLATFORM_DEPRECATED}
cecho ${INFO} "using ./${PLATFORM}."
cecho ${WARN} "Warning: Platform is deprecated and will be removed shortly but may still work!"
else
cecho ${BAD} "Error: Your operating system could not be automatically recognised."
echo "You may force a (similar) platform directly by:"
echo "./candi.sh --platform=${PROJECT}/platforms/ {supported|contributed|deprecated} / <FORCED>.platform"
exit 1
fi
unset PLATFORM_SUPPORTED
unset PLATFORM_CONTRIBUTED
unset PLATFORM_DEPRECATED
else
# Forced platform by the user, check if the given platform file is available.
if [ -e ${GIVEN_PLATFORM} ]; then
PLATFORM=${GIVEN_PLATFORM}
cecho ${BAD} "using (user-forced) ./${PLATFORM}."
unset GIVEN_PLATFORM
else
cecho ${BAD} "Error: Your forced platform file ${GIVEN_PLATFORM} does not exists"
exit 1
fi
fi
echo
# Guess the operating system type -> PLATFORM_OSTYPE
PLATFORM_OSTYPE=`guess_ostype`
if [ -z "${PLATFORM_OSTYPE}" ]; then
cecho ${WARN} "WARNING: could not determine your Operating System Type (assuming linux)"
PLATFORM_OSTYPE=linux
fi
cecho ${INFO} "Operating System Type detected as: ${PLATFORM_OSTYPE}"
if [ -z "${PLATFORM_OSTYPE}" ]; then
# check if PLATFORM_OSTYPE is set and not empty failed
cecho ${BAD} "Error: (internal) could not set PLATFORM_OSTYPE"
exit 1
fi
# Guess dynamic shared library file extension -> LDSUFFIX
if [ ${PLATFORM_OSTYPE} == "linux" ]; then
LDSUFFIX=so
elif [ ${PLATFORM_OSTYPE} == "macos" ]; then
LDSUFFIX=dylib
elif [ ${PLATFORM_OSTYPE} == "cygwin" ]; then
LDSUFFIX=dll
fi
cecho ${INFO} "Dynamic shared library file extension detected as: *.${LDSUFFIX}"
if [ -z "${LDSUFFIX}" ]; then
# check if PLATFORM_OSTYPE is set and not empty failed
cecho ${BAD} "Error: (internal) could not set LDSUFFIX"
exit 1
fi
# Source PLATFORM variables if set up correctly
if [ -z ${PLATFORM} ]; then
cecho ${BAD} "Please contact the authors, if you have not changed candi!"
cecho ${INFO} "candi: Internal error, no PLATFORM variable available."
exit 1
else
# Load PLATFORM variables
source ${PLATFORM}
fi
echo
# Output PLATFORM details
echo "-------------------------------------------------------------------------------"
cecho ${WARN} "Please read carefully your operating system notes below!"
echo
# Show the initial comments in the platform file until the pattern '##' appears.
# Further, removes first field '#' before the output.
awk '/^##/ {exit} {$1=""; print}' <${PLATFORM}
echo
# If interaction is enabled, let the user confirm, that the platform is set up
# correctly
if [ ${USER_INTERACTION} = ON ]; then
echo "--------------------------------------------------------------------------------"
cecho ${GOOD} "Please make sure you've read the instructions above and your system"
cecho ${GOOD} "is ready for installing ${PROJECT}."
cecho ${BAD} "If not, please abort the installer by pressing <CTRL> + <C> !"
cecho ${INFO} "Then copy and paste these instructions into this terminal."
echo
cecho ${GOOD} "Once ready, hit enter to continue!"
read
fi
################################################################################
# Output configuration details
cls
echo "*******************************************************************************"
cecho ${GOOD} "candi tries now to download, configure, build and install:"
echo
cecho ${GOOD} "Project: ${PROJECT}"
cecho ${GOOD} "Platform: ${PLATFORM}"
echo
echo "-------------------------------------------------------------------------------"
if [ ${DEVELOPER_MODE} = "OFF" ]; then
cecho ${INFO} "Downloading files to: $(prettify_dir ${DOWNLOAD_PATH})"
cecho ${INFO} "Unpacking files to: $(prettify_dir ${UNPACK_PATH})"
elif [ ${DEVELOPER_MODE} = "ON" ]; then
cecho ${BAD} "Warning: You are using the DEVELOPER_MODE"
cecho ${INFO} "Note: You need to have run candi with the same settings without this mode before!"
cecho ${BAD} "For packages not in the build mode={load|skip|once}, candi now use"
cecho ${BAD} "source files from: $(prettify_dir ${UNPACK_PATH})"
echo
else
cecho ${BAD} "candi: bad variable: DEVELOPER_MODE={ON|OFF}; (your specified option is = ${DEVELOPER_MODE})"
exit 1
fi
cecho ${INFO} "Building packages in: $(prettify_dir ${BUILD_PATH})"
cecho ${GOOD} "Installing packages in: $(prettify_dir ${INSTALL_PATH})"
cecho ${GOOD} "Package configuration in: $(prettify_dir ${CONFIGURATION_PATH})"
echo
echo "-------------------------------------------------------------------------------"
cecho ${INFO} "Number of (at most) build processes to use: JOBS=${JOBS}"
echo
echo "-------------------------------------------------------------------------------"
cecho ${INFO} "Packages:"
for PACKAGE in ${PACKAGES[@]}; do
echo ${PACKAGE}
done
echo
# if the program 'module' is available, output the currently loaded modulefiles
if builtin command -v module > /dev/null; then
echo "-------------------------------------------------------------------------------"
cecho ${GOOD} Currently loaded modulefiles:
cecho ${INFO} "$(module list)"
echo
fi
############################################################################
# Compiler variables check
# Firstly test, if compiler variables are set, and if not try to set the
# default mpi-compiler suite finally test, if compiler variables are useful.
echo "--------------------------------------------------------------------------------"
cecho ${INFO} "Compiler Variables:"
echo
# CC test
if [ ! -n "${CC}" ]; then
if builtin command -v mpicc > /dev/null; then
cecho ${WARN} "CC variable not set, but default mpicc found."
export CC=mpicc
fi
fi
if [ -n "${CC}" ]; then
cecho ${INFO} "CC = $(which ${CC})"
else
cecho ${BAD} "CC variable not set. Please set it with \$export CC = <(MPI) C compiler>"
fi
# CXX test
if [ ! -n "${CXX}" ]; then
if builtin command -v mpicxx > /dev/null; then
cecho ${WARN} "CXX variable not set, but default mpicxx found."
export CXX=mpicxx
fi
fi
if [ -n "${CXX}" ]; then
cecho ${INFO} "CXX = $(which ${CXX})"
else
cecho ${BAD} "CXX variable not set. Please set it with \$export CXX = <(MPI) C++ compiler>"
fi
# FC test
if [ ! -n "${FC}" ]; then
if builtin command -v mpif90 > /dev/null; then
cecho ${WARN} "FC variable not set, but default mpif90 found."
export FC=mpif90
fi
fi
if [ -n "${FC}" ]; then
cecho ${INFO} "FC = $(which ${FC})"
else
cecho ${BAD} "FC variable not set. Please set it with \$export FC = <(MPI) F90 compiler>"
fi
# FF test
if [ ! -n "${FF}" ]; then
if builtin command -v mpif77 > /dev/null; then
cecho ${WARN} "FF variable not set, but default mpif77 found."
export FF=mpif77
fi
fi
if [ -n "${FF}" ]; then
cecho ${INFO} "FF = $(which ${FF})"
else
cecho ${BAD} "FF variable not set. Please set it with \$export FF = <(MPI) F77 compiler>"
fi
echo
# Final test for compiler variables
if [ -z "${CC}" ] || [ -z "${CXX}" ] || [ -z "${FC}" ] || [ -z "${FF}" ]; then
cecho ${WARN} "One or multiple compiler variables (CC,CXX,FC,FF) are not set."
cecho ${INFO} "Please read your platform information above carefully, how you get those"
cecho ${INFO} "compilers installed and set up! Usually the values should be:"
cecho ${INFO} "CC=mpicc, CXX=mpicxx, FC=mpif90, FF=mpif77"
cecho ${WARN} "It is strongly recommended to set them to guarantee the same compilers for all"
cecho ${WARN} "dependencies."
echo
fi
################################################################################
# If interaction is enabled, force the user to accept the current output
if [ ${USER_INTERACTION} = ON ]; then
echo "--------------------------------------------------------------------------------"
cecho ${GOOD} "Once ready, hit enter to continue!"