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