]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-installer/install-template.sh
New upstream version 1.22.1+dfsg1
[rustc.git] / src / tools / rust-installer / install-template.sh
1 #!/bin/bash
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 # No undefined variables
13 set -u
14
15 init_logging() {
16 local _abs_libdir="$1"
17 local _logfile="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/install.log"
18 rm -f "$_logfile"
19 need_ok "failed to remove old installation log"
20 touch "$_logfile"
21 need_ok "failed to create installation log"
22 LOGFILE="$_logfile"
23 }
24
25 log_line() {
26 local _line="$1"
27
28 if [ -n "${LOGFILE-}" -a -e "${LOGFILE-}" ]; then
29 echo "$_line" >> "$LOGFILE"
30 # Ignore errors, which may happen e.g. after the manifest dir is deleted
31 fi
32 }
33
34 msg() {
35 local _line="install: ${1-}"
36 echo "$_line"
37 log_line "$_line"
38 }
39
40 verbose_msg() {
41 if [ -n "${CFG_VERBOSE-}" ]; then
42 msg "${1-}"
43 else
44 log_line "install: ${1-}"
45 fi
46 }
47
48 step_msg() {
49 msg
50 msg "$1"
51 msg
52 }
53
54 verbose_step_msg() {
55 if [ -n "${CFG_VERBOSE-}" ]; then
56 msg
57 msg "$1"
58 msg
59 else
60 log_line ""
61 log_line "install: $1"
62 log_line ""
63 fi
64 }
65
66 warn() {
67 local _line="install: WARNING: $1"
68 echo "$_line" >&2
69 log_line "$_line"
70 }
71
72 err() {
73 local _line="install: error: $1"
74 echo "$_line" >&2
75 log_line "$_line"
76 exit 1
77 }
78
79 # A non-user error that is likely to result in a corrupted install
80 critical_err() {
81 local _line="install: error: $1. see logs at '${LOGFILE-}'"
82 echo "$_line" >&2
83 log_line "$_line"
84 exit 1
85 }
86
87 need_ok() {
88 if [ $? -ne 0 ]
89 then
90 err "$1"
91 fi
92 }
93
94 critical_need_ok() {
95 if [ $? -ne 0 ]
96 then
97 critical_err "$1"
98 fi
99 }
100
101 want_ok() {
102 if [ $? -ne 0 ]; then
103 warn "$1"
104 fi
105 }
106
107 assert_nz() {
108 if [ -z "$1" ]; then err "assert_nz $2"; fi
109 }
110
111 need_cmd() {
112 if command -v $1 >/dev/null 2>&1
113 then verbose_msg "found $1"
114 else err "need $1"
115 fi
116 }
117
118 run() {
119 local _line="\$ $*"
120 "$@"
121 local _retval=$?
122 log_line "$_line"
123 return $_retval
124 }
125
126 write_to_file() {
127 local _msg="$1"
128 local _file="$2"
129 local _line="$ echo \"$_msg\" > \"$_file\""
130 echo "$_msg" > "$_file"
131 local _retval=$?
132 log_line "$_line"
133 return $_retval
134 }
135
136 append_to_file() {
137 local _msg="$1"
138 local _file="$2"
139 local _line="$ echo \"$_msg\" >> \"$_file\""
140 echo "$_msg" >> "$_file"
141 local _retval=$?
142 log_line "$_line"
143 return $_retval
144 }
145
146 make_dir_recursive() {
147 local _dir="$1"
148 local _line="$ umask 022 && mkdir -p \"$_dir\""
149 umask 022 && mkdir -p "$_dir"
150 local _retval=$?
151 log_line "$_line"
152 return $_retval
153 }
154
155 putvar() {
156 local t
157 local tlen
158 eval t=\$$1
159 eval tlen=\${#$1}
160 }
161
162 valopt() {
163 VAL_OPTIONS="$VAL_OPTIONS $1"
164
165 local op=$1
166 local default=$2
167 shift
168 shift
169 local doc="$*"
170 if [ $HELP -eq 0 ]
171 then
172 local uop=$(echo $op | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
173 local v="CFG_${uop}"
174 eval $v="$default"
175 for arg in $CFG_ARGS
176 do
177 if echo "$arg" | grep -q -- "--$op="
178 then
179 local val=$(echo "$arg" | cut -f2 -d=)
180 eval $v=$val
181 fi
182 done
183 putvar $v
184 else
185 if [ -z "$default" ]
186 then
187 default="<none>"
188 fi
189 op="${op}=[${default}]"
190 printf " --%-30s %s\n" "$op" "$doc"
191 fi
192 }
193
194 opt() {
195 BOOL_OPTIONS="$BOOL_OPTIONS $1"
196
197 local op=$1
198 local default=$2
199 shift
200 shift
201 local doc="$*"
202 local flag=""
203
204 if [ $default -eq 0 ]
205 then
206 flag="enable"
207 else
208 flag="disable"
209 doc="don't $doc"
210 fi
211
212 if [ $HELP -eq 0 ]
213 then
214 for arg in $CFG_ARGS
215 do
216 if [ "$arg" = "--${flag}-${op}" ]
217 then
218 op=$(echo $op | tr 'a-z-' 'A-Z_')
219 flag=$(echo $flag | tr 'a-z' 'A-Z')
220 local v="CFG_${flag}_${op}"
221 eval $v=1
222 putvar $v
223 fi
224 done
225 else
226 if [ ! -z "${META-}" ]
227 then
228 op="$op=<$META>"
229 fi
230 printf " --%-30s %s\n" "$flag-$op" "$doc"
231 fi
232 }
233
234 flag() {
235 BOOL_OPTIONS="$BOOL_OPTIONS $1"
236
237 local op=$1
238 shift
239 local doc="$*"
240
241 if [ $HELP -eq 0 ]
242 then
243 for arg in $CFG_ARGS
244 do
245 if [ "$arg" = "--${op}" ]
246 then
247 op=$(echo $op | tr 'a-z-' 'A-Z_')
248 local v="CFG_${op}"
249 eval $v=1
250 putvar $v
251 fi
252 done
253 else
254 if [ ! -z "${META-}" ]
255 then
256 op="$op=<$META>"
257 fi
258 printf " --%-30s %s\n" "$op" "$doc"
259 fi
260 }
261
262 validate_opt () {
263 for arg in $CFG_ARGS
264 do
265 local is_arg_valid=0
266 for option in $BOOL_OPTIONS
267 do
268 if test --disable-$option = $arg
269 then
270 is_arg_valid=1
271 fi
272 if test --enable-$option = $arg
273 then
274 is_arg_valid=1
275 fi
276 if test --$option = $arg
277 then
278 is_arg_valid=1
279 fi
280 done
281 for option in $VAL_OPTIONS
282 do
283 if echo "$arg" | grep -q -- "--$option="
284 then
285 is_arg_valid=1
286 fi
287 done
288 if [ "$arg" = "--help" ]
289 then
290 echo
291 echo "No more help available for Configure options,"
292 echo "check the Wiki or join our IRC channel"
293 break
294 else
295 if test $is_arg_valid -eq 0
296 then
297 err "Option '$arg' is not recognized"
298 fi
299 fi
300 done
301 }
302
303 absolutify() {
304 local file_path="$1"
305 local file_path_dirname="$(dirname "$file_path")"
306 local file_path_basename="$(basename "$file_path")"
307 local file_abs_path="$(abs_path "$file_path_dirname")"
308 local file_path="$file_abs_path/$file_path_basename"
309 # This is the return value
310 RETVAL="$file_path"
311 }
312
313 # Prints the absolute path of a directory to stdout
314 abs_path() {
315 local path="$1"
316 # Unset CDPATH because it causes havok: it makes the destination unpredictable
317 # and triggers 'cd' to print the path to stdout. Route `cd`'s output to /dev/null
318 # for good measure.
319 (unset CDPATH && cd "$path" > /dev/null && pwd)
320 }
321
322 uninstall_legacy() {
323 local _abs_libdir="$1"
324
325 local _uninstalled_something=false
326
327 # Replace commas in legacy manifest list with spaces
328 _legacy_manifest_dirs=`echo "$TEMPLATE_LEGACY_MANIFEST_DIRS" | sed "s/,/ /g"`
329
330 # Uninstall from legacy manifests
331 local _md
332 for _md in $_legacy_manifest_dirs; do
333 # First, uninstall from the installation prefix.
334 # Errors are warnings - try to rm everything in the manifest even if some fail.
335 if [ -f "$_abs_libdir/$_md/manifest" ]
336 then
337
338 # iterate through installed manifest and remove files
339 local _p;
340 while read _p; do
341 # the installed manifest contains absolute paths
342 msg "removing legacy file $_p"
343 if [ -f "$_p" ]
344 then
345 run rm -f "$_p"
346 want_ok "failed to remove $_p"
347 else
348 warn "supposedly installed file $_p does not exist!"
349 fi
350 done < "$_abs_libdir/$_md/manifest"
351
352 # If we fail to remove $md below, then the
353 # installed manifest will still be full; the installed manifest
354 # needs to be empty before install.
355 msg "removing legacy manifest $_abs_libdir/$_md/manifest"
356 run rm -f "$_abs_libdir/$_md/manifest"
357 # For the above reason, this is a hard error
358 need_ok "failed to remove installed manifest"
359
360 # Remove $template_rel_manifest_dir directory
361 msg "removing legacy manifest dir $_abs_libdir/$_md"
362 run rm -R "$_abs_libdir/$_md"
363 want_ok "failed to remove $_md"
364
365 _uninstalled_something=true
366 fi
367 done
368
369 RETVAL="$_uninstalled_something"
370 }
371
372 uninstall_components() {
373 local _abs_libdir="$1"
374 local _dest_prefix="$2"
375 local _components="$3"
376
377 # We're going to start by uninstalling existing components. This
378 local _uninstalled_something=false
379
380 # First, try removing any 'legacy' manifests from before
381 # rust-installer
382 uninstall_legacy "$_abs_libdir"
383 assert_nz "$RETVAL", "RETVAL"
384 if [ "$RETVAL" = true ]; then
385 _uninstalled_something=true;
386 fi
387
388 # Load the version of the installed installer
389 local _installed_version=
390 if [ -f "$abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/rust-installer-version" ]; then
391 _installed_version=`cat "$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/rust-installer-version"`
392
393 # Sanity check
394 if [ ! -n "$_installed_version" ]; then critical_err "rust installer version is empty"; fi
395 fi
396
397 # If there's something installed, then uninstall
398 if [ -n "$_installed_version" ]; then
399 # Check the version of the installed installer
400 case "$_installed_version" in
401
402 # If this is a previous version, then upgrade in place to the
403 # current version before uninstalling.
404 2 )
405 # The only change between version 2 -> 3 is that components are placed
406 # in subdirectories of the installer tarball. There are no changes
407 # to the installed data format, so nothing to do.
408 ;;
409
410 # This is the current version. Nothing need to be done except uninstall.
411 "$TEMPLATE_RUST_INSTALLER_VERSION")
412 ;;
413
414 # If this is an unknown (future) version then bail.
415 * )
416 echo "The copy of $TEMPLATE_PRODUCT_NAME at $_dest_prefix was installed using an"
417 echo "unknown version ($_installed_version) of rust-installer."
418 echo "Uninstall it first with the installer used for the original installation"
419 echo "before continuing."
420 exit 1
421 ;;
422 esac
423
424 local _md="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
425 local _installed_components="$(cat "$_md/components")"
426
427 # Uninstall (our components only) before reinstalling
428 local _available_component
429 for _available_component in $_components; do
430 local _installed_component
431 for _installed_component in $_installed_components; do
432 if [ "$_available_component" = "$_installed_component" ]; then
433 msg "uninstalling component '$_available_component'"
434 local _component_manifest="$_md/manifest-$_installed_component"
435
436 # Sanity check: there should be a component manifest
437 if [ ! -f "$_component_manifest" ]; then
438 critical_err "installed component '$_installed_component' has no manifest"
439 fi
440
441 # Iterate through installed component manifest and remove files
442 local _directive
443 while read _directive; do
444
445 local _command=`echo $_directive | cut -f1 -d:`
446 local _file=`echo $_directive | cut -f2 -d:`
447
448 # Sanity checks
449 if [ ! -n "$_command" ]; then critical_err "malformed installation directive"; fi
450 if [ ! -n "$_file" ]; then critical_err "malformed installation directive"; fi
451
452 case "$_command" in
453 file)
454 verbose_msg "removing file $_file"
455 if [ -f "$_file" ]; then
456 run rm -f "$_file"
457 want_ok "failed to remove $_file"
458 else
459 warn "supposedly installed file $_file does not exist!"
460 fi
461 ;;
462
463 dir)
464 verbose_msg "removing directory $_file"
465 run rm -r "$_file"
466 want_ok "unable to remove directory $_file"
467 ;;
468
469 *)
470 critical_err "unknown installation directive"
471 ;;
472 esac
473
474 done < "$_component_manifest"
475
476 # Remove the installed component manifest
477 verbose_msg "removing component manifest $_component_manifest"
478 run rm "$_component_manifest"
479 # This is a hard error because the installation is unrecoverable
480 critical_need_ok "failed to remove installed manifest for component '$_installed_component'"
481
482 # Update the installed component list
483 local _modified_components="$(sed "/^$_installed_component\$/d" "$_md/components")"
484 write_to_file "$_modified_components" "$_md/components"
485 critical_need_ok "failed to update installed component list"
486 fi
487 done
488 done
489
490 # If there are no remaining components delete the manifest directory,
491 # but only if we're doing an uninstall - if we're doing an install,
492 # then leave the manifest directory around to hang onto the logs,
493 # and any files not managed by the installer.
494 if [ -n "${CFG_UNINSTALL-}" ]; then
495 local _remaining_components="$(cat "$_md/components")"
496 if [ ! -n "$_remaining_components" ]; then
497 verbose_msg "removing manifest directory $_md"
498 run rm -r "$_md"
499 want_ok "failed to remove $_md"
500
501 maybe_unconfigure_ld
502 fi
503 fi
504
505 _uninstalled_something=true
506 fi
507
508 # There's no installed version. If we were asked to uninstall, then that's a problem.
509 if [ -n "${CFG_UNINSTALL-}" -a "$_uninstalled_something" = false ]
510 then
511 err "unable to find installation manifest at $CFG_LIBDIR/$TEMPLATE_REL_MANIFEST_DIR"
512 fi
513 }
514
515 install_components() {
516 local _src_dir="$1"
517 local _abs_libdir="$2"
518 local _dest_prefix="$3"
519 local _components="$4"
520
521 local _component
522 for _component in $_components; do
523
524 msg "installing component '$_component'"
525
526 # The file name of the manifest we're installing from
527 local _input_manifest="$_src_dir/$_component/manifest.in"
528
529 # Sanity check: do we have our input manifests?
530 if [ ! -f "$_input_manifest" ]; then
531 critical_err "manifest for $_component does not exist at $_input_manifest"
532 fi
533
534 # The installed manifest directory
535 local _md="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
536
537 # The file name of the manifest we're going to create during install
538 local _installed_manifest="$_md/manifest-$_component"
539
540 # Create the installed manifest, which we will fill in with absolute file paths
541 touch "$_installed_manifest"
542 critical_need_ok "failed to create installed manifest"
543
544 # Add this component to the installed component list
545 append_to_file "$_component" "$_md/components"
546 critical_need_ok "failed to update components list for $_component"
547
548 # Now install, iterate through the new manifest and copy files
549 local _directive
550 while read _directive; do
551
552 local _command=`echo $_directive | cut -f1 -d:`
553 local _file=`echo $_directive | cut -f2 -d:`
554
555 # Sanity checks
556 if [ ! -n "$_command" ]; then critical_err "malformed installation directive"; fi
557 if [ ! -n "$_file" ]; then critical_err "malformed installation directive"; fi
558
559 # Decide the destination of the file
560 local _file_install_path="$_dest_prefix/$_file"
561
562 if echo "$_file" | grep "^etc/" > /dev/null
563 then
564 local _f="$(echo "$_file" | sed 's/^etc\///')"
565 _file_install_path="$CFG_SYSCONFDIR/$_f"
566 fi
567
568 if echo "$_file" | grep "^bin/" > /dev/null
569 then
570 local _f="$(echo "$_file" | sed 's/^bin\///')"
571 _file_install_path="$CFG_BINDIR/$_f"
572 fi
573
574 if echo "$_file" | grep "^lib/" > /dev/null
575 then
576 local _f="$(echo "$_file" | sed 's/^lib\///')"
577 _file_install_path="$CFG_LIBDIR/$_f"
578 fi
579
580 if echo "$_file" | grep "^share/man/" > /dev/null
581 then
582 local _f="$(echo "$_file" | sed 's/^share\/man\///')"
583 _file_install_path="$CFG_MANDIR/$_f"
584 fi
585
586 # HACK: Try to support overriding --docdir. Paths with the form
587 # "share/doc/$product/" can be redirected to a single --docdir
588 # path. If the following detects that --docdir has been specified
589 # then it will replace everything preceeding the "$product" path
590 # component. The problem here is that the combined rust installer
591 # contains two "products": rust and cargo; so the contents of those
592 # directories will both be dumped into the same directory; and the
593 # contents of those directories are _not_ disjoint. Since this feature
594 # is almost entirely to support 'make install' anyway I don't expect
595 # this problem to be a big deal in practice.
596 if [ "$CFG_DOCDIR" != "<default>" ]
597 then
598 if echo "$_file" | grep "^share/doc/" > /dev/null
599 then
600 local _f="$(echo "$_file" | sed 's/^share\/doc\/[^/]*\///')"
601 _file_install_path="$CFG_DOCDIR/$_f"
602 fi
603 fi
604
605 # Make sure there's a directory for it
606 make_dir_recursive "$(dirname "$_file_install_path")"
607 critical_need_ok "directory creation failed"
608
609 # Make the path absolute so we can uninstall it later without
610 # starting from the installation cwd
611 absolutify "$_file_install_path"
612 _file_install_path="$RETVAL"
613 assert_nz "$_file_install_path" "file_install_path"
614
615 case "$_command" in
616 file )
617
618 verbose_msg "copying file $_file_install_path"
619
620 maybe_backup_path "$_file_install_path"
621
622 if echo "$_file" | grep "^bin/" > /dev/null || test -x "$_src_dir/$_component/$_file"
623 then
624 run cp "$_src_dir/$_component/$_file" "$_file_install_path"
625 run chmod 755 "$_file_install_path"
626 else
627 run cp "$_src_dir/$_component/$_file" "$_file_install_path"
628 run chmod 644 "$_file_install_path"
629 fi
630 critical_need_ok "file creation failed"
631
632 # Update the manifest
633 append_to_file "file:$_file_install_path" "$_installed_manifest"
634 critical_need_ok "failed to update manifest"
635
636 ;;
637
638 dir )
639
640 verbose_msg "copying directory $_file_install_path"
641
642 maybe_backup_path "$_file_install_path"
643
644 run cp -R "$_src_dir/$_component/$_file" "$_file_install_path"
645 critical_need_ok "failed to copy directory"
646
647 # Set permissions. 0755 for dirs, 644 for files
648 run chmod -R u+rwX,go+rX,go-w "$_file_install_path"
649 critical_need_ok "failed to set permissions on directory"
650
651 # Update the manifest
652 append_to_file "dir:$_file_install_path" "$_installed_manifest"
653 critical_need_ok "failed to update manifest"
654 ;;
655
656 *)
657 critical_err "unknown installation directive"
658 ;;
659 esac
660 done < "$_input_manifest"
661
662 done
663 }
664
665 maybe_configure_ld() {
666 local _abs_libdir="$1"
667
668 local _ostype="$(uname -s)"
669 assert_nz "$_ostype" "ostype"
670
671 if [ "$_ostype" = "Linux" -a ! -n "${CFG_DISABLE_LDCONFIG-}" ]; then
672
673 # Fedora-based systems do not configure the dynamic linker to look
674 # /usr/local/lib, which is our default installation directory. To
675 # make things just work, try to put that directory in
676 # /etc/ld.so.conf.d/rust-installer-v1 so ldconfig picks it up.
677 # Issue #30.
678 #
679 # This will get rm'd when the last component is uninstalled in
680 # maybe_unconfigure_ld.
681 if [ "$_abs_libdir" = "/usr/local/lib" -a -d "/etc/ld.so.conf.d" ]; then
682 echo "$_abs_libdir" > "/etc/ld.so.conf.d/rust-installer-v1-$TEMPLATE_REL_MANIFEST_DIR.conf"
683 if [ $? -ne 0 ]; then
684 # This shouldn't happen if we've gotten this far
685 # installing to /usr/local
686 warn "failed to update /etc/ld.so.conf.d. this is unexpected"
687 fi
688 fi
689
690 verbose_msg "running ldconfig"
691 if [ -n "${CFG_VERBOSE-}" ]; then
692 ldconfig
693 else
694 ldconfig 2> /dev/null
695 fi
696 if [ $? -ne 0 ]
697 then
698 warn "failed to run ldconfig. this may happen when not installing as root. run with --verbose to see the error"
699 fi
700 fi
701 }
702
703 maybe_unconfigure_ld() {
704 local _ostype="$(uname -s)"
705 assert_nz "$_ostype" "ostype"
706
707 if [ "$_ostype" != "Linux" ]; then
708 return 0
709 fi
710
711 rm "/etc/ld.so.conf.d/rust-installer-v1-$TEMPLATE_REL_MANIFEST_DIR.conf" 2> /dev/null
712 # Above may fail since that file may not have been created on install
713 }
714
715 # Doing our own 'install'-like backup that is consistent across platforms
716 maybe_backup_path() {
717 local _file_install_path="$1"
718
719 if [ -e "$_file_install_path" ]; then
720 msg "backing up existing file at $_file_install_path"
721 run mv -f "$_file_install_path" "$_file_install_path.old"
722 critical_need_ok "failed to back up $_file_install_path"
723 fi
724 }
725
726 install_uninstaller() {
727 local _src_dir="$1"
728 local _src_basename="$2"
729 local _abs_libdir="$3"
730
731 local _uninstaller="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/uninstall.sh"
732 msg "creating uninstall script at $_uninstaller"
733 run cp "$_src_dir/$_src_basename" "$_uninstaller"
734 critical_need_ok "unable to install uninstaller"
735 }
736
737 do_preflight_sanity_checks() {
738 local _src_dir="$1"
739 local _dest_prefix="$2"
740
741 # Sanity check: can we can write to the destination?
742 verbose_msg "verifying destination is writable"
743 make_dir_recursive "$CFG_LIBDIR"
744 need_ok "can't write to destination. consider \`sudo\`."
745 touch "$CFG_LIBDIR/rust-install-probe" > /dev/null
746 if [ $? -ne 0 ]
747 then
748 err "can't write to destination. consider \`sudo\`."
749 fi
750 rm "$CFG_LIBDIR/rust-install-probe"
751 need_ok "failed to remove install probe"
752
753 # Sanity check: don't install to the directory containing the installer.
754 # That would surely cause chaos.
755 verbose_msg "verifying destination is not the same as source"
756 local _prefix_dir="$(abs_path "$dest_prefix")"
757 if [ "$_src_dir" = "$_dest_prefix" -a "${CFG_UNINSTALL-}" != 1 ]; then
758 err "cannot install to same directory as installer"
759 fi
760 }
761
762 verbose_msg "looking for install programs"
763 verbose_msg
764
765 need_cmd mkdir
766 need_cmd printf
767 need_cmd cut
768 need_cmd grep
769 need_cmd uname
770 need_cmd tr
771 need_cmd sed
772 need_cmd chmod
773 need_cmd env
774 need_cmd pwd
775
776 CFG_ARGS="${@:-}"
777
778 HELP=0
779 if [ "${1-}" = "--help" ]
780 then
781 HELP=1
782 shift
783 echo
784 echo "Usage: $0 [options]"
785 echo
786 echo "Options:"
787 echo
788 else
789 verbose_step_msg "processing arguments"
790 fi
791
792 OPTIONS=""
793 BOOL_OPTIONS=""
794 VAL_OPTIONS=""
795
796 flag uninstall "only uninstall from the installation prefix"
797 valopt destdir "" "set installation root"
798 valopt prefix "/usr/local" "set installation prefix"
799
800 # Avoid prepending an extra / to the prefix path if there's no destdir
801 # NB: CFG vars here are undefined when passing --help
802 if [ -z "${CFG_DESTDIR-}" ]; then
803 CFG_DESTDIR_PREFIX="${CFG_PREFIX-}"
804 else
805 CFG_DESTDIR_PREFIX="$CFG_DESTDIR/$CFG_PREFIX"
806 fi
807
808 # NB This isn't quite the same definition as in `configure`.
809 # just using 'lib' instead of configure's CFG_LIBDIR_RELATIVE
810 valopt without "" "comma-separated list of components to not install"
811 valopt components "" "comma-separated list of components to install"
812 flag list-components "list available components"
813 valopt sysconfdir "$CFG_DESTDIR_PREFIX/etc" "install system configuration files"
814 valopt bindir "$CFG_DESTDIR_PREFIX/bin" "install binaries"
815 valopt libdir "$CFG_DESTDIR_PREFIX/lib" "install libraries"
816 valopt mandir "$CFG_DESTDIR_PREFIX/share/man" "install man pages in PATH"
817 # NB See the docdir handling in install_components for an explanation of this
818 # weird <default> string
819 valopt docdir "\<default\>" "install documentation in PATH"
820 opt ldconfig 1 "run ldconfig after installation (Linux only)"
821 opt verify 1 "obsolete"
822 flag verbose "run with verbose output"
823
824 if [ $HELP -eq 1 ]
825 then
826 echo
827 exit 0
828 fi
829
830 verbose_step_msg "validating arguments"
831 validate_opt
832
833 # Template configuration.
834 # These names surrounded by '%%` are replaced by sed when generating install.sh
835 # FIXME: Might want to consider loading this from a file and not generating install.sh
836
837 # Rust or Cargo
838 TEMPLATE_PRODUCT_NAME=%%TEMPLATE_PRODUCT_NAME%%
839 # rustlib or cargo
840 TEMPLATE_REL_MANIFEST_DIR=%%TEMPLATE_REL_MANIFEST_DIR%%
841 # 'Rust is ready to roll.' or 'Cargo is cool to cruise.'
842 TEMPLATE_SUCCESS_MESSAGE=%%TEMPLATE_SUCCESS_MESSAGE%%
843 # Locations to look for directories containing legacy, pre-versioned manifests
844 TEMPLATE_LEGACY_MANIFEST_DIRS=%%TEMPLATE_LEGACY_MANIFEST_DIRS%%
845 # The installer version
846 TEMPLATE_RUST_INSTALLER_VERSION=%%TEMPLATE_RUST_INSTALLER_VERSION%%
847
848 # OK, let's get installing ...
849
850 # This is where we are installing from
851 src_dir="$(abs_path $(dirname "$0"))"
852
853 # The name of the script
854 src_basename="$(basename "$0")"
855
856 # If we've been run as 'uninstall.sh' (from the existing installation)
857 # then we're doing a full uninstall, as opposed to the --uninstall flag
858 # which just means 'uninstall my components'.
859 if [ "$src_basename" = "uninstall.sh" ]; then
860 if [ "${*:-}" != "" ]; then
861 # Currently don't know what to do with arguments in this mode
862 err "uninstall.sh does not take any arguments"
863 fi
864 CFG_UNINSTALL=1
865 CFG_DESTDIR_PREFIX="$(abs_path "$src_dir/../../")"
866 CFG_LIBDIR="$(abs_path "$src_dir/../")"
867 fi
868
869 # This is where we are installing to
870 dest_prefix="$CFG_DESTDIR_PREFIX"
871
872 # Open the components file to get the list of components to install.
873 # NB: During install this components file is read from the installer's
874 # source dir, during a full uninstall it's read from the manifest dir,
875 # and thus contains all installed components.
876 components=`cat "$src_dir/components"`
877
878 # Sanity check: do we have components?
879 if [ ! -n "$components" ]; then
880 err "unable to find installation components"
881 fi
882
883 # If the user asked for a component list, do that and exit
884 if [ -n "${CFG_LIST_COMPONENTS-}" ]; then
885 echo
886 echo "# Available components"
887 echo
888 for component in $components; do
889 echo "* $component"
890 done
891 echo
892 exit 0
893 fi
894
895 # If the user specified which components to install/uninstall,
896 # then validate that they exist and select them for installation
897 if [ -n "$CFG_COMPONENTS" ]; then
898 # Remove commas
899 user_components="$(echo "$CFG_COMPONENTS" | sed "s/,/ /g")"
900 for user_component in $user_components; do
901 found=false
902 for my_component in $components; do
903 if [ "$user_component" = "$my_component" ]; then
904 found=true
905 fi
906 done
907 if [ "$found" = false ]; then
908 err "unknown component: $user_component"
909 fi
910 done
911 components="$user_components"
912 fi
913
914 if [ -n "$CFG_WITHOUT" ]; then
915 without_components="$(echo "$CFG_WITHOUT" | sed "s/,/ /g")"
916 for without_component in $without_components; do
917 components="$(echo "$components" | sed "s/$without_component//" | sed "s/$without_component//")"
918 done
919 fi
920
921 if [ -z "$components" ]; then
922 if [ -z "${CFG_UNINSTALL-}" ]; then
923 err "no components selected for installation"
924 else
925 err "no components selected for uninstallation"
926 fi
927 fi
928
929 do_preflight_sanity_checks "$src_dir" "$dest_prefix"
930
931 # Using an absolute path to libdir in a few places so that the status
932 # messages are consistently using absolute paths.
933 absolutify "$CFG_LIBDIR"
934 abs_libdir="$RETVAL"
935 assert_nz "$abs_libdir" "abs_libdir"
936
937 # Create the manifest directory, where we will put our logs
938 make_dir_recursive "$abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
939 need_ok "failed to create $TEMPLATE_REL_MANIFEST_DIR"
940
941 # Log messages and commands
942 init_logging "$abs_libdir"
943
944 # First do any uninstallation, including from legacy manifests. This
945 # will also upgrade the metadata of existing installs.
946 uninstall_components "$abs_libdir" "$dest_prefix" "$components"
947
948 # If we're only uninstalling then exit
949 if [ -n "${CFG_UNINSTALL-}" ]
950 then
951 echo
952 echo " $TEMPLATE_PRODUCT_NAME is uninstalled."
953 echo
954 exit 0
955 fi
956
957 # Create the manifest directory again! uninstall_legacy
958 # may have deleted it.
959 make_dir_recursive "$abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
960 need_ok "failed to create $TEMPLATE_REL_MANIFEST_DIR"
961
962 # Drop the version number into the manifest dir
963 write_to_file "$TEMPLATE_RUST_INSTALLER_VERSION" "$abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/rust-installer-version"
964 critical_need_ok "failed to write installer version"
965
966 # Install the uninstaller
967 install_uninstaller "$src_dir" "$src_basename" "$abs_libdir"
968
969 # Install each component
970 install_components "$src_dir" "$abs_libdir" "$dest_prefix" "$components"
971
972 # Make dynamic libraries available to the linker
973 maybe_configure_ld "$abs_libdir"
974
975 echo
976 echo " $TEMPLATE_SUCCESS_MESSAGE"
977 echo
978
979