]> git.lizzy.rs Git - rust.git/blob - src/etc/install.sh
install: Correct libdir for Windows installs.
[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 need_cmd() {
39     if command -v $1 >/dev/null 2>&1
40     then msg "found $1"
41     else err "need $1"
42     fi
43 }
44
45 putvar() {
46     local T
47     eval T=\$$1
48     eval TLEN=\${#$1}
49     if [ $TLEN -gt 35 ]
50     then
51         printf "install: %-20s := %.35s ...\n" $1 "$T"
52     else
53         printf "install: %-20s := %s %s\n" $1 "$T" "$2"
54     fi
55 }
56
57 valopt() {
58     VAL_OPTIONS="$VAL_OPTIONS $1"
59
60     local OP=$1
61     local DEFAULT=$2
62     shift
63     shift
64     local DOC="$*"
65     if [ $HELP -eq 0 ]
66     then
67         local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
68         local V="CFG_${UOP}"
69         eval $V="$DEFAULT"
70         for arg in $CFG_ARGS
71         do
72             if echo "$arg" | grep -q -- "--$OP="
73             then
74                 val=$(echo "$arg" | cut -f2 -d=)
75                 eval $V=$val
76             fi
77         done
78         putvar $V
79     else
80         if [ -z "$DEFAULT" ]
81         then
82             DEFAULT="<none>"
83         fi
84         OP="${OP}=[${DEFAULT}]"
85         printf "    --%-30s %s\n" "$OP" "$DOC"
86     fi
87 }
88
89 opt() {
90     BOOL_OPTIONS="$BOOL_OPTIONS $1"
91
92     local OP=$1
93     local DEFAULT=$2
94     shift
95     shift
96     local DOC="$*"
97     local FLAG=""
98
99     if [ $DEFAULT -eq 0 ]
100     then
101         FLAG="enable"
102     else
103         FLAG="disable"
104         DOC="don't $DOC"
105     fi
106
107     if [ $HELP -eq 0 ]
108     then
109         for arg in $CFG_ARGS
110         do
111             if [ "$arg" = "--${FLAG}-${OP}" ]
112             then
113                 OP=$(echo $OP | tr 'a-z-' 'A-Z_')
114                 FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
115                 local V="CFG_${FLAG}_${OP}"
116                 eval $V=1
117                 putvar $V
118             fi
119         done
120     else
121         if [ ! -z "$META" ]
122         then
123             OP="$OP=<$META>"
124         fi
125         printf "    --%-30s %s\n" "$FLAG-$OP" "$DOC"
126      fi
127 }
128
129 flag() {
130     BOOL_OPTIONS="$BOOL_OPTIONS $1"
131
132     local OP=$1
133     shift
134     local DOC="$*"
135
136     if [ $HELP -eq 0 ]
137     then
138         for arg in $CFG_ARGS
139         do
140             if [ "$arg" = "--${OP}" ]
141             then
142                 OP=$(echo $OP | tr 'a-z-' 'A-Z_')
143                 local V="CFG_${OP}"
144                 eval $V=1
145                 putvar $V
146             fi
147         done
148     else
149         if [ ! -z "$META" ]
150         then
151             OP="$OP=<$META>"
152         fi
153         printf "    --%-30s %s\n" "$OP" "$DOC"
154      fi
155 }
156
157 validate_opt () {
158     for arg in $CFG_ARGS
159     do
160         isArgValid=0
161         for option in $BOOL_OPTIONS
162         do
163             if test --disable-$option = $arg
164             then
165                 isArgValid=1
166             fi
167             if test --enable-$option = $arg
168             then
169                 isArgValid=1
170             fi
171             if test --$option = $arg
172             then
173                 isArgValid=1
174             fi
175         done
176         for option in $VAL_OPTIONS
177         do
178             if echo "$arg" | grep -q -- "--$option="
179             then
180                 isArgValid=1
181             fi
182         done
183         if [ "$arg" = "--help" ]
184         then
185             echo
186             echo "No more help available for Configure options,"
187             echo "check the Wiki or join our IRC channel"
188             break
189         else
190             if test $isArgValid -eq 0
191             then
192                 err "Option '$arg' is not recognized"
193             fi
194         fi
195     done
196 }
197
198 absolutify() {
199     FILE_PATH="${1}"
200     FILE_PATH_DIRNAME="$(dirname ${FILE_PATH})"
201     FILE_PATH_BASENAME="$(basename ${FILE_PATH})"
202     FILE_ABS_PATH="$(cd ${FILE_PATH_DIRNAME} && pwd)"
203     FILE_PATH="${FILE_ABS_PATH}/${FILE_PATH_BASENAME}"
204     # This is the return value
205     ABSOLUTIFIED="${FILE_PATH}"
206 }
207
208 msg "looking for install programs"
209 need_cmd mkdir
210 need_cmd printf
211 need_cmd cut
212 need_cmd grep
213 need_cmd uname
214 need_cmd tr
215 need_cmd sed
216
217 CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
218 CFG_SELF="$0"
219 CFG_ARGS="$@"
220
221 HELP=0
222 if [ "$1" = "--help" ]
223 then
224     HELP=1
225     shift
226     echo
227     echo "Usage: $CFG_SELF [options]"
228     echo
229     echo "Options:"
230     echo
231 else
232     step_msg "processing $CFG_SELF args"
233 fi
234
235 # Check for mingw or cygwin in order to special case $CFG_LIBDIR_RELATIVE.
236 # This logic is duplicated from configure in order to get the correct libdir
237 # for Windows installs.
238 CFG_OSTYPE=$(uname -s)
239
240 case $CFG_OSTYPE in
241
242     MINGW32*)
243         CFG_OSTYPE=pc-mingw32
244         ;;
245
246     MINGW64*)
247         # msys2, MSYSTEM=MINGW64
248         CFG_OSTYPE=w64-mingw32
249         ;;
250
251 # Thad's Cygwin identifers below
252
253 #   Vista 32 bit
254     CYGWIN_NT-6.0)
255         CFG_OSTYPE=pc-mingw32
256         ;;
257
258 #   Vista 64 bit
259     CYGWIN_NT-6.0-WOW64)
260         CFG_OSTYPE=w64-mingw32
261         ;;
262
263 #   Win 7 32 bit
264     CYGWIN_NT-6.1)
265         CFG_OSTYPE=pc-mingw32
266         ;;
267
268 #   Win 7 64 bit
269     CYGWIN_NT-6.1-WOW64)
270         CFG_OSTYPE=w64-mingw32
271         ;;
272 esac
273
274 OPTIONS=""
275 BOOL_OPTIONS=""
276 VAL_OPTIONS=""
277
278 # On windows we just store the libraries in the bin directory because
279 # there's no rpath. This is where the build system itself puts libraries;
280 # --libdir is used to configure the installation directory.
281 # FIXME: Thise needs to parameterized over target triples. Do it in platform.mk
282 CFG_LIBDIR_RELATIVE=lib
283 if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
284 then
285     CFG_LIBDIR_RELATIVE=bin
286 fi
287
288 flag uninstall "only uninstall from the installation prefix"
289 opt verify 1 "verify that the installed binaries run correctly"
290 valopt prefix "/usr/local" "set installation prefix"
291 # NB This isn't quite the same definition as in `configure`.
292 # just using 'lib' instead of CFG_LIBDIR_RELATIVE
293 valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries"
294 valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
295
296 if [ $HELP -eq 1 ]
297 then
298     echo
299     exit 0
300 fi
301
302 step_msg "validating $CFG_SELF args"
303 validate_opt
304
305
306 # OK, let's get installing ...
307
308 # Sanity check: can we run the binaries?
309 if [ -z "${CFG_DISABLE_VERIFY}" ]
310 then
311     # Don't do this if uninstalling. Failure here won't help in any way.
312     if [ -z "${CFG_UNINSTALL}" ]
313     then
314         msg "verifying platform can run binaries"
315         "${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
316         if [ $? -ne 0 ]
317         then
318             err "can't execute rustc binary on this platform"
319         fi
320     fi
321 fi
322
323 # Sanity check: can we can write to the destination?
324 msg "verifying destination is writable"
325 umask 022 && mkdir -p "${CFG_LIBDIR}"
326 need_ok "can't write to destination. consider \`sudo\`."
327 touch "${CFG_LIBDIR}/rust-install-probe" > /dev/null
328 if [ $? -ne 0 ]
329 then
330     err "can't write to destination. consider \`sudo\`."
331 fi
332 rm -f "${CFG_LIBDIR}/rust-install-probe"
333 need_ok "failed to remove install probe"
334
335 # Sanity check: don't install to the directory containing the installer.
336 # That would surely cause chaos.
337 msg "verifying destination is not the same as source"
338 INSTALLER_DIR="$(cd $(dirname $0) && pwd)"
339 PREFIX_DIR="$(cd ${CFG_PREFIX} && pwd)"
340 if [ "${INSTALLER_DIR}" = "${PREFIX_DIR}" ]
341 then
342     err "can't install to same directory as installer"
343 fi
344
345 # Using an absolute path to libdir in a few places so that the status
346 # messages are consistently using absolute paths.
347 absolutify "${CFG_LIBDIR}"
348 ABS_LIBDIR="${ABSOLUTIFIED}"
349
350 # The file name of the manifest we're going to create during install
351 INSTALLED_MANIFEST="${ABS_LIBDIR}/rustlib/manifest"
352
353 # First, uninstall from the installation prefix.
354 # Errors are warnings - try to rm everything in the manifest even if some fail.
355 if [ -f "${INSTALLED_MANIFEST}" ]
356 then
357     # Iterate through installed manifest and remove files
358     while read p; do
359         # The installed manifest contains absolute paths
360         msg "removing $p"
361         if [ -f "$p" ]
362         then
363             rm -f "$p"
364             if [ $? -ne 0 ]
365             then
366                 warn "failed to remove $p"
367             fi
368         else
369             warn "supposedly installed file $p does not exist!"
370         fi
371     done < "${INSTALLED_MANIFEST}"
372
373     # If we fail to remove rustlib below, then the installed manifest will
374     # still be full; the installed manifest needs to be empty before install.
375     msg "removing ${INSTALLED_MANIFEST}"
376     rm -f "${INSTALLED_MANIFEST}"
377     # For the above reason, this is a hard error
378     need_ok "failed to remove installed manifest"
379
380     # Remove 'rustlib' directory
381     msg "removing ${ABS_LIBDIR}/rustlib"
382     rm -Rf "${ABS_LIBDIR}/rustlib"
383     if [ $? -ne 0 ]
384     then
385         warn "failed to remove rustlib"
386     fi
387 else
388     # There's no manifest. If we were asked to uninstall, then that's a problem.
389     if [ -n "${CFG_UNINSTALL}" ]
390     then
391         err "unable to find installation manifest at ${CFG_LIBDIR}/rustlib"
392     fi
393 fi
394
395 # If we're only uninstalling then exit
396 if [ -n "${CFG_UNINSTALL}" ]
397 then
398     echo
399     echo "    Rust is uninstalled. Have a nice day."
400     echo
401     exit 0
402 fi
403
404 # Create the installed manifest, which we will fill in with absolute file paths
405 mkdir -p "${CFG_LIBDIR}/rustlib"
406 need_ok "failed to create rustlib"
407 touch "${INSTALLED_MANIFEST}"
408 need_ok "failed to create installed manifest"
409
410 # Now install, iterate through the new manifest and copy files
411 while read p; do
412
413     # Decide the destination of the file
414     FILE_INSTALL_PATH="${CFG_PREFIX}/$p"
415
416     if echo "$p" | grep "^lib/" > /dev/null
417     then
418         pp=`echo $p | sed 's/^lib\///'`
419         FILE_INSTALL_PATH="${CFG_LIBDIR}/$pp"
420     fi
421
422     if echo "$p" | grep "^share/man/" > /dev/null
423     then
424         pp=`echo $p | sed 's/^share\/man\///'`
425         FILE_INSTALL_PATH="${CFG_MANDIR}/$pp"
426     fi
427
428     # Make sure there's a directory for it
429     umask 022 && mkdir -p "$(dirname ${FILE_INSTALL_PATH})"
430     need_ok "directory creation failed"
431
432     # Make the path absolute so we can uninstall it later without
433     # starting from the installation cwd
434     absolutify "${FILE_INSTALL_PATH}"
435     FILE_INSTALL_PATH="${ABSOLUTIFIED}"
436
437     # Install the file
438     msg "${FILE_INSTALL_PATH}"
439     if echo "$p" | grep "^bin/" > /dev/null
440     then
441         install -m755 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
442     else
443         install -m644 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}"
444     fi
445     need_ok "file creation failed"
446
447     # Update the manifest
448     echo "${FILE_INSTALL_PATH}" >> "${INSTALLED_MANIFEST}"
449     need_ok "failed to update manifest"
450
451 # The manifest lists all files to install
452 done < "${CFG_SRC_DIR}/${CFG_LIBDIR_RELATIVE}/rustlib/manifest.in"
453
454 # Sanity check: can we run the installed binaries?
455 if [ -z "${CFG_DISABLE_VERIFY}" ]
456 then
457     msg "verifying installed binaries are executable"
458     "${CFG_PREFIX}/bin/rustc" --version > /dev/null
459     if [ $? -ne 0 ]
460     then
461         ERR="can't execute installed rustc binary. "
462         ERR="${ERR}installation may be broken. "
463         ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
464         ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
465         err "${ERR}"
466     fi
467 fi
468
469
470 echo
471 echo "    Rust is ready to roll."
472 echo
473
474