diff --git a/mk/dist.mk b/mk/dist.mk index 60549e299cc..10c1636a03a 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -200,7 +200,8 @@ dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) dist-install-dir-$(1): PREPARE_CLEAN=true dist-install-dir-$(1): prepare-base-dir-$(1) $$(Q)(cd $$(PREPARE_DEST_DIR)/ && find -type f | sed 's/^\.\///') \ - > $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest + > tmp/manifest-$(1) # NB Use a tmp file so `find` doesn't *find the manifest* + $$(Q)cp tmp/manifest-$(1) $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest $$(Q)$$(PREPARE_MAN_CMD) $$(S)COPYRIGHT $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-APACHE $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-MIT $$(PREPARE_DEST_DIR) diff --git a/mk/install.mk b/mk/install.mk index 7bae272b47a..6545441a405 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -10,10 +10,10 @@ install: dist-install-dir-$(CFG_BUILD) - $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(CFG_PREFIX)" + $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(CFG_PREFIX)" --libdir="$(CFG_LIBDIR)" --mandir="$(CFG_MANDIR)" uninstall: dist-install-dir-$(CFG_BUILD) - $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(CFG_PREFIX)" --uninstall + $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(CFG_PREFIX)" --libdir="$(CFG_LIBDIR)" --mandir="$(CFG_MANDIR)" ###################################################################### diff --git a/src/etc/install.sh b/src/etc/install.sh index e6d20b932b3..3ae028d9713 100644 --- a/src/etc/install.sh +++ b/src/etc/install.sh @@ -213,6 +213,10 @@ VAL_OPTIONS="" flag uninstall "only uninstall from the installation prefix" valopt prefix "/usr/local" "set installation prefix" +# NB This isn't quite the same definition as in `configure`. +# just using 'lib' instead of CFG_LIBDIR_RELATIVE +valopt libdir "${CFG_PREFIX}/lib" "install libraries" +valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH" if [ $HELP -eq 1 ] then @@ -224,39 +228,40 @@ step_msg "validating $CFG_SELF args" validate_opt # Sanity check: can we can write to the destination? -umask 022 && mkdir -p "${CFG_PREFIX}/lib" +umask 022 && mkdir -p "${CFG_LIBDIR}" need_ok "directory creation failed" -touch "${CFG_PREFIX}/lib/rust-install-probe" 2> /dev/null +touch "${CFG_LIBDIR}/rust-install-probe" 2> /dev/null if [ $? -ne 0 ] then err "can't write to destination. try again with 'sudo'." fi -rm "${CFG_PREFIX}/lib/rust-install-probe" +rm "${CFG_LIBDIR}/rust-install-probe" need_ok "failed to remove install probe" +INSTALLED_MANIFEST="${CFG_LIBDIR}/rustlib/manifest" # First, uninstall from the installation prefix. # Errors are warnings - try to rm everything in the manifest even if some fail. -if [ -f "${CFG_PREFIX}/lib/rustlib/manifest" ] +if [ -f "${INSTALLED_MANIFEST}" ] then # Iterate through installed manifest and remove files while read p; do - msg "removing ${CFG_PREFIX}/$p" - if [ -f "${CFG_PREFIX}/$p" ] + # The installed manifest contains absolute paths + msg "removing $p" + if [ -f "$p" ] then - rm "${CFG_PREFIX}/$p" + rm "$p" if [ $? -ne 0 ] then - warn "failed to remove ${CFG_PREFIX}/$p" + warn "failed to remove $p" fi else - warn "supposedly installed file ${CFG_PREFIX}/$p does not exist!" + warn "supposedly installed file $p does not exist!" fi - done < "${CFG_PREFIX}/lib/rustlib/manifest" + done < "${INSTALLED_MANIFEST}" # Remove 'rustlib' directory - msg "removing ${CFG_PREFIX}/lib/rustlib" - rm -r "${CFG_PREFIX}/lib/rustlib" + rm -r "${CFG_LIBDIR}/rustlib" if [ $? -ne 0 ] then warn "failed to remove rustlib" @@ -264,7 +269,7 @@ then else if [ -n "${CFG_UNINSTALL}" ] then - err "unable to find installation manifest at ${CFG_PREFIX}/lib/rustlib" + err "unable to find installation manifest at ${CFG_LIBDIR}/rustlib" fi fi @@ -277,22 +282,53 @@ then exit 0 fi +# Create the installed manifest, which we will fill in with absolute file paths +mkdir -p "${CFG_LIBDIR}/rustlib" +touch "${INSTALLED_MANIFEST}" # Now install, iterate through the new manifest and copy files while read p; do - umask 022 && mkdir -p "${CFG_PREFIX}/$(dirname $p)" + # Decide the destination of the file + FILE_INSTALL_PATH="${CFG_PREFIX}/$p" + + if echo "$p" | grep "^lib/" > /dev/null + then + pp=`echo $p | sed 's/^lib\///'` + FILE_INSTALL_PATH="${CFG_LIBDIR}/$pp" + fi + + if echo "$p" | grep "^share/man/" > /dev/null + then + pp=`echo $p | sed 's/^share\/man\///'` + FILE_INSTALL_PATH="${CFG_MANDIR}/$pp" + fi + + # Make sure ther's a directory for it + umask 022 && mkdir -p "$(dirname ${FILE_INSTALL_PATH})" need_ok "directory creation failed" - msg "${CFG_PREFIX}/$p" - if echo "$p" | grep "/bin/" > /dev/null + # Make the path absolute so we can uninstall it later without + # starting from the installation cwd + FILE_INSTALL_PATH_DIRNAME="$(dirname ${FILE_INSTALL_PATH})" + FILE_INSTALL_PATH_BASENAME="$(basename ${FILE_INSTALL_PATH})" + FILE_INSTALL_ABS_PATH="$(cd ${FILE_INSTALL_PATH_DIRNAME} && pwd)" + FILE_INSTALL_PATH="${FILE_INSTALL_ABS_PATH}/${FILE_INSTALL_PATH_BASENAME}" + + # Install the file + msg "${FILE_INSTALL_PATH}" + if echo "$p" | grep "^bin/" > /dev/null then - install -m755 "${CFG_SRC_DIR}/$p" "${CFG_PREFIX}/$p" + install -m755 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}" else - install -m644 "${CFG_SRC_DIR}/$p" "${CFG_PREFIX}/$p" + install -m644 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}" fi need_ok "file creation failed" + # Update the manifest + echo "${FILE_INSTALL_PATH}" >> "${INSTALLED_MANIFEST}" + need_ok "failed to update manifest" + # The manifest lists all files to install done < "${CFG_SRC_DIR}/lib/rustlib/manifest" diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 08e96ec9215..d548dc6dfb7 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -54,8 +54,9 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> { } fn get_sysroot_absolute_rt_lib(sess: &Session) -> Path { - let r = filesearch::relative_target_lib_path(sess.opts.target_triple); - let mut p = sess.filesearch().sysroot.join(&r); + let sysroot = sess.filesearch().sysroot; + let r = filesearch::relative_target_lib_path(sysroot, sess.opts.target_triple); + let mut p = sysroot.join(&r); p.push(os::dll_filename("rustrt")); p } @@ -91,7 +92,7 @@ fn get_rpaths(os: abi::Os, let abs_rpaths = get_absolute_rpaths(libs); // And a final backup rpath to the global library location. - let fallback_rpaths = vec!(get_install_prefix_rpath(target_triple)); + let fallback_rpaths = vec!(get_install_prefix_rpath(sysroot, target_triple)); fn log_rpaths(desc: &str, rpaths: &[~str]) { debug!("{} rpaths:", desc); @@ -156,10 +157,10 @@ pub fn get_absolute_rpath(lib: &Path) -> ~str { p.as_str().expect("non-utf8 component in rpath").to_owned() } -pub fn get_install_prefix_rpath(target_triple: &str) -> ~str { +pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &str) -> ~str { let install_prefix = env!("CFG_PREFIX"); - let tlib = filesearch::relative_target_lib_path(target_triple); + let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); let mut path = Path::new(install_prefix); path.push(&tlib); let path = os::make_absolute(&path); @@ -195,7 +196,8 @@ mod test { #[test] fn test_prefix_rpath() { - let res = get_install_prefix_rpath("triple"); + let sysroot = filesearch::get_or_default_sysroot(); + let res = get_install_prefix_rpath(sysroot, "triple"); let mut d = Path::new(env!("CFG_PREFIX")); d.push("lib"); d.push(filesearch::rustlibdir()); @@ -208,7 +210,8 @@ mod test { #[test] fn test_prefix_rpath_abs() { - let res = get_install_prefix_rpath("triple"); + let sysroot = filesearch::get_or_default_sysroot(); + let res = get_install_prefix_rpath(sysroot, "triple"); assert!(Path::new(res).is_absolute()); } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index df5aa1fe414..5a92c48f400 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -60,7 +60,8 @@ impl<'a> FileSearch<'a> { if !found { let rustpath = rust_path(); for path in rustpath.iter() { - let tlib_path = make_rustpkg_target_lib_path(path, self.target_triple); + let tlib_path = make_rustpkg_target_lib_path( + self.sysroot, path, self.target_triple); debug!("is {} in visited_dirs? {:?}", tlib_path.display(), visited_dirs.contains_equiv(&tlib_path.as_vec().to_owned())); @@ -136,8 +137,8 @@ impl<'a> FileSearch<'a> { } } -pub fn relative_target_lib_path(target_triple: &str) -> Path { - let mut p = Path::new(libdir()); +pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { + let mut p = Path::new(find_libdir(sysroot)); assert!(p.is_relative()); p.push(rustlibdir()); p.push(target_triple); @@ -147,12 +148,13 @@ pub fn relative_target_lib_path(target_triple: &str) -> Path { fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { - sysroot.join(&relative_target_lib_path(target_triple)) + sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } -fn make_rustpkg_target_lib_path(dir: &Path, - target_triple: &str) -> Path { - let mut p = dir.join(libdir()); +fn make_rustpkg_target_lib_path(sysroot: &Path, + dir: &Path, + target_triple: &str) -> Path { + let mut p = dir.join(find_libdir(sysroot)); p.push(target_triple); p } @@ -236,12 +238,30 @@ pub fn rust_path() -> Vec { // The name of the directory rustc expects libraries to be located. // On Unix should be "lib", on windows "bin" #[cfg(unix)] -pub fn libdir() -> ~str { - ~"lib" +fn find_libdir(sysroot: &Path) -> ~str { + // FIXME: This is a quick hack to make the rustc binary able to locate + // Rust libraries in Linux environments where libraries might be installed + // to lib64/lib32. This would be more foolproof by basing the sysroot off + // of the directory where librustc is located, rather than where the rustc + // binary is. + + if sysroot.join(primary_libdir_name()).exists() { + return primary_libdir_name(); + } else { + return secondary_libdir_name(); + } + + #[cfg(target_word_size = "64")] + fn primary_libdir_name() -> ~str { ~"lib64" } + + #[cfg(target_word_size = "32")] + fn primary_libdir_name() -> ~str { ~"lib32" } + + fn secondary_libdir_name() -> ~str { ~"lib" } } #[cfg(windows)] -pub fn libdir() -> ~str { +fn find_libdir(_sysroot: &Path) -> ~str { ~"bin" }