about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2014-03-25 21:25:43 -0700
committerBrian Anderson <banderson@mozilla.com>2014-03-25 23:57:39 -0700
commitce1e48a52be07f39291848aa17b8666b7165e804 (patch)
tree1d188912b525617783232a61ad21c907e49384b3
parent380fe976c83bd78ae1a797849ea1162a8c6d349b (diff)
install: Support --libdir and --mandir correctly
This adds a hack to rustc to make it find the library directory
regardless of whether it is named lib/lib64/lib32.
-rw-r--r--mk/dist.mk3
-rw-r--r--mk/install.mk4
-rw-r--r--src/etc/install.sh72
-rw-r--r--src/librustc/back/rpath.rs17
-rw-r--r--src/librustc/metadata/filesearch.rs40
5 files changed, 98 insertions, 38 deletions
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<Path> {
 // 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"
 }