forked from project-everest/everest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
everest
executable file
·1683 lines (1489 loc) · 51.5 KB
/
everest
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
# Sorry, everyone
if (( ${BASH_VERSION%%.*} < 4 )); then
echo "This script requires Bash >= 4. On OSX, try: brew install bash"
exit 1
fi
# Any error is fatal.
set -e
set -o pipefail
# set -x # uncomment for debugging.
# set -u
# Known URLs, directories and versions
OPAM_URL=https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam64.tar.xz
MINIMAL_OCAML_VERSION=4.08.0
OPAM_VERSION=4.12.0+mingw64c
# Provide for a Python, necessary for scons
# (all other occurrences of python can use whatever python 2 is in the PATH, be it Windows or Cygwin)
# NOTE: if you change SCONS_PYTHON_MAJOR and/or SCONS_PYTHON_MINOR, then please also update scons-python-version-test.py
SCONS_PYTHON_MAJOR=3
SCONS_PYTHON_MINOR=6
SCONS_PYTHON_MAJOR_MINOR=$SCONS_PYTHON_MAJOR.$SCONS_PYTHON_MINOR
SCONS_PYTHON_REVISION=6
SCONS_PYTHON_VER=$SCONS_PYTHON_MAJOR_MINOR.$SCONS_PYTHON_REVISION
# NOTE: if you change SCONS_VER, then please also update scons-python-version-test.py
SCONS_VER=3.0.1
SCONS_INSTALL_DIR=scons-$SCONS_VER
SCONS_INSTALL_FILE=$SCONS_INSTALL_DIR.tar.gz
SCONS_INSTALL_POINT=https://downloads.sourceforge.net/project/scons/scons/$SCONS_VER/$SCONS_INSTALL_FILE
SED=$(which gsed >/dev/null 2>&1 && echo gsed || echo sed)
MAKE=$(which gmake >/dev/null 2>&1 && echo gmake || echo make)
# OPAM_AUTO_SETUP defines the opam command-line option to
# automatically setup environment variables into
# $EVEREST_ENV_DEST_FILE . By default, it is left empty, but it is set
# to --auto-setup if everest is run with --yes, i.e. in
# non-interactive mode
OPAM_AUTO_SETUP=
ADVANCE_YES=false
IS_ARCHIVE=false
VALE_ARCHIVE=true
# No-interaction when this script is used for CI purposes
INTERACTIVE=true
make_non_interactive () {
INTERACTIVE=false
export GIT_SSH_COMMAND="ssh -oBatchMode=yes"
export GIT_TERMINAL_PROMPT=0
export OPAMYES=1
export NOSHORTLOG=1
export ADVANCE_YES=true
OPAM_AUTO_SETUP=--auto-setup
}
# The parallel option, either empty (by default), or -j n,
# as specified on the command line.
# WARNING: in the latter case, it MUST be interpreted as two words, so
# NEVER quote it as "$parallel_opt"
# Use $parallel_opt instead
unset parallel_opt
# The -k option (to instruct make to keep going upon a failure),
# disabled by default
unset keep_going_opt
# A string made of both options above, for convenience
unset make_opts
set_make_opts () {
make_opts="$parallel_opt $keep_going_opt"
}
# The file where to store customized environment variables
if [[ $EVEREST_ENV_DEST_FILE == "" ]] ; then
# For people who have installed and initialized opam prior to
# running ./everest check, opam will modify .profile instead of
# .bash_profile, if the latter does not exist. So we need to
# account for that case.
if [[ -f "$HOME/.bash_profile" ]] ; then
EVEREST_ENV_DEST_FILE="$HOME/.bash_profile"
else
EVEREST_ENV_DEST_FILE="$HOME/.profile"
fi
fi
# The whole script makes the assumption that we're in the everest directory;
# this is a conservative method that ensures we switch to this directory first
# thing. Basically, this supports:
# - calling "everest" (in the PATH)
# - calling "./everest" (same directory)
# - calling "/path/to/everest"
# - calling "../path/to/everest"
# This bails for corner cases, e.g. "source everest" or "wget http://.../everest | bash"
cd_to_everest () {
echo -n "# Switching to the everest directory"
if [[ ${0##*/} != "everest" ]]; then
echo -e "\nThis script must be called via ./everest"
exit 1
fi
if [[ $0 != ${0#*/} ]]; then
# Relative or absolute path (contains /)
cd $(dirname $0)
else
# Called via the path
cd $(dirname $(which $0))
fi
echo " ... now in $(pwd)"
echo
}
# Save the initial working directory, to switch to when $0 pull calls
# the new version of $0
initial_pwd="$(pwd)"
cd_to_everest
check_no_archive () {
if $IS_ARCHIVE; then
red "This is an archived Everest repo, and the command you attempted to run \
is not supported."
red "To proceed anyway *at your own risk*, set the IS_ARCHIVE variable to \
false within this script and re-run."
exit 1
fi
}
# "Modularity": include other files (requires us to be in the right directory)
source lib.sh
source repositories.sh
source hashes.sh
GETOPT=getopt
if is_osx; then
export PATH=$(brew --prefix gnu-getopt)/bin:$PATH
echo $PATH
fi
# -allow a command to fail with !’s side effect on errexit
# -use return value from ${PIPESTATUS[0]}, because ! hosed $?
! $GETOPT --test > /dev/null
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
echo "you have an antiquated getopt; on Mac OS X, run \"brew install gnu-getopt\" and make sure it comes first in the PATH"
exit 1
fi
# Windows only: Visual Studio's command line to set up environment (VS_ENV_CMD)
if is_windows ; then
# Starting from Visual Studio 2017, version 15.2 or later,
# we can determine the location of a VS install
# using vswhere.exe, see:
# https://docs.microsoft.com/en-us/visualstudio/extensibility/locating-visual-studio
if
VSWHERE_WINDOWS="$(cmd.exe /C 'echo %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe' | sed 's!\r!!g')" &&
VSWHERE=$(cygpath -u "$VSWHERE_WINDOWS") &&
VS_HOME=$("$VSWHERE" -requires Microsoft.VisualStudio.Component.FSharp -format value -property InstallationPath | head -1 | sed 's!\r!!g') &&
[[ -n "$VS_HOME" ]]
then
echo ... found Visual Studio 2017 or later at $VS_HOME
# Visual Studio 2017 (15.2) or later
# vcvarsall.bat has been superseded by vsdevcmd.bat, see:
# https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/how-to-set-environment-variables-for-the-visual-studio-command-line
VSDEVCMD_PATH=$(cygpath -u "$VS_HOME")/Common7/Tools
VSDEVCMD=$(cygpath -w "$VSDEVCMD_PATH/VsDevCmd.bat")
# Here we assume that BOTH the target platform
# and the host platform are amd64.
VS_ENV_CMD='"'"$VSDEVCMD"'" -arch=amd64 -host_arch=amd64'
else
# Older versions are based on vcvarsall.bat
if [[ -v VS140COMNTOOLS ]]; then
# Visual Studio 2015 (14.x)
VS_TOOLS_PATH="$VS140COMNTOOLS"
elif [[ -v VS120COMNTOOLS ]]; then
# Visual Studio 2012 (12.x)
VS_TOOLS_PATH="$VS120COMNTOOLS"
elif [[ -v VS110COMNTOOLS ]]; then
# Visual Studio 2010 (10.x)
VS_TOOLS_PATH="$VS110COMNTOOLS"
else
# Not found
echo Could not find Visual Studio
exit 1
fi
VCVARSALL_PATH="$VS_TOOLS_PATH"/../../VC
VCVARSALL=$(cygpath -d "$VCVARSALL_PATH/vcvarsall.bat")
# Here we assume that BOTH the target platform
# and the host platform are amd64.
VS_ENV_CMD="$VCVARSALL amd64"
fi
fi
# May be overridden to include a single project
ALL_PROJECTS="${!repositories[@]}"
# ------------------------------------------------------------------------------
# A series of helpers
# ------------------------------------------------------------------------------
write_to_env_dest_file () {
str="$1"
# NOTE: "$str" contains line breaks, since it actually contains
# several commands, with each command on its own line.
# These line breaks must be preserved.
eval "$str"
echo "$str" >> "$EVEREST_ENV_DEST_FILE"
magenta "Remember to run source \"$EVEREST_ENV_DEST_FILE\" in your terminal afterwards!"
}
# Append $1 to the (Cygwin) path
windows_append_path () {
path=$(cygpath -m -d "$1")
path=$(cygpath "$path")
str="
# This line automatically added by $0
export PATH=\"$path\":\$PATH"
write_to_env_dest_file "$str"
export PATH="$path":"$PATH"
}
# Windows requires several tools that can be installed via Visual Studio, but
# these usually aren't in the PATH. Check in the usual locations, then offer to
# customize "$EVEREST_ENV_DEST_FILE"
# $1: name of command to check for
# $2: candidate directory where it may reside
# NOTE: this function is also used to locate python and scons
windows_check_or_modify_env_dest_file () {
if ! command -v $1 >/dev/null 2>&1; then
red "ERROR: $1 not found in PATH"
if [ -f "$2"/$1 ]; then
magenta "$1 found in $2; add to PATH via $EVEREST_ENV_DEST_FILE ? [Yn]"
if prompt_yes true false; then
windows_append_path "$2"
fi
else
red "$1 not found in $2, bailing"
echo Hint: it looks like some VS2015 components are missing. We need \
VS2015, including the C++ components. You can run the VS2015 installer \
and choose a custom setup, to ensure you have both F# and the C++ \
components. Download it from: \
https://go.microsoft.com/fwlink/?LinkId=532606&clcid=0x409
exit 1
fi
fi
echo "... found $1"
}
write_z3_env_dest_file () {
str="
# This line automatically added by $0
export PATH=$(pwd)/$1/bin:\$PATH"
write_to_env_dest_file "$str"
}
write_cygwin_env_dest_file () {
str="
# These lines automatically added by $0
export PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin:\$PATH
export CYGWIN='winsymlinks:native'"
write_to_env_dest_file "$str"
}
write_cxx_env_dest_file () {
str="
# This line automatically added by $0
export CXX=x86_64-w64-mingw32-g++.exe"
write_to_env_dest_file "$str"
}
write_everest_env_dest_file () {
if is_windows; then
str="
# These lines automatically added by $0
export EVEREST_SCONS_CACHE_DIR=$(cygpath -m \"$TEMP\"/everest)"
else
str="
# These lines automatically added by $0
export EVEREST_SCONS_CACHE_DIR=/tmp/everest"
fi
write_to_env_dest_file "$str"
}
cygsetup="setup-x86_64.exe"
cygsetup_args="--no-desktop --no-shortcuts --no-startmenu --wait --quiet-mode"
# Find Cygwin's setup utility, or download it from the internet.
# Success: writes the path to Cygwin's setup in $cygsetup
# Failure: aborts.
find_cygsetup () {
found=false
for s in "$USERPROFILE/Desktop/setup-x86_64.exe" "$USERPROFILE/Downloads/setup-x86_64.exe" "./setup-x86_64.exe" "c:/cygwin64/setup-x86_64.exe"; do
if [ -x "$s" ]; then
echo "Found $cygsetup"
found=true
cygsetup="$s"
fi
done
# Try to find chocolatey version
if ! $found; then
for s in "$USERPROFILE/Desktop/cygwinsetup.exe" "$USERPROFILE/Downloads/cygwinsetup.exe" "./cygwinsetup.exe" "c:/cygwin64/cygwinsetup.exe"; do
if [ -x "$s" ]; then
echo "Found $cygsetup"
found=true
cygsetup="$s"
fi
done
fi
if ! $found; then
magenta "Cygwin setup not found, downloading it"
if ! command -v wget >/dev/null 2>&1; then
red "ERROR: please either place cygwin's setup-x86_64.exe in your Downloads or Desktop folder, or install wget via cygwin's setup"
fi
wget "https://cygwin.com/setup-x86_64.exe"
chmod a+x setup-x86_64.exe
cygsetup=./setup-x86_64.exe
fi
}
install_all_opam_packages () {
packages=$(cat opam-packages | cut -d ' ' -f 2 | tr '\n' ' ')
opam update
if is_windows; then
opam install depext-cygwinports
fi
opam depext $packages
opam install -j 4 $packages
}
try_git_clone () {
if ! git clone --recursive $1 $3; then
magenta "Proceed with https? [Yn]"
prompt_yes true "exit 1"
git clone --recursive $2 $3
fi
}
parse_z3_version () {
if ! which z3 >/dev/null 2>&1; then
echo "no z3 in path!"
else
local z3_version=$(z3 --version)
if echo $z3_version | grep hashcode >/dev/null 2>&1; then
z3 --version | $SED 's/.*build hashcode \(.*\)/\1/' | tr -d '\r'
else
z3 --version | $SED 's/Z3 version \([0-9\.]\+\).*/\1/'
fi
fi
}
# ------------------------------------------------------------------------------
# The functions that implement the main actions
# ------------------------------------------------------------------------------
do_update_z3 () {
# Update our clone of FStarLang/binaries and check that we have the blessed z3
# version
if ! [[ -d fstarlang_binaries ]]; then
echo "... cloning FStarLang/binaries"
try_git_clone "git@github.com:FStarLang/binaries.git" "https://github.com/FStarLang/binaries.git" fstarlang_binaries
fi
(cd fstarlang_binaries && git fetch && git checkout z3-4.8.5 && git reset --hard origin/z3-4.8.5)
local current_z3=$(parse_z3_version)
echo "... version of z3 found in PATH: $current_z3"
if is_windows; then
local new_z3_file=fstarlang_binaries/z3-tested/z3-4.8.5*-x64-win.zip
elif is_osx; then
local new_z3_file=fstarlang_binaries/z3-tested/z3-4.8.5*-x64-osx-*.zip
elif [[ $(lsb_release -i | awk '{ print $3; }') == "Ubuntu" ]]; then
local new_z3_file=fstarlang_binaries/z3-tested/z3-4.8.5*-x64-ubuntu-14.04.zip
elif [[ $(lsb_release -i | awk '{ print $3; }') == "Debian" ]]; then
local new_z3_file=fstarlang_binaries/z3-tested/z3-4.8.5*-x64-debian-*.zip
else
red "WARNING: could not figure out your system via lsb_release; defaulting to Debian"
local new_z3_file=fstarlang_binaries/z3-tested/z3-4.8.5*-x64-debian-*.zip
fi
local new_z3=4.8.5
new_z3_file=$(ls $new_z3_file)
echo "... version of z3 found in z3-tested is: $new_z3_file"
if [[ $new_z3 != $current_z3 ]]; then
magenta "Get the freshest z3 from FStarLang/binaries? [Yn]"
prompt_yes true "exit 1"
echo "... ls fstarlang_binaries/z3-tested"
ls -altrh fstarlang_binaries/z3-tested
echo "... ls $new_z3_file"
ls -altrh $new_z3_file
echo "... unzipping $new_z3_file"
unzip $new_z3_file
local new_z3_folder=${new_z3_file%%.zip}
new_z3_folder=${new_z3_folder##fstarlang_binaries/z3-tested/}
find $new_z3_folder -iname '*.dll' -or -iname '*.exe' | xargs chmod a+x
magenta "Automatically customize $EVEREST_ENV_DEST_FILE with the z3 path? [Yn]"
prompt_yes "write_z3_env_dest_file $new_z3_folder" true
rm -f z3
ln -sf $new_z3_folder z3
fi
}
# Windows-only: print out the directory of the Python associated to SCons
windows_scons_python_dir () {
PYDIR=$(regtool -q get "/HKLM/Software/Python/PythonCore/$SCONS_PYTHON_MAJOR_MINOR/InstallPath/" || true)
if ! [[ -d $PYDIR ]] ; then
PYDIR=$(regtool -q get "/HKCU/Software/Python/PythonCore/$SCONS_PYTHON_MAJOR_MINOR/InstallPath/" || true)
fi
if ! [[ -d $PYDIR ]] ; then
red "ERROR: Python $SCONS_PYTHON_MAJOR_MINOR was not installed properly"
exit 1
fi
echo "$PYDIR"
}
# check_windows_scons: (Windows only) checks if Python 3.x and a
# corresponding Scons and pywin32 are installed; and if not, propose
# to install scons and pywin32 along with its required Python
check_windows_scons ()
{
if command -v scons.bat > /dev/null 2>&1 ; then
echo "... scons.bat found in PATH"
# Check whether it corresponds to the right expected version of Python
scons.bat --file=scons-python-version-test.py
echo "... scons is well configured for Python $SCONS_PYTHON_MAJOR_MINOR"
else
magenta "Warning: scons.bat not found in PATH"
if ! PYDIR=$(windows_scons_python_dir) ; then
red "ERROR: No Python $SCONS_PYTHON_MAJOR_MINOR found"
magenta "Do you want to install Windows Python $SCONS_PYTHON_VER , and scons for that version of Python?"
prompt_yes true "exit 1"
local python_file_name="python-$SCONS_PYTHON_VER-amd64.exe"
wget "https://www.python.org/ftp/python/$SCONS_PYTHON_VER/$python_file_name"
chmod +x "$python_file_name"
# From: https://docs.python.org/3/using/windows.html
"./$python_file_name" /passive
PYDIR=$(windows_scons_python_dir)
else
echo "... Python $SCONS_PYTHON_MAJOR_MINOR found"
fi
if "$PYDIR/python.exe" "$PYDIR/Scripts/scons.py" -f scons-python-version-test.py ; then
echo '... SCons for Python $SCONS_PYTHON_MAJOR_MINOR was detected'
else
red "No SCons detected for Python $SCONS_PYTHON_MAJOR_MINOR"
magenta "Do you want to install SCons $SCONS_VER for Python $SCONS_PYTHON_MAJOR_MINOR ?"
prompt_yes true "exit 1"
wget $SCONS_INSTALL_POINT
tar xf "$SCONS_INSTALL_FILE"
pushd "$SCONS_INSTALL_DIR"
"$PYDIR/python.exe" setup.py install # --prefix=$scons_target_wdir
popd
# Test whether SCons was installed properly
"$PYDIR/python.exe" "$PYDIR/Scripts/scons.py" -f scons-python-version-test.py
fi
magenta 'The default scons.bat is installed in a directory that cannot be added to PATH,'
magenta 'because that directory contains a python.exe, which would shadow the already'
magenta 'existing python command that shall point to a Python 2.x.'
magenta 'Do you want to create a new scons.bat and have PATH point to it?'
if prompt_yes true false
then
pydir_dos=$(cygpath -d "$PYDIR")
mkdir -p scons
echo "$pydir_dos/python.exe $pydir_dos/Scripts/scons.py "'%*' > scons/scons.bat
chmod +x scons/scons.bat
windows_append_path "$PWD/scons"
fi
fi
# Also test for pywin32
echo "checking for pywin32"
if ! PYDIR=$(windows_scons_python_dir) ; then
red "ERROR: Python $SCONS_PYTHON_MAJOR_MINOR was not installed properly"
exit 1
fi
if "$PYDIR/Scripts/pip.exe" show pywin32 ; then
echo "... pywin32 found"
else
red "pywin32 does not seem to be installed for Python $SCONS_PYTHON_MAJOR_MINOR"
magenta "Do you want to install it?"
prompt_yes true "exit 1"
"$PYDIR/Scripts/pip.exe" install pywin32
fi
}
do_check ()
{
blue "Checking environment"
# Basic utilities
success_or "which" "please execute this script in a Unix environment"
if is_osx; then
local msg="please run \"brew install gnu-getopt coreutils gnu-sed findutils make\""
brew --prefix gnu-getopt || echo $msg
success_or "greadlink" "$msg"
success_or "gsed" "$msg"
success_or "gfind" "$msg"
success_or "gmake" "$msg"
fi
# Slightly suboptimal, since we may end up running Cygwin's setup twice.
if ! command -v git >/dev/null 2>&1; then
if is_windows; then
magenta "Git not found. Install Cygwin's git? [Yn]"
find_cygsetup
prompt_yes "$cygsetup $cygsetup_args --packages=git"
else
red "ERROR: git not found; install it via your favorite package manager"
exit 1
fi
fi
# Windows pre-requisites
if is_windows; then
# A list of known causes for failure
if where.exe bash.exe | grep -v cygwin >/dev/null 2>&1; then
red "ERROR: bash.exe has been found in a non-standard location!"
echo "Please remove Bash for Windows and others (GNU for Windows, MSYS2, etc.)"
red "Are you sure you want to continue? [Yn]"
prompt_yes true "exit 1"
else
echo "... no suspicious bash"
fi
if [[ $(uname -m) != "x86_64" ]]; then
red "ERROR: not a 64-bit Cygwin"
echo "We've experienced tons of issues with 32-bit Cygwin. Time to upgrade."
exit 1
fi
echo "... 64-bit cygwin"
if cygwin_has "ocaml" || cygwin_has "flexdll"; then
red "ERROR: please remove the cygwin ocaml and/or flexdll packages"
exit 1
fi
echo "... no suspicious cygwin packages"
if ! (flexlink.exe -help 2>&1 || true) | grep "fdopen" >/dev/null; then
red "Warning: you have an unknown version of flexlink"
red "Please use the version from https://fdopen.github.io/opam-repository-mingw/"
else
echo "... flexlink is good"
fi
# The list of required cygwin packages
for p in $(cat cygwin-packages); do
if ! cygwin_has $p; then
find_cygsetup
echo "Cygwin package $p is missing"
if_yes "$cygsetup $cygsetup_args --packages=$(cat cygwin-packages | tr '\n' ,)"
fi
done
echo "... all $(cat cygwin-packages | wc -l) cygwin packages seem to be installed"
if ! command -v libsqlite3-0.dll >/dev/null 2>&1; then
red "Warning: x86_64-mingw32 DLLs not in PATH"
magenta "Automatically customize $EVEREST_ENV_DEST_FILE with the x86_64-mingw32 path + native windows symlinks?"
prompt_yes write_cygwin_env_dest_file true
else
echo "... proper mingw directory seems to be in PATH"
fi
if [[ -z "$CXX" ]] ; then
red "Warning: CXX not defined"
magenta "Automatically set CXX to x86_64-w64-mingw32-g++.exe?"
prompt_yes write_cxx_env_dest_file true
fi
fi # if is_windows
# Note: ssh returns the exit code of the remote command (1 in this case),
# hence the || true -- the success of this step is determined by the presence
# of "authenticated".
if ! (ssh -oStrictHostKeyChecking=no git@github.com 2>&1 || true) | grep authenticated >/dev/null; then
magenta "Warning: git client not configured with the proper ssh credentials"
echo "Hint: check which git you're running, and make sure you have the same SSH key in ~/.ssh and github.com"
else
echo "... github.com access ok"
fi
# OCaml detection
if ! command -v >/dev/null 2>&1 ocaml; then
# Offer to install and sed-setup a crappy snapshot
if is_windows; then
magenta "No OCaml detected!"
cat <<MSG
Proceed with the download?
MSG
prompt_yes true "exit 1"
if [ -e ~/.opam ]; then
red "Warning: stale ~/.opam; continue? [Yn]"
prompt_yes true "exit 1"
fi
if [ -e /cygdrive/c/ocamlmgw64 ]; then
red "Warning: stale /cygdrive/c/ocamlmgw64; continue? [Yn]"
prompt_yes true "exit 1"
fi
# Download and Install OPAM
wget $OPAM_URL
tar -xf 'opam64.tar.xz'
rm -f 'opam64.tar.xz'
bash opam64/install.sh
echo "Interactive is: $INTERACTIVE ; auto-setup is: $OPAM_AUTO_SETUP ; dot-profile is: $EVEREST_ENV_DEST_FILE ;"
opam init default "https://github.com/fdopen/opam-repository-mingw.git#opam2" -c "ocaml-variants.$OPAM_VERSION" --disable-sandboxing
if { ! $INTERACTIVE ; } && ! grep 'opam-init' "$EVEREST_ENV_DEST_FILE" >/dev/null ; then
# --auto-setup might not have worked, so manually do it here.
# Do not expand variables in the textual output.
echo '. "$HOME/.opam/opam-init/init.sh" > /dev/null 2>/dev/null' >> "$EVEREST_ENV_DEST_FILE"
fi
eval $(opam config env)
else
red "ERROR: no ocaml found in PATH"
if is_osx; then
echo "Hint: brew install ocaml opam"
else
echo "Please use your distribution's package management system to install ocaml and opam"
echo "Note: on older Ubuntus, see https://launchpad.net/~avsm/+archive/ubuntu/ppa"
fi
exit 1
fi
else
# OCaml; if this exits, set -e means this is a hard error
ocaml -noinit -noprompt -stdin <<OCAML
if Sys.ocaml_version < "$MINIMAL_OCAML_VERSION" then begin
print_endline "ERROR: Everest needs OCaml >= $MINIMAL_OCAML_VERSION";
print_endline ("You have OCaml " ^ Sys.ocaml_version);
exit 1
end
OCAML
echo "... ocaml minimum version requirements met"
fi
# OCamlfind & extra packages. Required OPAM packages are stored in
# [opam-packages], where each line is of the form:
# <ocamlfind-package-name> <SPACE> <opam-package-name>
success_or "opam"
if [ ! -d ~/.opam ]; then
if is_windows; then
echo "This is a Windows environment; not running opam init."
echo "Please follow instructions for the installer you picked."
echo "Hint: https://github.com/protz/ocaml-installer/wiki or https://fdopen.github.io/opam-repository-mingw/"
else
if_yes "opam init"
fi
eval $(opam config env)
fi
if ! command -v ocamlfind >/dev/null 2>&1; then
magenta "ocamlfind not found!"
if_yes "opam install ocamlfind"
fi
missing=false
while read line; do
ocamlfind_package=$(echo $line | cut -d " " -f 1)
opam_package=$(echo $line | cut -d " " -f 2)
if ! ocamlfind query $ocamlfind_package >/dev/null 2>&1; then
red "ERROR: ocamlfind package $ocamlfind_package is not installed"
missing=true
break
fi
done < opam-packages
if $missing; then
if_yes "install_all_opam_packages"
fi
echo "... all $(cat opam-packages | wc -l) ocamlfind packages found"
# Check for caveats using my OCaml installer
if ! (cd test && ocamlbuild test.native -use-ocamlfind >compiler_output 2>&1); then
red "Cannot compile the test OCaml program (see errors in test/compiler_output)"
red "Maybe you've been using the OCaml installer for windows"
echo Suggestion: check \
https://github.com/protz/ocaml-installer/wiki#package-specific-hints and \
follow instructions for ppx deriving and friends
exit 1
fi
rm -f test/compiler_output
echo "... sample ocamlbuild project compiles successfully"
if is_windows && [ -d "/cygdrive/c/OCaml/lib/camlp4" ] && [[ $CAMLP4LIB == "" ]]; then
red "Warning: seems like you're using the OCaml installer for windows"
echo There is a bug in the installer -- please see \
https://github.com/protz/ocaml-installer/wiki#configure-your-initial-opam-setup \
and add \"export CAMLP4LIB=C:/OCaml/lib/camlp4\" in your "$EVEREST_ENV_DEST_FILE"
fi
if is_windows ; then
# the latest ocaml-stdint segfaults on Windows with
# 128-bit integers (confirmed on gcc-9 at least)
# so we need to test whether it works, and if not,
# then we pull a homemade patch that recompiles it with
# C compiler optimizations disabled
if ! [[ -d ocaml-stdint ]] ; then
echo "... cloning tahina-pro/ocaml-stdint"
try_git_clone "git@github.com:tahina-pro/ocaml-stdint.git" "https://github.com/tahina-pro/ocaml-stdint.git" ocaml-stdint
fi
echo "... building ocaml-stdint test"
(cd ocaml-stdint && git clean -ffdx)
ocamlfind ocamlopt -package str,qcheck,stdint ocaml-stdint/tests/stdint_test.ml -linkpkg -o ocaml-stdint/tests/stdint_test.exe
echo "... running ocaml-stdint test"
if
{ ocaml-stdint/tests/stdint_test.exe > /dev/null ; } ||
[[ $? -le 1 ]] # tests fail, but should not segfault
then
echo "... ocaml-stdint works well"
else
magenta "ERROR: Your ocaml stdint package does not work with your C compiler."
magenta "Do you want to have it recompiled with -O0 and reinstalled? [Yn]"
prompt_yes true "exit 1"
echo "... recompiling and reinstalling ocaml-stdint from tahina-pro/ocaml-stdint"
(
cd ocaml-stdint &&
git clean -ffdx &&
$MAKE &&
$MAKE tests/stdint_test &&
{ { tests/stdint_test.exe > /dev/null ; } || [[ $? -le 1 ]] ; } &&
dune install
)
fi
fi
# Check for Node.js
if ! which node >/dev/null 2>&1 ; then
red "ERROR: Node.js doesn\'t seem to be installed"
if is_windows ; then
magenta "Download it from the internet? [Yn]"
prompt_yes true "exit 1"
# There is no clean way to determine the latest version of
# Node.js available. However, the URL below points to a HTML
# page containing a list of files, and there, there is exactly
# one link to a .msi file corresponding to 64-bit platforms. So
# we just need to extract its name from the page.
NODEJS_MSI=$(wget --output-document=- --no-verbose --quiet https://nodejs.org/dist/latest/ | grep -o '"node-[^-]*-x64\.msi"' | sed 's!"!!g')
# Check that there are exactly one .msi file there
test $(echo "$NODEJS_MSI" | grep -o '\.msi' | wc -l) -eq 1
# Finally, launch Windows installer in unattended mode
msiexec /i "https://nodejs.org/dist/latest/$NODEJS_MSI" /quiet /passive
# Test whether Node.js installed properly
# Impossible: Windows PATH has changed, we cannot refresh it
# which node > /dev/null 2>&1
red "CRITICAL: Windows PATH has changed, please restart a new Cygwin window"
else
echo "Please install node.js through your package manager"
exit 1
fi
fi
echo "... Node.js found in PATH"
# F# and MS compilers (note: nothing for OSX/Linux right now)
if is_windows; then
# note: nothing left, we will use vcvarsall.bat/vsdevcmd.bat instead
true
else
success_or "fsharpc" "brew install mono (Intel) or install mono from website (M1) and reopen terminal"
fi
echo "... fsc found in PATH"
do_update_z3
# Check whether python points to a python2
if which python > /dev/null 2>&1 ; then
# nasty: python outputs its version on STDERR
if python --version 2>&1 | grep '^Python 2\.' 2>/dev/null ; then
echo "... python found in PATH, points to some Python 2.x"
else
red "ERROR: python points to something that is not a Python 2.x"
red "Please fix this according to your platform"
exit 1
fi
else
magenta "WARNING: python not found in PATH"
fi
# Check for Python 2
if ! which python2 >/dev/null 2>&1 ; then
red "ERROR: python2 not found in PATH"
if is_windows ; then
magenta "Do you want to install a Cygwin python2?"
find_cygsetup
cygcmd="$cygsetup $cygsetup_args --packages=python2"
echo "$cygcmd"
prompt_yes "$cygcmd"
else
echo Please install python2 using your package manager
exit 1
fi
else
echo "... python2 found in PATH"
fi
# We need Scons for Vale which needs Python 3
if is_windows; then
check_windows_scons
else # *nix
if ! command -v scons >/dev/null 2>&1; then
red "ERROR: scons not installed -- please install"
exit 1
else
echo "... scons found in PATH"
if ! which python$SCONS_PYTHON_MAJOR > /dev/null 2>&1 ; then
red "ERROR: python$SCONS_PYTHON_MAJOR not found in PATH"
red "Please install Python $SCONS_PYTHON_MAJOR or higher"
exit 1
fi
echo "... python$SCONS_PYTHON_MAJOR found in PATH"
# Check whether it corresponds to a Python 3.6 or above
python$SCONS_PYTHON_MAJOR $(which scons) --file=scons-python-version-test.py
echo "... python$SCONS_PYTHON_MAJOR is recent enough"
fi
fi
if [[ -z "$EVEREST_SCONS_CACHE_DIR" ]]; then
echo "Warning: Scons cache directory not set. Set it?"
prompt_yes write_everest_env_dest_file true
fi
if is_windows; then
if [[ $(echo $FSTAR_HOME | cut -c 1 | tr -d '\r\n' ) == "/" ]]; then
magenta "You are on windows but your FSTAR_HOME is a Cygwin-style path."
magenta "Don't do that, follow the suggestion below, and check all your other *_HOME variables."
unset FSTAR_HOME
fi
fi
echo
magenta "Remember to run source \"$EVEREST_ENV_DEST_FILE\" if it was modified!"
local xpwd=""
if is_windows; then
xpwd="$(cygpath -m $(pwd))"
else
xpwd="$(pwd)"
fi
magenta "Note: you *may* want to add ${xpwd}/FStar/bin and ${xpwd}/karamel to your PATH"
[ -n "${FSTAR_HOME}" ] || \
magenta "Note: you *may* want to export FSTAR_HOME=${xpwd}/FStar"
[ -n "${KRML_HOME}" ] || \
magenta "Note: you *may* want to export KRML_HOME=${xpwd}/karamel"
[ -n "${HACL_HOME}" ] || \
magenta "Note: you *may* want to export HACL_HOME=${xpwd}/hacl-star"
}
get_vale ()
{
if [ ! -d vale ]; then
mkdir vale
fi
vale_version=$(<hacl-star/vale/.vale_version)
vale_version=${vale_version%$'\r'} # remove Windows carriage return, if it exists
old_vale_version=none
if [ -e vale/bin/.vale_version ]; then
old_vale_version=$(<vale/bin/.vale_version)
old_vale_version=${old_vale_version%$'\r'} # remove Windows carriage return, if it exists
fi
if [ $vale_version != $old_vale_version ]; then
wget "https://github.com/project-everest/vale/releases/download/v${vale_version}/vale-release-${vale_version}.zip" -O vale/vale-release.zip
rm -rf "vale/vale-release-${vale_version}"
unzip -o vale/vale-release.zip -d vale
rm -rf "vale/bin"
mv "vale/vale-release-${vale_version}/bin" vale/
chmod +x vale/bin/*.exe
fi
}
self_update () {
check_no_archive
old_revision=$(git rev-parse HEAD)
git pull --rebase
if [[ $(git rev-parse HEAD) != $old_revision ]]; then
blue "Self-updating to new everest revision $(git rev-parse HEAD | cut -c 1-8)"
# Now, we transfer execution to the new version of $0
cd "$initial_pwd"
exec "${@/pull/}"
else
echo "No new everest revision available"
fi
}
do_pull () {
source hashes.sh
source repositories.sh
echo Reset working copies
do_reset
}
symlink_clone_warned=false
check_subp_exists () {
check_no_archive
local r=$1
if [ ! -d $r ]; then
if [ -e $r ]; then
red "$r exists but is not a directory, aborting"
exit 1
fi
if ! $symlink_clone_warned; then
echo Note: you\'re welcome to create symbolic links if you already have \
cloned the repository elsewhere
symlink_clone_warned=true
fi
try_git_clone ${repositories[$r]} ${https[$r]} $r
fi
}
do_reset ()
{
for r in $ALL_PROJECTS; do
echo
blue "Pulling $r"
# Some sanity checks, and clone the repositories that aren't there already
check_subp_exists "$r"
# Note: the snapshot command guarantees that the commit was pushed to a
# branch of the form origin/foo. So, we checkout foo, because there's a good
# chance it tracks origin/foo which contains the commit we want. If it's not
# the case it's a crazy setup and the user is on their own.
cd $r
git fetch
hash=${hashes[$r]}
branch=${branches[$r]}
if [[ $(git symbolic-ref HEAD) != $branch ]]; then
git checkout -f $branch
fi
# Note: this is not super robust in the face of weird cases like someone
# having a local branch named origin/master, in which case [upstream] will
# contain "remotes/origin/master"... alternate solution:
# local found=false
# for b in $(git branch -r --contains $hash | awk '{ print $0; }'); do
# if [[ $upstream == $(git rev-parse --abbrev-ref --symbolic-full-name $b@{u} ]]; then
# found=true
# fi
# done
# if ! $found; then
# etc.
# fi
# Note: the --format option of git branch would be better than awk but a lot of
# people are stuck on git 2.8, including cygwin and Azure VMs.
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name @{u})
if ! git branch -r --contains $hash | egrep "^ +$upstream$" >/dev/null 2>&1; then
red "ERROR: in repository $r, the hash $hash claims to belong to branch \
$branch, but $branch pulls from $upstream which does not contain $hash"
exit 1
fi
git reset --hard $hash
git submodule update --init
cd ..
done
get_vale
}
do_advance ()
{
for r in $ALL_PROJECTS; do
echo
blue "Advancing $r"
check_subp_exists "$r"
pushd $r
branch=${branches[$r]}
if ( ! $ADVANCE_YES ) && ( git status -s -uall | grep -q . ); then
red "project $r has local changes, aborting advance (pass --yes to ignore)"
exit 1
fi
git checkout -f $branch
git fetch
git reset --hard origin/$branch
git submodule update --init
popd
done
}
do_archive ()
{
TEMPDIR=$(mktemp -d -p .)
OUTDIR0=${TEMPDIR}/everest/
OUTDIR=$(realpath ${OUTDIR0})
# Make sure every subproject is there.
for r in ${!repositories[@]}; do
check_subp_exists "$r"
done
# Now we're sure hacl-star is there, so we have
# hacl-star/vale/.vale_version. Fetch that version of vale.
get_vale
# Go through each sub-repository (including the openssl submodule for MLCrypto)
# and put them in the staging directory ${OUTDIR}
mkdir -p ${OUTDIR}
for r in ${!repositories[@]} MLCrypto/openssl/; do
echo
blue "Archiving $r"
pushd $r
if ( git status -s -uall | grep -q . ); then
red "WARNING: project $r has local changes which will not be reflected in the archive"
fi
git archive HEAD --prefix "$r/" | tar -C ${OUTDIR} -x
popd