/
erlbrew
executable file
·316 lines (278 loc) · 7.82 KB
/
erlbrew
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
#!/bin/bash
#
# erlbrew: simplify / automate side-by-side Erlang builds
#
# Copyright (C) 2016 Mark Allen
# This software is released under the terms of the MIT license
# included in the README file or available here:
# http://opensource.org/licenses/MIT
set -e
set -u
usage() {
echo "Usage: $0 {download|build|install|use|list} [release-spec]"
}
# Given a release, map it to the appropriate directory when unpacked
_map_dir() {
RELEASE_SUFFIX=$1
case $1 in
R15B03-1)
# R15B03-1 unpacks to just R15B03
RELEASE_SUFFIX="R15B03"
esac
echo "otp_src_$RELEASE_SUFFIX"
}
if (( $# > 2 )); then
usage
exit 1
elif (( $# == 2 )); then
CMD=$1
RELEASE=$2
elif (( $# == 1 )); then
if [[ "$1" != "list" ]]; then
usage
exit 1
fi
CMD=$1
RELEASE="dummy"
else
usage
exit 1
fi
WORK="$HOME/.erlbrew"
STATE="$WORK/.erlbrew_current"
BUILD="$WORK/.build"
INSTALL="$WORK/$RELEASE"
FILENAME="otp_src_$RELEASE"
DIRNAME="$(_map_dir $RELEASE)"
DOWNLOAD_FILE="$FILENAME.tar.gz"
TARBALL_PATH="$BUILD/tarballs"
CHECKSUM_PATH="$BUILD/MD5"
TMP_PATH="$BUILD/work.$$"
DOWNLOAD_PATH="$BUILD/tarballs/$DOWNLOAD_FILE"
DOWNLOAD_URL="https://www.erlang.org/download/$DOWNLOAD_FILE"
DOWNLOAD_TOOL=$(which curl)
DOWNLOAD_TOOL_FLAGS="--insecure --fail --progress-bar --location --show-error"
DOWNLOAD_OTP_CMD="$DOWNLOAD_TOOL $DOWNLOAD_TOOL_FLAGS --output $DOWNLOAD_PATH $DOWNLOAD_URL"
DOWNLOAD_CHECKSUM_CMD="$DOWNLOAD_TOOL $DOWNLOAD_TOOL_FLAGS --output $CHECKSUM_PATH https://www.erlang.org/download/MD5"
BIN_PATH="$HOME/bin/.erlbrew.d"
UNTAR_CMD=$(which tar)
UNTAR_FLAGS="-zxvf"
_cleanup() {
if [ -d $BUILD ]; then
for directory in $(find "$BUILD" -name "work*" -type d -mtime +7d -print)
do
rm -rf $directory
done
fi
}
download() {
if [ ! -d "$TARBALL_PATH" ]; then
mkdir -p "$TARBALL_PATH"
fi
if [ ! -e "$DOWNLOAD_PATH" ]; then
echo "Downloading Erlang $RELEASE"
$DOWNLOAD_OTP_CMD
else
echo "You appear to have Erlang $RELEASE downloaded."
fi
CHECKSUM_FILE_VALUE=$(grep $DOWNLOAD_FILE $CHECKSUM_PATH 2>/dev/null | cut -d" " -f2)
if [ ! -e "$CHECKSUM_PATH" ] || [ -z "$CHECKSUM_FILE_VALUE" ] ; then
echo "Downloading checksum file"
$DOWNLOAD_CHECKSUM_CMD
CHECKSUM_FILE_VALUE=$(grep $DOWNLOAD_FILE $CHECKSUM_PATH | cut -d" " -f2)
fi
COMPUTED_CHECKSUM=$(md5 -q $DOWNLOAD_PATH)
if [ "$CHECKSUM_FILE_VALUE" != "$COMPUTED_CHECKSUM" ]; then
echo "The file $DOWNLOAD_PATH has MD5"
echo "$COMPUTED_CHECKSUM and it should have"
echo "$CHECKSUM_FILE_VALUE"
exit 1
fi
echo "Tarball has correct MD5 checksum"
}
build() {
mkdir -p "$TMP_PATH"
rm -f "$BUILD/current"
ln -s "$TMP_PATH" "$BUILD/current"
cp -a "$DOWNLOAD_PATH" "$TMP_PATH"
cd "$TMP_PATH"
echo "Unpacking Erlang $RELEASE"
$UNTAR_CMD $UNTAR_FLAGS $DOWNLOAD_FILE 1>>"$TMP_PATH/erlbrew.log" 2>&1
cd "$DIRNAME"
echo "Configuring Erlang $RELEASE for $OSTYPE"
if [[ "${CFLAGS:-unset}" == "unset" ]]; then
CFLAGS=""
fi
if [[ "$OSTYPE" =~ darwin(.*) ]]; then
VERSION=${BASH_REMATCH[1]}
# Patch the R14 source in OS X 10.8 or newer (Mountain Lion, Mavericks)
if [[ $VERSION -ge 12 ]]; then
case "$RELEASE" in
R14*)
CFLAGS="-DERTS_DO_INCL_GLB_INLINE_FUNC_DEF"
apply_r14_osx_patch
esac
fi
if [[ "${ERLBREW_CONFIGURE_OPTIONS:-unset}" == "unset" ]]; then
ERLBREW_CONFIGURE_OPTIONS=""
if [ $VERSION -ge 15 ]; then
if [[ "${ERLBREW_OPENSSL_PATH:-unset}" == "unset" ]]; then
ERLBREW_OPENSSL_PATH="/usr/local/ssl"
fi
if [ -d "$ERLBREW_OPENSSL_PATH" ]; then
ERLBREW_CONFIGURE_OPTIONS="--with-ssl=$ERLBREW_OPENSSL_PATH $ERLBREW_CONFIGURE_OPTIONS"
elif [ -d /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-migrator/sdk/MacOSX.sdk/usr ]; then
# Apple removed OpenSSL from El Capitan but its still in this funky
# location, so auto set this if the directory exists - fragile but
# better than nothing
ERLBREW_CONFIGURE_OPTIONS="--with-ssl=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-migrator/sdk/MacOSX.sdk/usr $ERLBREW_CONFIGURE_OPTIONS"
else
echo "I can't figure out where OpenSSL is on this system. Set ERLBREW_OPENSSL_PATH and retry."
exit 1
fi
fi
case "$RELEASE" in
17*|18*|19*)
ERLBREW_CONFIGURE_OPTIONS=" --enable-dirty-schedulers $ERLBREW_CONFIGURE_OPTIONS"
esac
ERLBREW_CONFIGURE_OPTIONS=" --with-dynamic-trace=dtrace $ERLBREW_CONFIGURE_OPTIONS"
fi
CFLAGS="$CFLAGS -O0" ./configure $ERLBREW_CONFIGURE_OPTIONS --disable-hipe --without-javac --enable-smp-support \
--enable-threads --enable-kernel-poll --without-odbc \
--enable-darwin-64bit --prefix="$INSTALL" 1>>"$TMP_PATH/erlbrew.log" 2>&1
else
echo "Sorry $OSTYPE isn't supported yet. Patches welcome. :)"
exit 1
fi
echo "Building Erlang $RELEASE"
make 1>>"$TMP_PATH/erlbrew.log" 2>&1
if [ ${ERLBREW_MAKE_DOCS:-''} ]; then
echo "Building Erlang $RELEASE documentation"
make docs 1>>"$TMP_PATH/erlbrew.log" 2>&1
fi
}
install() {
if [ ! -d "$INSTALL" ]; then
mkdir -p "$INSTALL"
else
rm -rf "$INSTALL"
mkdir -p "$INSTALL"
fi
echo "Installing Erlang $RELEASE"
make install 1>>"$TMP_PATH/erlbrew.log" 2>&1
if [ ${ERLBREW_MAKE_DOCS:-''} ]; then
echo "Installing Erlang $RELEASE documentation"
make install-docs 1>>"$TMP_PATH/erlbrew.log" 2>&1
fi
}
use() {
if [ ! -d "$BIN_PATH" ]; then
mkdir -p "$BIN_PATH"
else
rm -rf "$BIN_PATH"
mkdir -p "$BIN_PATH"
fi
if [ -d "$INSTALL" ]; then
for file in $(ls "$INSTALL/lib/erlang/bin/"*)
do
ln -s $file "$BIN_PATH"
done
hash -r
echo $RELEASE > "$STATE"
echo "You have switched to Erlang $RELEASE"
else
echo "Erlang $RELEASE doesn't seem to be installed."
exit 1
fi
}
list() {
CURRENT="hoge"
if [ -e "$STATE" ]; then
CURRENT=$(<"$STATE")
fi
if [ -d $WORK ]; then
for r in $(ls -1 $WORK)
do
if [[ "$r" == "$CURRENT" ]]; then
echo "* $r"
else
echo " $r"
fi
done
else
echo "No Erlang environments installed"
exit 1
fi
}
apply_r14_osx_patch() {
patch -p0 <<END_OF_PATCH
--- erts/emulator/beam/beam_bp.c.orig 2011-10-03 13:12:07.000000000 -0500
+++ erts/emulator/beam/beam_bp.c 2013-10-04 13:42:03.000000000 -0500
@@ -496,7 +496,8 @@
}
/* bp_hash */
-ERTS_INLINE Uint bp_sched2ix() {
+#ifndef ERTS_DO_INCL_GLB_INLINE_FUNC_DEF
+ERTS_GLB_INLINE Uint bp_sched2ix() {
#ifdef ERTS_SMP
ErtsSchedulerData *esdp;
esdp = erts_get_scheduler_data();
@@ -505,6 +506,7 @@
return 0;
#endif
}
+#endif
static void bp_hash_init(bp_time_hash_t *hash, Uint n) {
Uint size = sizeof(bp_data_time_item_t)*n;
Uint i;
--- erts/emulator/beam/beam_bp.h.orig 2011-10-03 13:12:07.000000000 -0500
+++ erts/emulator/beam/beam_bp.h 2013-10-04 13:42:08.000000000 -0500
@@ -144,7 +144,19 @@
#define ErtsSmpBPUnlock(BDC)
#endif
-ERTS_INLINE Uint bp_sched2ix(void);
+ERTS_GLB_INLINE Uint bp_sched2ix(void);
+
+#ifdef ERTS_DO_INCL_GLB_INLINE_FUNC_DEF
+ERTS_GLB_INLINE Uint bp_sched2ix() {
+#ifdef ERTS_SMP
+ ErtsSchedulerData *esdp;
+ esdp = erts_get_scheduler_data();
+ return esdp->no - 1;
+#else
+ return 0;
+#endif
+}
+#endif
#ifdef ERTS_SMP
#define bp_sched2ix_proc(p) ((p)->scheduler_data->no - 1)
END_OF_PATCH
}
case "$CMD" in
download)
_cleanup
download
;;
build)
_cleanup
download
build
;;
install)
_cleanup
download
build
install
;;
use)
_cleanup
use
;;
list)
_cleanup
list
;;
*)
usage
exit 1
esac