]> git.lizzy.rs Git - rust.git/blob - src/etc/install.sh
librustc: Don't try to perform the magical
[rust.git] / src / etc / install.sh
1 #!/bin/sh
2 # Copyright 2014 The Rust Project Developers. See the COPYRIGHT
3 # file at the top-level directory of this distribution and at
4 # http://rust-lang.org/COPYRIGHT.
5 #
6 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9 # option. This file may not be copied, modified, or distributed
10 # except according to those terms.
11
12 msg() {
13     echo "install: $1"
14 }
15
16 step_msg() {
17     msg
18     msg "$1"
19     msg
20 }
21
22 warn() {
23     echo "install: WARNING: $1"
24 }
25
26 err() {
27     echo "install: error: $1"
28     exit 1
29 }
30
31 need_ok() {
32     if [ $? -ne 0 ]
33     then
34         err "$1"
35     fi
36 }
37
38 putvar() {
39     local T
40     eval T=\$$1
41     eval TLEN=\${#$1}
42     if [ $TLEN -gt 35 ]
43     then
44         printf "install: %-20s := %.35s ...\n" $1 "$T"
45     else
46         printf "install: %-20s := %s %s\n" $1 "$T" "$2"
47     fi
48 }
49
50 valopt() {
51     VAL_OPTIONS="$VAL_OPTIONS $1"
52
53     local OP=$1
54     local DEFAULT=$2
55     shift
56     shift
57     local DOC="$*"
58     if [ $HELP -eq 0 ]
59     then
60         local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
61         local V="CFG_${UOP}"
62         eval $V="$DEFAULT"
63         for arg in $CFG_ARGS
64         do
65             if echo "$arg" | grep -q -- "--$OP="
66             then
67                 val=$(echo "$arg" | cut -f2 -d=)
68                 eval $V=$val
69             fi
70         done
71         putvar $V
72     else
73         if [ -z "$DEFAULT" ]
74         then
75             DEFAULT="<none>"
76         fi
77         OP="${OP}=[${DEFAULT}]"
78         printf "    --%-30s %s\n" "$OP" "$DOC"
79     fi
80 }
81
82 opt() {
83     BOOL_OPTIONS="$BOOL_OPTIONS $1"
84
85     local OP=$1
86     local DEFAULT=$2
87     shift
88     shift
89     local DOC="$*"
90     local FLAG=""
91
92     if [ $DEFAULT -eq 0 ]
93     then
94         FLAG="enable"
95     else
96         FLAG="disable"
97         DOC="don't $DOC"
98     fi
99
100     if [ $HELP -eq 0 ]
101     then
102         for arg in $CFG_ARGS
103         do
104             if [ "$arg" = "--${FLAG}-${OP}" ]
105             then
106                 OP=$(echo $OP | tr 'a-z-' 'A-Z_')
107                 FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
108                 local V="CFG_${FLAG}_${OP}"
109                 eval $V=1
110                 putvar $V
111             fi
112         done
113     else
114         if [ ! -z "$META" ]
115         then
116             OP="$OP=<$META>"
117         fi
118         printf "    --%-30s %s\n" "$FLAG-$OP" "$DOC"
119      fi
120 }
121
122 flag() {
123     BOOL_OPTIONS="$BOOL_OPTIONS $1"
124
125     local OP=$1
126     shift
127     local DOC="$*"
128
129     if [ $HELP -eq 0 ]
130     then
131         for arg in $CFG_ARGS
132         do
133             if [ "$arg" = "--${OP}" ]
134             then
135                 OP=$(echo $OP | tr 'a-z-' 'A-Z_')
136                 local V="CFG_${OP}"
137                 eval $V=1
138                 putvar $V
139             fi
140         done
141     else
142         if [ ! -z "$META" ]
143         then
144             OP="$OP=<$META>"
145         fi
146         printf "    --%-30s %s\n" "$OP" "$DOC"
147      fi
148 }
149
150 validate_opt () {
151     for arg in $CFG_ARGS
152     do
153         isArgValid=0
154         for option in $BOOL_OPTIONS
155         do
156             if test --disable-$option = $arg
157             then
158                 isArgValid=1
159             fi
160             if test --enable-$option = $arg
161             then
162                 isArgValid=1
163             fi
164             if test --$option = $arg
165             then
166                 isArgValid=1
167             fi
168         done
169         for option in $VAL_OPTIONS
170         do
171             if echo "$arg" | grep -q -- "--$option="
172             then
173                 isArgValid=1
174             fi
175         done
176         if [ "$arg" = "--help" ]
177         then
178             echo
179             echo "No more help available for Configure options,"
180             echo "check the Wiki or join our IRC channel"
181             break
182         else
183             if test $isArgValid -eq 0
184             then
185                 err "Option '$arg' is not recognized"
186             fi
187         fi
188     done
189 }
190
191 absolutify() {
192     FILE_PATH="${1}"
193     FILE_PATH_DIRNAME="$(dirname ${FILE_PATH})"
194     FILE_PATH_BASENAME="$(basename ${FILE_PATH})"
195     FILE_ABS_PATH="$(cd ${FILE_PATH_DIRNAME} && pwd)"
196     FILE_PATH="${FILE_ABS_PATH}/${FILE_PATH_BASENAME}"
197     # This is the return value
198     ABSOLUTIFIED="${FILE_PATH}"
199 }
200
201 CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
202 CFG_SELF="$0"
203 CFG_ARGS="$@"
204
205 HELP=0
206 if [ "$1" = "--help" ]
207 then
208     HELP=1
209     shift
210     echo
211     echo "Usage: $CFG_SELF [options]"
212     echo
213     echo "Options:"
214     echo
215 else
216     step_msg "processing $CFG_SELF args"
217 fi
218
219 OPTIONS=""
220 BOOL_OPTIONS=""
221 VAL_OPTIONS=""
222
223 flag uninstall "only uninstall from the installation prefix"
224 opt verify 1 "verify that the installed binaries run correctly"
225 valopt prefix "/usr/local" "set installation prefix"
226 # NB This isn't quite the same definition as in `configure`.
227 # just using 'lib' instead of CFG_LIBDIR_RELATIVE
228 valopt libdir "${CFG_PREFIX}/lib" "install libraries"
229 valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
230
231 if [ $HELP -eq 1 ]
232 then
233     echo
234     exit 0
235 fi
236
237 step_msg "validating $CFG_SELF args"
238 validate_opt
239
240
241 # OK, let's get installing ...
242
243 # Sanity check: can we run the binaries?
244 if [ -z "${CFG_DISABLE_VERIFY}" ]
245 then
246     # Don't do this if uninstalling. Failure here won't help in any way.
247     if [ -z "${CFG_UNINSTALL}" ]
248     then
249         msg "verifying platform can run binaries"
250         "${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
251         if [ $? -ne 0 ]
252         then
253             err "can't execute rustc binary on this platform"
254         fi
255     fi
256 fi
257
258 # Sanity check: can we can write to the destination?
259 msg "verifying destination is writable"
260 umask 022 && mkdir -p "${CFG_LIBDIR}"
261 need_ok "can't write to destination. consider \`sudo\`."
262 touch "${CFG_LIBDIR}/rust-install-probe" > /dev/null
263 if [ $? -ne 0 ]
264 then
265     err "can't write to destination. consider \`sudo\`."
266 fi
267 rm -f "${CFG_LIBDIR}/rust-install-probe"
268 need_ok "failed to remove install probe"
269
270 # Sanity check: don't install to the directory containing the installer.
271 # That would surely cause chaos.
272 msg "verifying destination is not the same as source"
273 INSTALLER_DIR="$(cd $(dirname $0) && pwd)"
274 PREFIX_DIR="$(cd ${CFG_PREFIX} && pwd)"
275 if [ "${INSTALLER_DIR}" = "${PREFIX_DIR}" ]
276 then
277     err "can't install to same directory as installer"
278 fi
279
280 # Using an absolute path to libdir in a few places so that the status
281 # messages are consistently using absolute paths.
282 absolutify "${CFG_LIBDIR}"
283 ABS_LIBDIR="${ABSOLUTIFIED}"
284
285 # The file name of the manifest we're going to create during install
286 INSTALLED_MANIFEST="${ABS_LIBDIR}/rustlib/manifest"
287
288 # First, uninstall from the installation prefix.
289 # Errors are warnings - try to rm everything in the manifest even if some fail.
290 if [ -f "${INSTALLED_MANIFEST}" ]
291 then
292     # Iterate through installed manifest and remove files
293     while read p; do
294         # The installed manifest contains absolute paths
295         msg "removing $p"
296         if [ -f "$p" ]
297         then
298             rm -f "$p"
299             if [ $? -ne 0 ]
300             then
301                 warn "failed to remove $p"
302             fi
303         else
304             warn "supposedly installed file $p does not exist!"
305         fi
306     done < "${INSTALLED_MANIFEST}"
307
308     # If we fail to remove rustlib below, then the installed manifest will
309     # still be full; the installed manifest needs to be empty before install.
310     msg "removing ${INSTALLED_MANIFEST}"
311     rm -f "${INSTALLED_MANIFEST}"
312     # For the above reason, this is a hard error
313     need_ok "failed to remove installed manifest"
314
315     # Remove 'rustlib' directory
316     msg "removing ${ABS_LIBDIR}/rustlib"
317     rm -Rf "${ABS_LIBDIR}/rustlib"
318     if [ $? -ne 0 ]
319     then
320         warn "failed to remove rustlib"
321     fi
322 else
323     # There's no manifest. If we were asked to uninstall, then that's a problem.
324     if [ -n "${CFG_UNINSTALL}" ]
325     then
326         err "unable to find installation manifest at ${CFG_LIBDIR}/rustlib"
327     fi
328 fi
329
330 # If we're only uninstalling then exit
331 if [ -n "${CFG_UNINSTALL}" ]
332 then
333     echo
334     echo "    Rust is uninstalled. Have a nice day."
335     echo
336     exit 0
337 fi
338
339 # Create the installed manifest, which we will fill in with absolute file paths
340 mkdir -p "${CFG_LIBDIR}/rustlib"
341 need_ok "failed to create rustlib"
342 touch "${INSTALLED_MANIFEST}"
343 need_ok "failed to create installed manifest"
344
345 # Now install, iterate through the new manifest and copy files
346 while read p; do
347
348     # Decide the destination of the file
349     FILE_INSTALL_PATH="${CFG_PREFIX}/$p"
350
351     if echo "$p" | grep "^lib/" > /dev/null
352     then
353         pp=`echo $p | sed 's/^lib\///'`
354         FILE_INSTALL_PATH="${CFG_LIBDIR}/$pp"
355     fi
356
357     if echo "$p" | grep "^share/man/" > /dev/null
358     then
359         pp=`echo $p | sed 's/^share\/man\///'`
360         FILE_INSTALL_PATH="${CFG_MANDIR}/$pp"
361     fi
362
363     # Make sure there's a directory for it
364     umask 022 && mkdir -p "$(dirname ${FILE_INSTALL_PATH})"
365     need_ok "directory creation failed"
366
367     # Make the path absolute so we can uninstall it later without
368     # starting from the installation cwd
369     absolutify "${FILE_INSTALL_PATH}"
370     FILE_INSTALL_PATH="${ABSOLUTIFIED}"
371
372     # Install the file
373     msg "${FILE_INSTALL_PATH}"
374     if echo "$p" | grep "^bin/" > /dev/null
375     then
376         install -m755 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
377     else
378         install -m644 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
379     fi
380     need_ok "file creation failed"
381
382     # Update the manifest
383     echo "${FILE_INSTALL_PATH}" >> "${INSTALLED_MANIFEST}"
384     need_ok "failed to update manifest"
385
386 # The manifest lists all files to install
387 done < "${CFG_SRC_DIR}/lib/rustlib/manifest.in"
388
389 # Sanity check: can we run the installed binaries?
390 if [ -z "${CFG_DISABLE_VERIFY}" ]
391 then
392     msg "verifying installed binaries are executable"
393     "${CFG_PREFIX}/bin/rustc" --version > /dev/null
394     if [ $? -ne 0 ]
395     then
396         ERR="can't execute installed rustc binary. "
397         ERR="${ERR}installation may be broken. "
398         ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
399         ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
400         err "${ERR}"
401     fi
402 fi
403
404
405 echo
406 echo "    Rust is ready to roll."
407 echo
408
409