Fix --disable-rpath and tests

This involved a few changes to the local build system:

* Makefiles now prefer our own LD_LIBRARY_PATH over the user's LD_LIBRARY_PATH
  in order to support building rust with rust already installed.
* The compiletest program was taught to correctly pass through the aux dir as a
  component of LD_LIBRARY_PATH in more situations.

This change was spliced out of #14832 to consist of just the fixes to running
tests without an rpath setting embedded in executables.
This commit is contained in:
Alex Crichton 2014-06-11 14:52:38 -07:00
parent 56d7bbe263
commit 375c5b884f
9 changed files with 59 additions and 38 deletions

View File

@ -360,10 +360,10 @@ endef
# contains spaces which confuse make.
# * `LD_LIBRARY_PATH_ENV_HOSTDIR`: the entry to add to lookup path for the host
# * `LD_LIBRARY_PATH_ENV_TARGETDIR`: the entry to add to lookup path for target
#
#
# Below that, HOST_RPATH_VAR and TARGET_RPATH_VAR are defined in terms of the
# above settings.
#
#
define SREQ_CMDS
ifeq ($$(OSTYPE_$(3)),apple-darwin)
@ -382,9 +382,9 @@ LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3) := \
$$(CURDIR)/$$(TLIB1_T_$(2)_H_$(CFG_BUILD))
HOST_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)):$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3))
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
TARGET_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)):$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(HOST_RPATH_VAR$(1)_T_$(2)_H_$(3))

View File

@ -91,7 +91,8 @@ endif
define DEF_TARGET_COMMANDS
ifdef CFG_UNIXY_$(1)
CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),,$$(CFG_VALGRIND) $$(1))
CFG_RUN_TEST_$(1)=$$(TARGET_RPATH_VAR$$(2)_T_$$(3)_H_$$(4)) \
$$(call CFG_RUN_$(1),,$$(CFG_VALGRIND) $$(1))
endif
ifdef CFG_WINDOWSY_$(1)
@ -105,13 +106,13 @@ ifdef CFG_WINDOWSY_$(1)
$$(if $$(findstring stage3,$$(1)), \
stage3/$$(CFG_LIBDIR_RELATIVE), \
)))))/rustlib/$$(CFG_BUILD)/lib
CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),$$(call CFG_TESTLIB_$(1),$$(1),$$(3)),$$(1))
CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),$$(call CFG_TESTLIB_$(1),$$(1),$$(4)),$$(1))
endif
# Run the compiletest runner itself under valgrind
ifdef CTEST_VALGRIND
CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \
$$(call CFG_RUN_TEST_$$(CFG_BUILD),$$(2),$$(3))
$$(call CFG_RUN_TEST_$$(CFG_BUILD),$$(3),$$(4))
else
CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \
$$(call CFG_RUN_$$(CFG_BUILD),$$(TLIB$$(1)_T_$$(3)_H_$$(3)),$$(2))
@ -391,7 +392,7 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$<)
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(2),$(3)) $$(TESTARGS) \
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(1),$(2),$(3)) $$(TESTARGS) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
&& touch $$@

View File

