diff --git a/configure b/configure index 7790025301401..791460135dc35 100755 --- a/configure +++ b/configure @@ -340,6 +340,7 @@ need_cmd date need_cmd tr need_cmd sed need_cmd file +need_cmd realpath msg "inspecting environment" @@ -554,12 +555,20 @@ fi valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries" +CFG_BINDIR_RELATIVE=bin +valopt bindir "${CFG_PREFIX}/${CFG_BINDIR_RELATIVE}" "install binaries" + if [ $HELP -eq 1 ] then echo exit 0 fi +# Determine libdir and bindir relative to prefix +step_msg "calculating relative paths to prefix = ${CFG_PREFIX}" +CFG_BINDIR_RELATIVE=$(realpath -m --relative-to="${CFG_PREFIX}" "${CFG_BINDIR}") +CFG_LIBDIR_RELATIVE=$(realpath -m --relative-to="${CFG_PREFIX}" "${CFG_LIBDIR}") + # Validate Options step_msg "validating $CFG_SELF args" validate_opt @@ -1312,6 +1321,7 @@ putvar CFG_PREFIX putvar CFG_HOST putvar CFG_TARGET putvar CFG_LIBDIR_RELATIVE +putvar CFG_BINDIR_RELATIVE putvar CFG_DISABLE_MANAGE_SUBMODULES putvar CFG_ANDROID_CROSS_PATH putvar CFG_MANDIR diff --git a/mk/grammar.mk b/mk/grammar.mk index 12190fb034854..dcebabf5ca375 100644 --- a/mk/grammar.mk +++ b/mk/grammar.mk @@ -11,8 +11,8 @@ BG = $(CFG_BUILD_DIR)/grammar/ SG = $(S)src/grammar/ B = $(CFG_BUILD_DIR)/$(CFG_BUILD)/stage2/ -L = $(B)lib/rustlib/$(CFG_BUILD)/lib -LD = $(CFG_BUILD)/stage2/lib/rustlib/$(CFG_BUILD)/lib/ +L = $(B)$(CFG_LIBDIR_RELATIVE)/rustlib/$(CFG_BUILD)/lib +LD = $(CFG_BUILD)/stage2/$(CFG_LIBDIR_RELATIVE)/rustlib/$(CFG_BUILD)/lib/ RUSTC = $(STAGE2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) # Run the reference lexer against libsyntax and compare the tokens and spans. diff --git a/mk/host.mk b/mk/host.mk index 59a00950b5cfd..b8e83458acaf1 100644 --- a/mk/host.mk +++ b/mk/host.mk @@ -59,9 +59,13 @@ endef # $(4) - the host triple (same as $(3)) define CP_HOST_STAGE_N -ifneq ($(CFG_LIBDIR_RELATIVE),bin) $$(HLIB$(2)_H_$(4))/: @mkdir -p $$@ + +# Avoid redefinition warnings if libdir==bindir +ifneq ($(HBIN$(2)_H_$(4)),$(HLIB$(2)_H_$(4))) +$$(HBIN$(2)_H_$(4))/: + @mkdir -p $$@ endif endef diff --git a/mk/install.mk b/mk/install.mk index 88b451f661af2..0fba6eef07ab3 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -21,7 +21,7 @@ ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER))) else $(Q)$(MAKE) prepare_install endif - $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)" + $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" --bindir="$(DESTDIR)$(CFG_BINDIR)" "$(MAYBE_DISABLE_VERIFY)" # Remove tmp files because it's a decent amount of disk space $(Q)rm -R tmp/dist @@ -34,7 +34,7 @@ ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER))) else $(Q)$(MAKE) prepare_uninstall endif - $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" + $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" --bindir="$(DESTDIR)$(CFG_BINDIR)" # Remove tmp files because it's a decent amount of disk space $(Q)rm -R tmp/dist diff --git a/mk/main.mk b/mk/main.mk index 3df4d3bfa5ec6..676ea2194fa27 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -315,7 +315,9 @@ export CFG_BUILD export CFG_LLVM_ROOT export CFG_PREFIX export CFG_LIBDIR +export CFG_BINDIR export CFG_LIBDIR_RELATIVE +export CFG_BINDIR_RELATIVE export CFG_DISABLE_INJECT_STD_VERSION ###################################################################### @@ -331,8 +333,18 @@ define SREQ # Destinations of artifacts for the host compiler HROOT$(1)_H_$(3) = $(3)/stage$(1) + +ifeq ($(1)-$(3),0-$$(CFG_BUILD)) +# stage0 relative paths are fixed. This is done because we don't have control +# over where the bootstrap (snapshot or local) rustc looks to locate it's +# libdir. At the moment, this assumes the relative paths (from sysroot aka +# prefix) are 'lib' and 'bin'. HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin +HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/lib +else +HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_BINDIR_RELATIVE) HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE) +endif # Destinations of artifacts for target architectures TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustlib/$(2) diff --git a/mk/perf.mk b/mk/perf.mk index 16cbaab495d82..f8a354c68a8f9 100644 --- a/mk/perf.mk +++ b/mk/perf.mk @@ -10,13 +10,13 @@ ifdef CFG_PERF_TOOL -rustc-perf$(X): $(CFG_BUILD)/stage2/bin/rustc$(X_$(CFG_BUILD)) +rustc-perf$(X): $(CFG_BUILD)/stage2/$(CFG_BINDIR_RELATIVE)/rustc$(X_$(CFG_BUILD)) @$(call E, perf compile: $@) $(PERF_STAGE2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \ -o $@ $(COMPILER_CRATE) >rustc-perf.err 2>&1 $(Q)rm -f $(LIBRUSTC_GLOB) else -rustc-perf$(X): $(CFG_BUILD)/stage2/bin/rustc$(X_$(CFG_BUILD)) +rustc-perf$(X): $(CFG_BUILD)/stage2/$(CFG_BINDIR_RELATIVE)/rustc$(X_$(CFG_BUILD)) $(Q)touch $@ endif diff --git a/mk/prepare.mk b/mk/prepare.mk index 7df2489744b67..842078f221a11 100644 --- a/mk/prepare.mk +++ b/mk/prepare.mk @@ -147,10 +147,10 @@ endef define DEF_PREPARE prepare-base-$(1): PREPARE_SOURCE_DIR=$$(PREPARE_HOST)/stage$$(PREPARE_STAGE) -prepare-base-$(1): PREPARE_SOURCE_BIN_DIR=$$(PREPARE_SOURCE_DIR)/bin +prepare-base-$(1): PREPARE_SOURCE_BIN_DIR=$$(PREPARE_SOURCE_DIR)/$$(CFG_BINDIR_RELATIVE) prepare-base-$(1): PREPARE_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_DIR)/$$(CFG_LIBDIR_RELATIVE) prepare-base-$(1): PREPARE_SOURCE_MAN_DIR=$$(S)/man -prepare-base-$(1): PREPARE_DEST_BIN_DIR=$$(PREPARE_DEST_DIR)/bin +prepare-base-$(1): PREPARE_DEST_BIN_DIR=$$(PREPARE_DEST_DIR)/$$(CFG_BINDIR_RELATIVE) prepare-base-$(1): PREPARE_DEST_LIB_DIR=$$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE) prepare-base-$(1): PREPARE_DEST_MAN_DIR=$$(PREPARE_DEST_DIR)/share/man/man1 prepare-base-$(1): prepare-everything-$(1) diff --git a/mk/stage0.mk b/mk/stage0.mk index e028bba73da1e..460a4a7f445e3 100644 --- a/mk/stage0.mk +++ b/mk/stage0.mk @@ -22,7 +22,7 @@ ifdef CFG_ENABLE_LOCAL_RUST else $(Q)$(CFG_PYTHON) $(S)src/etc/get-snapshot.py $(CFG_BUILD) $(SNAPSHOT_FILE) endif - $(Q)touch $@ + $(Q)if [ -e "$@" ]; then touch "$@"; else echo "ERROR: snapshot $@ not found"; exit 1; fi # For other targets, let the host build the target: diff --git a/mk/target.mk b/mk/target.mk index ed7d8bb497d28..acdf780f10545 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -116,7 +116,7 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ $$(foreach dep,$$(TOOL_DEPS_$(4)), \ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ - | $$(TBIN$(1)_T_$(4)_H_$(3))/ + | $$(TBIN$(1)_T_$(2)_H_$(3))/ @$$(call E, rustc: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4) diff --git a/src/etc/install.sh b/src/etc/install.sh index 4f43b1ed13033..add1c267720a0 100644 --- a/src/etc/install.sh +++ b/src/etc/install.sh @@ -285,6 +285,8 @@ then CFG_LIBDIR_RELATIVE=bin fi +CFG_BINDIR_RELATIVE=bin + if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ] then CFG_LD_PATH_VAR=PATH @@ -304,6 +306,7 @@ 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}/${CFG_LIBDIR_RELATIVE}" "install libraries" +valopt bindir "${CFG_PREFIX}/${CFG_BINDIR_RELATIVE}" "install binaries" valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH" if [ $HELP -eq 1 ] @@ -424,6 +427,7 @@ need_ok "failed to create installed manifest" # Now install, iterate through the new manifest and copy files while read p; do + is_bin=false # Decide the destination of the file FILE_INSTALL_PATH="${CFG_PREFIX}/$p" @@ -434,6 +438,13 @@ while read p; do FILE_INSTALL_PATH="${CFG_LIBDIR}/$pp" fi + if echo "$p" | grep "^bin/" > /dev/null + then + is_bin=true + pp=`echo $p | sed 's/^bin\///'` + FILE_INSTALL_PATH="${CFG_BINDIR}/$pp" + fi + if echo "$p" | grep "^share/man/" > /dev/null then pp=`echo $p | sed 's/^share\/man\///'` @@ -451,7 +462,7 @@ while read p; do # Install the file msg "${FILE_INSTALL_PATH}" - if echo "$p" | grep "^bin/" > /dev/null + if $is_bin then install -m755 "${CFG_SRC_DIR}/$p" "${FILE_INSTALL_PATH}" else diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index fee289df3e4e4..b626308fc822f 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -66,8 +66,7 @@ impl<'a> FileSearch<'a> { if !found { let rustpath = rust_path(); for path in rustpath.iter() { - let tlib_path = make_rustpkg_lib_path( - self.sysroot, path, self.triple); + let tlib_path = make_rustpkg_lib_path(path, self.triple); debug!("is {} in visited_dirs? {}", tlib_path.display(), visited_dirs.contains(&tlib_path.as_vec().to_vec())); @@ -149,7 +148,7 @@ impl<'a> FileSearch<'a> { // Returns a list of directories where target-specific tool binaries are located. pub fn get_tools_search_paths(&self) -> Vec { let mut p = Path::new(self.sysroot); - p.push(find_libdir(self.sysroot)); + p.push(libdir_str()); p.push(rustlibdir()); p.push(self.triple); p.push("bin"); @@ -157,8 +156,8 @@ impl<'a> FileSearch<'a> { } } -pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { - let mut p = Path::new(find_libdir(sysroot)); +pub fn relative_target_lib_path(target_triple: &str) -> Path { + let mut p = Path::new(libdir_str()); assert!(p.is_relative()); p.push(rustlibdir()); p.push(target_triple); @@ -168,17 +167,24 @@ pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { - sysroot.join(&relative_target_lib_path(sysroot, target_triple)) + sysroot.join(&relative_target_lib_path(target_triple)) } -fn make_rustpkg_lib_path(sysroot: &Path, - dir: &Path, +fn make_rustpkg_lib_path(dir: &Path, triple: &str) -> Path { - let mut p = dir.join(find_libdir(sysroot)); + let mut p = dir.join(libdir_str()); p.push(triple); p } +pub fn bindir_relative_str() -> &'static str { + env!("CFG_BINDIR_RELATIVE") +} + +pub fn bindir_relative_path() -> Path { + Path::new(bindir_relative_str()) +} + pub fn get_or_default_sysroot() -> Path { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: Option) -> Option { @@ -190,7 +196,17 @@ pub fn get_or_default_sysroot() -> Path { } match canonicalize(os::self_exe_name()) { - Some(mut p) => { p.pop(); p.pop(); p } + Some(mut p) => { + // Remove the exe name + p.pop(); + let mut rel = bindir_relative_path(); + // Remove a number of elements equal to the number of elements in the bindir relative + // path + while rel.pop() { + p.pop(); + } + p + } None => panic!("can't determine value for sysroot") } } @@ -248,40 +264,9 @@ pub fn rust_path() -> Vec { env_rust_path } -// The name of the directory rustc expects libraries to be located. -// On Unix should be "lib", on windows "bin" -#[cfg(unix)] -fn find_libdir(sysroot: &Path) -> String { - // 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()).join(rustlibdir()).exists() { - return primary_libdir_name(); - } else { - return secondary_libdir_name(); - } - - #[cfg(target_word_size = "64")] - fn primary_libdir_name() -> String { - "lib64".to_string() - } - - #[cfg(target_word_size = "32")] - fn primary_libdir_name() -> String { - "lib32".to_string() - } - - fn secondary_libdir_name() -> String { - "lib".to_string() - } -} - -#[cfg(windows)] -fn find_libdir(_sysroot: &Path) -> String { - "bin".to_string() +// The name of the directory rustc expects libraries to be located, relative to the sysroot +fn libdir_str() -> &'static str { + env!("CFG_LIBDIR_RELATIVE") } // The name of rustc's own place to organize libraries. diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index d5d488e8965a3..cddf970d91d5b 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1015,11 +1015,10 @@ fn link_args(cmd: &mut Command, // where extern libraries might live, based on the // addl_lib_search_paths if sess.opts.cg.rpath { - let sysroot = sess.sysroot(); let target_triple = sess.opts.target_triple.as_slice(); let get_install_prefix_lib_path = || { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); - let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); + let tlib = filesearch::relative_target_lib_path(target_triple); let mut path = Path::new(install_prefix); path.push(&tlib); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 21242e6f1e48d..b040a4bfd2a09 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -18,7 +18,6 @@ use rustc_trans::back::link; use syntax::{ast, ast_map, codemap, diagnostic}; use std::cell::RefCell; -use std::os; use std::collections::{HashMap, HashSet}; use arena::TypedArena; @@ -89,7 +88,7 @@ pub fn run_core(libs: Vec, cfgs: Vec, externs: Externs, let warning_lint = lint::builtin::WARNINGS.name_lower(); let sessopts = config::Options { - maybe_sysroot: Some(os::self_exe_path().unwrap().dir_path()), + maybe_sysroot: None, addl_lib_search_paths: RefCell::new(libs), crate_types: vec!(config::CrateTypeRlib), lint_opts: vec!((warning_lint, lint::Allow)),