Skip to content

Add support for --bindir and remember the relative locations of bindir and libdir vs prefix (ie: sysroot) #19065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
10 changes: 10 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ need_cmd date
need_cmd tr
need_cmd sed
need_cmd file
need_cmd realpath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both my linux machine and my OSX machine don't have this command, so it may not be common enough to require. There are some snippets in #16552 which may be useful, however.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll look into alternatives to calculate the relative paths.


msg "inspecting environment"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions mk/grammar.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion mk/host.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions mk/install.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
12 changes: 12 additions & 0 deletions mk/main.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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

######################################################################
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions mk/perf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions mk/prepare.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion mk/stage0.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion mk/target.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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))/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm... not sure how this ever worked!

@$$(call E, rustc: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4)

Expand Down
13 changes: 12 additions & 1 deletion src/etc/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ]
Expand Down Expand Up @@ -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"
Expand All @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I configure my bindir as foo, then won't this check fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will. I have some more fixes for this in testing. Should be updating this PR at some point soon.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using different libdirs between the configure command and the install command will also result in wierdness, a known bug. All the possible permutations here scare me.

I think in an ideal world I would prefer that the build always uses a consistent directory layout, even on windows, and only change the layout on install, but that might require deeper changes.


if echo "$p" | grep "^share/man/" > /dev/null
then
pp=`echo $p | sed 's/^share\/man\///'`
Expand All @@ -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
Expand Down
73 changes: 29 additions & 44 deletions src/librustc/metadata/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));

Expand Down Expand Up @@ -149,16 +148,16 @@ impl<'a> FileSearch<'a> {
// Returns a list of directories where target-specific tool binaries are located.
pub fn get_tools_search_paths(&self) -> Vec<Path> {
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");
vec![p]
}
}

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);
Expand All @@ -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<Path>) -> Option<Path> {
Expand All @@ -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")
}
}
Expand Down Expand Up @@ -248,40 +264,9 @@ pub fn rust_path() -> Vec<Path> {
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.
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 1 addition & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -89,7 +88,7 @@ pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, 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)),
Expand Down