@ -13,21 +13,19 @@ use std::str;
use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
use std::dynamic_lib::DynamicLibrary;
fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog};
let mut aux_path = prog.to_string();
aux_path.push_str(".libaux");
fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
// Need to be sure to put both the lib_path and the aux path in the dylib
// search path for the child.
let mut path = DynamicLibrary::search_path();
path.insert(0, Path::new(aux_path));
match aux_path {
Some(p) => path.insert(0, Path::new(p)),
None => {}
}
path.insert(0, Path::new(lib_path));
// Remove the previous dylib search path var
let var = DynamicLibrary::envvar();
let mut env: Vec<(String,String)> =
os::env().move_iter().map(|(a,b)|(a.to_string(), b.to_string())).collect();
let mut env: Vec<(String,String)> = os::env();
match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
Some(i) => { env.remove(i); }
None => {}
@ -35,8 +33,8 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
// Add the new dylib search path var
let newpath = DynamicLibrary::create_path(path.as_slice());
env.push((var.to_string(),
str::from_utf8(newpath.as_slice()).unwrap().to_string()));
let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
env.push((var.to_string(), newpath));
return env;
}
@ -44,11 +42,12 @@ pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
pub fn run(lib_path: &str,
prog: &str,
aux_path: Option<&str>,
args: &[String],
env: Vec<(String, String)> ,
input: Option<String>) -> Option<Result> {
let env = env.clone().append(target_env(lib_path, prog).as_slice());
let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() {
Ok(mut process) => {
for input in input.iter() {
@ -69,11 +68,12 @@ pub fn run(lib_path: &str,
pub fn run_background(lib_path: &str,
prog: &str,
aux_path: Option<&str>,
args: &[String],
env: Vec<(String, String)> ,
input: Option<String>) -> Option<Process> {
let env = env.clone().append(target_env(lib_path, prog).as_slice());
let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() {
Ok(mut process) => {
for input in input.iter() {

View File

@ -230,6 +230,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
testfile: &Path,
src: String,
pretty_type: &str) -> ProcRes {
let aux_dir = aux_output_dir_name(config, testfile);
compose_and_run(config,
testfile,
make_pp_args(config,
@ -238,6 +239,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
pretty_type.to_string()),
props.exec_env.clone(),
config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
Some(src))
}
@ -354,6 +356,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
procsrv::run("",
config.adb_path.as_slice(),
None,
[
"push".to_string(),
exe_file.as_str().unwrap().to_string(),
@ -365,6 +368,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
procsrv::run("",
config.adb_path.as_slice(),
None,
[
"forward".to_string(),
"tcp:5039".to_string(),
@ -385,6 +389,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
let mut process = procsrv::run_background("",
config.adb_path
.as_slice(),
None,
[
"shell".to_string(),
adb_arg.clone()
@ -425,6 +430,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
status
} = procsrv::run("",
gdb_path.as_slice(),
None,
debugger_opts.as_slice(),
vec!(("".to_string(), "".to_string())),
None)
@ -486,7 +492,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
testfile,
proc_args,
Vec::new(),
"",
config.run_lib_path.as_slice(),
None,
None);
}
}
@ -994,11 +1001,13 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
}
_=> {
let aux_dir = aux_output_dir_name(config, testfile);
compose_and_run(config,
testfile,
make_run_args(config, props, testfile),
env,
config.run_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
None)
}
}
@ -1045,6 +1054,7 @@ fn compose_and_run_compiler(
aux_args,
Vec::new(),
config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
None);
if !auxres.status.success() {
fatal_proc_rec(
@ -1066,6 +1076,7 @@ fn compose_and_run_compiler(
args,
Vec::new(),
config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
input)
}
@ -1078,9 +1089,10 @@ fn compose_and_run(config: &Config, testfile: &Path,
ProcArgs{ args, prog }: ProcArgs,
procenv: Vec<(String, String)> ,
lib_path: &str,
aux_path: Option<&str>,
input: Option<String>) -> ProcRes {
return program_output(config, testfile, lib_path,
prog, args, procenv, input);
prog, aux_path, args, procenv, input);
}
enum TargetLocation {
@ -1189,7 +1201,8 @@ fn split_maybe_args(argstr: &Option<String>) -> Vec<String> {
}
fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String,
args: Vec<String> , env: Vec<(String, String)> ,
aux_path: Option<&str>, args: Vec<String>,
env: Vec<(String, String)>,
input: Option<String>) -> ProcRes {
let cmdline =
{
@ -1205,6 +1218,7 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
status
} = procsrv::run(lib_path,
prog.as_slice(),
aux_path,
args.as_slice(),
env,
input).expect(format!("failed to exec `{}`", prog).as_slice());
@ -1326,6 +1340,7 @@ fn _arm_exec_compiled_test(config: &Config,
// copy to target
let copy_result = procsrv::run("",
config.adb_path.as_slice(),
None,
[
"push".to_string(),
args.prog.clone(),
@ -1361,6 +1376,7 @@ fn _arm_exec_compiled_test(config: &Config,
}
procsrv::run("",
config.adb_path.as_slice(),
None,
runargs.as_slice(),
vec!(("".to_string(), "".to_string())), Some("".to_string()))
.expect(format!("failed to exec `{}`", config.adb_path).as_slice());
@ -1374,6 +1390,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
procsrv::run("",
config.adb_path.as_slice(),
None,
runargs.as_slice(),
vec!(("".to_string(), "".to_string())),
Some("".to_string()))
@ -1397,6 +1414,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: stdout_out, err: _, status: _ } =
procsrv::run("",
config.adb_path.as_slice(),
None,
runargs.as_slice(),
vec!(("".to_string(), "".to_string())),
Some("".to_string()))
@ -1411,6 +1429,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: stderr_out, err: _, status: _ } =
procsrv::run("",
config.adb_path.as_slice(),
None,
runargs.as_slice(),
vec!(("".to_string(), "".to_string())),
Some("".to_string()))
@ -1438,6 +1457,7 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
// FIXME (#9639): This needs to handle non-utf8 paths
let copy_result = procsrv::run("",
config.adb_path.as_slice(),
None,
[
"push".to_string(),
file.as_str()
@ -1505,7 +1525,7 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps,
bitcodefile.as_str().unwrap().to_string(),
testcc.as_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}
fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
@ -1522,7 +1542,7 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
format!("-o={}", extracted_bc.as_str().unwrap()),
bitcodefile.as_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}
fn disassemble_extract(config: &Config, _props: &TestProps,
@ -1538,7 +1558,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
extracted_bc.as_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}

View File

@ -4,8 +4,8 @@
ifndef IS_WINDOWS
all:
$(RUSTDOC) --test foo.rs
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
$(HOST_RPATH_ENV) $(RUSTDOC) --test foo.rs
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
cp verify.sh $(TMPDIR)
$(call RUN,verify.sh) $(TMPDIR)

View File

@ -1,4 +1,4 @@
-include ../tools.mk
all:
$(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
$(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json
$(HOST_RPATH_ENV) $(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
$(HOST_RPATH_ENV) $(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json

View File

@ -1,5 +1,5 @@
-include ../tools.mk
all:
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
cp verify.sh $(TMPDIR)
$(call RUN,verify.sh) $(TMPDIR)

View File

@ -1,15 +1,15 @@
export LD_LIBRARY_PATH:=$(TMPDIR):$(LD_LIBRARY_PATH)
export DYLD_LIBRARY_PATH:=$(TMPDIR):$(DYLD_LIBRARY_PATH)
RUSTC := $(RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
CC := $(CC) -L $(TMPDIR)
# These deliberately use `=` and not `:=` so that client makefiles can
# augment HOST_RPATH_DIR / TARGET_RPATH_DIR.
HOST_RPATH_ENV = \
$(LD_LIB_PATH_ENVVAR)=$$$(LD_LIB_PATH_ENVVAR):$(HOST_RPATH_DIR)
$(LD_LIB_PATH_ENVVAR)=$(HOST_RPATH_DIR):$$$(LD_LIB_PATH_ENVVAR)
TARGET_RPATH_ENV = \
$(LD_LIB_PATH_ENVVAR)=$$$(LD_LIB_PATH_ENVVAR):$(TARGET_RPATH_DIR)
$(LD_LIB_PATH_ENVVAR)=$(TARGET_RPATH_DIR):$$$(LD_LIB_PATH_ENVVAR)
RUSTC := $(HOST_RPATH_ENV) $(RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
CC := $(CC) -L $(TMPDIR)
# This is the name of the binary we will generate and run; use this
# e.g. for `$(CC) -o $(RUN_BINFILE)`.

View File

@ -10,6 +10,7 @@
// ignore-android
// ignore-win32
// exec-env:RUST_LOG=debug
#![feature(phase)]
@ -29,9 +30,8 @@ fn main() {
return
}
let env = [("RUST_LOG".to_string(), "debug".to_string())];
let p = Command::new(args[0].as_slice())
.arg("child").env(env.as_slice())
.arg("child")
.spawn().unwrap().wait_with_output().unwrap();
assert!(p.status.success());
let mut lines = str::from_utf8(p.error.as_slice()).unwrap().lines();