File: compile-ocaml.sh

package info (click to toggle)
menhir 20210929-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 4,292 kB
  • sloc: ml: 24,825; sh: 180; makefile: 100; lisp: 8
file content (160 lines) | stat: -rwxr-xr-x 4,204 bytes parent folder | download
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
#!/bin/bash
set -euo pipefail
IFS=$' \n\t'

# This script compiles OCaml using the current version of Menhir and verifies
# that it behaves exactly as expected.

MENHIR_ROOT=$(pwd)

# We use a dedicated opam switch where it is permitted to uninstall/reinstall
# Menhir.

if opam switch list | grep 'test-menhir' >/dev/null ; then
  echo "The switch test-menhir already exists." ;
else
  echo "Creating switch test-menhir..." ;
  opam switch create test-menhir ocaml-system.4.11.1 ;
  echo "Installing required packages..." ;
  opam install --yes dune ;
fi

eval $(opam env --set-switch --switch test-menhir)

# Uninstall Menhir if it is installed.

# We are not sure whether it was installed via opam or directly
# via [make install], so we try both uninstallation methods.

echo "Removing menhir if already installed..."
#   read -p "Can I remove it [Enter/^C]?" -n 1 -r ;
(opam remove menhir menhirLib menhirSdk || /bin/true) >/dev/null 2>&1
make -C $MENHIR_ROOT uninstall >/dev/null 2>&1

# Check if everything has been committed.
# This seems required for [opam pin] to work properly.

if git status --porcelain | grep -v compile-ocaml ; then
  echo "Error: there remain uncommitted changes." ;
  git status ;
  exit 1 ;
  fi

# This function runs a command silently, and prints its execution time.

execute () {
  echo "$1" > .command
  T="$(date +%s)"
  if eval "$1" >log.out 2>log.err ; then
    T="$(($(date +%s)-T))"
    echo " $T seconds." ;
  else
    code=$?
    echo " failure."
    cat log.err
    exit $code
  fi
}

# Check out a fresh copy of OCaml at a specific tag.

TEMPDIR=/tmp/menhir-test-ocaml
mkdir -p $TEMPDIR
cd $TEMPDIR
rm -rf ocaml

echo -n "Cloning OCaml..."
execute "git clone git@github.com:ocaml/ocaml.git --depth 1 --branch 4.11.1"

cd ocaml

# Configure and compile OCaml. This step does not depend on Menhir.

echo -n "Configuring OCaml..."
execute "./configure"

echo -n "Compiling OCaml..."
execute "make -j"
ls -l ocamlc

if false ; then
  echo -n "Testing OCaml..."
  execute "make -C testsuite parallel"
  execute "make -C testsuite clean"
fi

# Install Menhir.

# Should we install Menhir via [make install] or via [opam]?

# [make install], which invokes [dune install], is likely to be much
# faster (especially if Menhir has already been compiled in its
# working directory). Unfortunately, I have seen dune (2.8.2) become
# confused and install files partly in one switch, partly in another,
# so perhaps installing via [opam pin ...] is preferable.

echo -n "Installing Menhir..."

if true ; then
  # Installation via opam.
  execute "make -C $MENHIR_ROOT pin"
else
  # Installation via [make install].
  execute "make -C $MENHIR_ROOT install"
fi
ls -l `which menhir`

# Re-compile OCaml's parser using Menhir.

echo -n "Recompiling OCaml's parser using Menhir..."
execute "make promote-menhir"

echo -n "Committing the recompiled parser..."
execute "git add boot/menhir && git commit -m 'make promote-menhir'"

# Take a snapshot of the ASTs produced by the current parser.

echo -n "Constructing ASTs for all source files..."
execute "make -j build-all-asts"

echo -n "Committing all ASTs..."
execute "make list-all-asts | xargs git add && git commit -m 'Build all ASTs.'"

# Compile OCaml (again).

# Cleaning up first should be unnecessary, but let's make sure the
# compiler is correctly reconstructed from scratch.

echo -n "Cleaning up..."
execute "make clean"

echo -n "Compiling OCaml..."
execute "make -j"
ls -l ocamlc

if false ; then
  echo -n "Testing OCaml..."
  execute "make -C testsuite parallel"
fi

# Reconstruct all ASTs.

# Removing them first should be unnecessary, but let's make sure they
# are correctly reconstructed from scratch.

echo -n "Removing previous ASTs..."
execute "make list-all-asts | xargs rm -f"

echo -n "Constructing ASTs for all source files..."
execute "make -j build-all-asts"

# Compare the ASTs produced by the current parser with the snapshot.

rm -f .command log.{err,out}

if git diff --exit-code >/dev/null ; then
  echo "Success: the original parser and the recompiled parser agree."
else
  echo "Failure: the original parser and the recompiled parser disagree."
  echo "cd $TEMPDIR/ocaml && git status"
fi