3 # No undefined variables
8 local _logfile
="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR/install.log"
10 need_ok
"failed to remove old installation log"
12 need_ok
"failed to create installation log"
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
26 local _line
="install: ${1-}"
32 if [ -n "${CFG_VERBOSE-}" ]; then
35 log_line
"install: ${1-}"
46 if [ -n "${CFG_VERBOSE-}" ]; then
52 log_line
"install: $1"
58 local _line
="install: WARNING: $1"
64 local _line
="install: error: $1"
70 # A non-user error that is likely to result in a corrupted install
72 local _line
="install: error: $1. see logs at '${LOGFILE-}'"
99 if [ -z "$1" ]; then err
"assert_nz $2"; fi
103 if command -v $1 >/dev
/null
2>&1
104 then verbose_msg
"found $1"
120 local _line
="$ echo \"$_msg\" > \"$_file\""
121 echo "$_msg" > "$_file"
130 local _line
="$ echo \"$_msg\" >> \"$_file\""
131 echo "$_msg" >> "$_file"
137 make_dir_recursive
() {
139 local _line
="$ umask 022 && mkdir -p \"$_dir\""
140 umask 022 && mkdir
-p "$_dir"
154 VAL_OPTIONS
="$VAL_OPTIONS $1"
163 local uop
=$
(echo $op |
tr 'a-z-' 'A-Z_')
168 if echo "$arg" |
grep -q -- "--$op="
170 local val
=$
(echo "$arg" | cut
-f2 -d=)
180 op
="${op}=[${default}]"
181 printf " --%-30s %s\n" "$op" "$doc"
186 BOOL_OPTIONS
="$BOOL_OPTIONS $1"
195 if [ $default -eq 0 ]
207 if [ "$arg" = "--${flag}-${op}" ]
209 op
=$
(echo $op |
tr 'a-z-' 'A-Z_')
210 flag
=$
(echo $flag |
tr 'a-z' 'A-Z')
211 local v
="CFG_${flag}_${op}"
217 if [ ! -z "${META-}" ]
221 printf " --%-30s %s\n" "$flag-$op" "$doc"
226 BOOL_OPTIONS
="$BOOL_OPTIONS $1"
236 if [ "$arg" = "--${op}" ]
238 op
=$
(echo $op |
tr 'a-z-' 'A-Z_')
245 if [ ! -z "${META-}" ]
249 printf " --%-30s %s\n" "$op" "$doc"
257 for option
in $BOOL_OPTIONS
259 if test --disable-$option = $arg
263 if test --enable-$option = $arg
267 if test --$option = $arg
272 for option
in $VAL_OPTIONS
274 if echo "$arg" |
grep -q -- "--$option="
279 if [ "$arg" = "--help" ]
282 echo "No more help available for Configure options,"
283 echo "check the Wiki or join our IRC channel"
286 if test $is_arg_valid -eq 0
288 err
"Option '$arg' is not recognized"
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
304 # Prints the absolute path of a directory to stdout
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
310 (unset CDPATH
&& cd "$path" > /dev
/null
&& pwd)
314 local _abs_libdir
="$1"
316 local _uninstalled_something
=false
318 # Replace commas in legacy manifest list with spaces
319 _legacy_manifest_dirs
=`echo "$TEMPLATE_LEGACY_MANIFEST_DIRS" | sed "s/,/ /g"`
321 # Uninstall from legacy manifests
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" ]
329 # iterate through installed manifest and remove files
332 # the installed manifest contains absolute paths
333 msg
"removing legacy file $_p"
337 want_ok
"failed to remove $_p"
339 warn
"supposedly installed file $_p does not exist!"
341 done < "$_abs_libdir/$_md/manifest"
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"
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"
356 _uninstalled_something
=true
360 RETVAL
="$_uninstalled_something"
363 uninstall_components
() {
364 local _abs_libdir
="$1"
365 local _dest_prefix
="$2"
366 local _components
="$3"
368 # We're going to start by uninstalling existing components. This
369 local _uninstalled_something
=false
371 # First, try removing any 'legacy' manifests from before
373 uninstall_legacy
"$_abs_libdir"
374 assert_nz
"$RETVAL", "RETVAL"
375 if [ "$RETVAL" = true
]; then
376 _uninstalled_something
=true
;
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"`
385 if [ ! -n "$_installed_version" ]; then critical_err
"rust installer version is empty"; fi
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
393 # If this is a previous version, then upgrade in place to the
394 # current version before uninstalling.
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.
401 # This is the current version. Nothing need to be done except uninstall.
402 "$TEMPLATE_RUST_INSTALLER_VERSION")
405 # If this is an unknown (future) version then bail.
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."
415 local _md
="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
416 local _installed_components
="$(cat "$_md/components
")"
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"
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"
432 # Iterate through installed component manifest and remove files
434 while read _directive
; do
436 local _command
=`echo $_directive | cut -f1 -d:`
437 local _file
=`echo $_directive | cut -f2 -d:`
440 if [ ! -n "$_command" ]; then critical_err
"malformed installation directive"; fi
441 if [ ! -n "$_file" ]; then critical_err
"malformed installation directive"; fi
445 verbose_msg
"removing file $_file"
446 if [ -f "$_file" ]; then
448 want_ok
"failed to remove $_file"
450 warn
"supposedly installed file $_file does not exist!"
455 verbose_msg
"removing directory $_file"
457 want_ok
"unable to remove directory $_file"
461 critical_err
"unknown installation directive"
465 done < "$_component_manifest"
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'"
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"
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"
490 want_ok
"failed to remove $_md"
496 _uninstalled_something
=true
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
]
502 err
"unable to find installation manifest at $CFG_LIBDIR/$TEMPLATE_REL_MANIFEST_DIR"
506 install_components
() {
508 local _abs_libdir
="$2"
509 local _dest_prefix
="$3"
510 local _components
="$4"
513 for _component
in $_components; do
515 msg
"installing component '$_component'"
517 # The file name of the manifest we're installing from
518 local _input_manifest
="$_src_dir/$_component/manifest.in"
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"
525 # The installed manifest directory
526 local _md
="$_abs_libdir/$TEMPLATE_REL_MANIFEST_DIR"
528 # The file name of the manifest we're going to create during install
529 local _installed_manifest
="$_md/manifest-$_component"
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"
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"
539 # Now install, iterate through the new manifest and copy files
541 while read _directive
; do
543 local _command
=`echo $_directive | cut -f1 -d:`
544 local _file
=`echo $_directive | cut -f2 -d:`
547 if [ ! -n "$_command" ]; then critical_err
"malformed installation directive"; fi
548 if [ ! -n "$_file" ]; then critical_err
"malformed installation directive"; fi
550 # Decide the destination of the file
551 local _file_install_path
="$_dest_prefix/$_file"
553 if echo "$_file" |
grep "^etc/" > /dev
/null
555 local _f
="$(echo "$_file" | sed 's/^etc\///')"
556 _file_install_path
="$CFG_SYSCONFDIR/$_f"
559 if echo "$_file" |
grep "^bin/" > /dev
/null
561 local _f
="$(echo "$_file" | sed 's/^bin\///')"
562 _file_install_path
="$CFG_BINDIR/$_f"
565 if echo "$_file" |
grep "^lib/" > /dev
/null
567 local _f
="$(echo "$_file" | sed 's/^lib\///')"
568 _file_install_path
="$CFG_LIBDIR/$_f"
571 if echo "$_file" |
grep "^share" > /dev
/null
573 local _f
="$(echo "$_file" | sed 's/^share\///')"
574 _file_install_path
="$CFG_DATADIR/$_f"
577 if echo "$_file" |
grep "^share/man/" > /dev
/null
579 local _f
="$(echo "$_file" | sed 's/^share\/man\///')"
580 _file_install_path
="$CFG_MANDIR/$_f"
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>" ]
595 if echo "$_file" |
grep "^share/doc/" > /dev
/null
597 local _f
="$(echo "$_file" | sed 's/^share\/doc\/[^/]*\///')"
598 _file_install_path
="$CFG_DOCDIR/$_f"
602 # Make sure there's a directory for it
603 make_dir_recursive
"$(dirname "$_file_install_path")"
604 critical_need_ok
"directory creation failed"
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"
615 verbose_msg
"copying file $_file_install_path"
617 maybe_backup_path
"$_file_install_path"
619 if echo "$_file" |
grep "^bin/" > /dev
/null ||
test -x "$_src_dir/$_component/$_file"
621 run
cp "$_src_dir/$_component/$_file" "$_file_install_path"
622 run
chmod 755 "$_file_install_path"
624 run
cp "$_src_dir/$_component/$_file" "$_file_install_path"
625 run
chmod 644 "$_file_install_path"
627 critical_need_ok
"file creation failed"
629 # Update the manifest
630 append_to_file
"file:$_file_install_path" "$_installed_manifest"
631 critical_need_ok
"failed to update manifest"
637 verbose_msg
"copying directory $_file_install_path"
639 maybe_backup_path
"$_file_install_path"
641 run
cp -R "$_src_dir/$_component/$_file" "$_file_install_path"
642 critical_need_ok
"failed to copy directory"
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"
648 # Update the manifest
649 append_to_file
"dir:$_file_install_path" "$_installed_manifest"
650 critical_need_ok
"failed to update manifest"
654 critical_err
"unknown installation directive"
657 done < "$_input_manifest"
662 maybe_configure_ld
() {
663 local _abs_libdir
="$1"
665 local _ostype
="$(uname -s)"
666 assert_nz
"$_ostype" "ostype"
668 if [ "$_ostype" = "Linux" -a ! -n "${CFG_DISABLE_LDCONFIG-}" ]; then
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.
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"
687 verbose_msg
"running ldconfig"
688 if [ -n "${CFG_VERBOSE-}" ]; then
691 ldconfig
2> /dev
/null
695 warn
"failed to run ldconfig. this may happen when not installing as root. run with --verbose to see the error"
700 maybe_unconfigure_ld
() {
701 local _ostype
="$(uname -s)"
702 assert_nz
"$_ostype" "ostype"
704 if [ "$_ostype" != "Linux" ]; then
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
712 # Doing our own 'install'-like backup that is consistent across platforms
713 maybe_backup_path
() {
714 local _file_install_path
="$1"
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"
723 install_uninstaller
() {
725 local _src_basename
="$2"
726 local _abs_libdir
="$3"
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"
734 do_preflight_sanity_checks
() {
736 local _dest_prefix
="$2"
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
745 err
"can't write to destination. consider \`sudo\`."
747 rm "$CFG_LIBDIR/rust-install-probe"
748 need_ok
"failed to remove install probe"
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"
759 verbose_msg
"looking for install programs"
776 if [ "${1-}" = "--help" ]
781 echo "Usage: $0 [options]"
786 verbose_step_msg
"processing arguments"
793 flag uninstall
"only uninstall from the installation prefix"
794 valopt destdir
"" "set installation root"
795 valopt prefix
"/usr/local" "set installation prefix"
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-}"
802 CFG_DESTDIR_PREFIX
="$CFG_DESTDIR/$CFG_PREFIX"
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"
829 verbose_step_msg
"validating arguments"
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
837 TEMPLATE_PRODUCT_NAME
=%%TEMPLATE_PRODUCT_NAME
%%
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
%%
847 # OK, let's get installing ...
849 # This is where we are installing from
850 src_dir
="$(abs_path $(dirname "$0"))"
852 # The name of the script
853 src_basename
="$(basename "$0")"
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"
864 CFG_DESTDIR_PREFIX
="$(abs_path "$src_dir/..
/..
/")"
865 CFG_LIBDIR
="$(abs_path "$src_dir/..
/")"
868 # This is where we are installing to
869 dest_prefix
="$CFG_DESTDIR_PREFIX"
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"`
877 # Sanity check: do we have components?
878 if [ ! -n "$components" ]; then
879 err
"unable to find installation components"
882 # If the user asked for a component list, do that and exit
883 if [ -n "${CFG_LIST_COMPONENTS-}" ]; then
885 echo "# Available components"
887 for component
in $components; do
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
898 user_components
="$(echo "$CFG_COMPONENTS" | sed "s
/,/ /g
")"
899 for user_component
in $user_components; do
901 for my_component
in $components; do
902 if [ "$user_component" = "$my_component" ]; then
906 if [ "$found" = false
]; then
907 err
"unknown component: $user_component"
910 components
="$user_components"
913 if [ -n "$CFG_WITHOUT" ]; then
914 without_components
="$(echo "$CFG_WITHOUT" | sed "s
/,/ /g
")"
916 # This does **not** check that all components in without_components are
917 # actually present in the list of available components.
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.
923 for component
in $components; do
925 for my_component
in $without_components; do
926 if [ "$component" = "$my_component" ]; then
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"
935 components
="$new_comp"
938 if [ -z "$components" ]; then
939 if [ -z "${CFG_UNINSTALL-}" ]; then
940 err
"no components selected for installation"
942 err
"no components selected for uninstallation"
946 do_preflight_sanity_checks
"$src_dir" "$dest_prefix"
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"
952 assert_nz
"$abs_libdir" "abs_libdir"
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"
958 # Log messages and commands
959 init_logging
"$abs_libdir"
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"
965 # If we're only uninstalling then exit
966 if [ -n "${CFG_UNINSTALL-}" ]
969 echo " $TEMPLATE_PRODUCT_NAME is uninstalled."
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"
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"
983 # Install the uninstaller
984 install_uninstaller
"$src_dir" "$src_basename" "$abs_libdir"
986 # Install each component
987 install_components
"$src_dir" "$abs_libdir" "$dest_prefix" "$components"
989 # Make dynamic libraries available to the linker
990 maybe_configure_ld
"$abs_libdir"
993 echo " $TEMPLATE_SUCCESS_MESSAGE"