-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Set the host library path in run-make v2 #123763
Conversation
When the build is configured with `[rust] rpath = false`, we need to set `LD_LIBRARY_PATH` (or equivalent) to what would have been the `RPATH`, so the compiler can find its own libraries. The old `tools.mk` code has this environment prefixed in the `$(BARE_RUSTC)` variable, so we just need to wire up something similar for run-make v2. This is now set while building each `rmake.rs` itself, as well as in the `rust-make-support` helpers for `rustc` and `rustdoc` commands. This is also available in a `set_host_rpath` function for manual commands, like in the `compiler-builtins` test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix, I believe this might also be the more general fix for run-make v2 tests breaking on sgx (cf. #123100) 💚
Feel free to r=me after fixing the PATH
joining and splitting issue (which is more than likely entirely my fault for misleading 😆)
src/tools/compiletest/src/runtest.rs
Outdated
let mut host_dylib_env_paths = String::new(); | ||
host_dylib_env_paths.push_str(&cwd.join(&self.config.compile_lib_path).to_string_lossy()); | ||
host_dylib_env_paths.push(':'); | ||
host_dylib_env_paths.push_str(&env::var(dylib_env_var()).unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might need to use std::env::join_paths
because dylib_env_var()
expands to PATH
on Windows, but Windows uses ;
for PATH
separator unlike :
for everyone else. std::env::join_paths
should handle this properly for the host platform at least. Expanding dylib_env_var()
into its constituent paths will also need to use std::env::split_paths
, and then repiece individual paths together with std::env::join_paths
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I initially added the v2 infra, I was not aware std::env::join_paths
existed and that Windows used ;
separators for PATH
not :
, so there may be a couple more places where this bug exists that may have misled you into writing this (sorry 😆)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did wonder about that, but decided to leave it alone for the moment. I'll update these now.
Perhaps the is_windows()
bit in run_make_support::run
is also related? That seemed odd to me, but I don't want to touch Windows if it's working... 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rust/src/tools/run-make-support/src/run.rs
Lines 15 to 34 in f13f37f
cmd.env(&ld_lib_path_envvar, { | |
let mut paths = vec![]; | |
paths.push(PathBuf::from(env::var("TMPDIR").unwrap())); | |
for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) { | |
paths.push(p.to_path_buf()); | |
} | |
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) { | |
paths.push(p.to_path_buf()); | |
} | |
env::join_paths(paths.iter()).unwrap() | |
}); | |
if is_windows() { | |
let mut paths = vec![]; | |
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { | |
paths.push(p.to_path_buf()); | |
} | |
paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf()); | |
cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); | |
} |
This bit is almost completely wrong, I did not know better at the time when this was written (I realize this is terribly broken now) 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll put up a fix for this lol EDIT: actually, could you propagate the fix for run_make_support::run
as well? The logic in there for the ld_lib_path_envvar()
should just use set_host_rpath()
. All of
cmd.env(&ld_lib_path_envvar, {
let mut paths = vec![];
paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) {
paths.push(p.to_path_buf());
}
for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
paths.push(p.to_path_buf());
}
env::join_paths(paths.iter()).unwrap()
});
if is_windows() {
let mut paths = vec![];
for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
paths.push(p.to_path_buf());
}
paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf());
cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
}
is just set_host_rpath()
but actually wrong I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I remember why there was a is_windows()
: you're right, but conditionally right...
RUN
has different environments depending on platform:
Lines 85 to 116 in 616a8f8
ifeq ($(UNAME),Darwin) | |
RUN = $(TARGET_RPATH_ENV) $(EXECUTE) | |
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 | |
DYLIB_GLOB = lib$(1)*.dylib | |
DYLIB = $(TMPDIR)/lib$(1).dylib | |
STATICLIB = $(TMPDIR)/lib$(1).a | |
STATICLIB_GLOB = lib$(1)*.a | |
else | |
ifdef IS_WINDOWS | |
RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) | |
FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0 | |
DYLIB_GLOB = $(1)*.dll | |
DYLIB = $(TMPDIR)/$(1).dll | |
ifdef IS_MSVC | |
STATICLIB = $(TMPDIR)/$(1).lib | |
STATICLIB_GLOB = $(1)*.lib | |
else | |
IMPLIB = $(TMPDIR)/lib$(1).dll.a | |
STATICLIB = $(TMPDIR)/lib$(1).a | |
STATICLIB_GLOB = lib$(1)*.a | |
endif | |
BIN = $(1).exe | |
LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)") | |
else | |
RUN = $(TARGET_RPATH_ENV) $(EXECUTE) | |
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0 | |
DYLIB_GLOB = lib$(1)*.so | |
DYLIB = $(TMPDIR)/lib$(1).so | |
STATICLIB = $(TMPDIR)/lib$(1).a | |
STATICLIB_GLOB = lib$(1)*.a | |
endif | |
endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. on windows it's RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE)
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Safe to say, there's a lot of weird legacy there...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think then it's fine to leave run()
as is, I'll go back to fix run()
in a follow up PR. I don't want to block this PR for a different bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed #123832 to make sure I double check run_make_support::run
Also maybe edit PR CI to run |
All clear! |
28b7bdf
to
7e171c7
Compare
Thanks! |
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#123599 (remove some things that do not need to be) - rust-lang#123763 (Set the host library path in run-make v2) - rust-lang#123775 (Make `PlaceRef` and `OperandValue::Ref` share a common `PlaceValue` type) - rust-lang#123789 (move QueryKeyStringCache from rustc_middle to rustc_query_impl, where it actually used) - rust-lang#123826 (Move rare overflow error to a cold function) - rust-lang#123827 (linker: Avoid some allocations in search directory iteration) - rust-lang#123829 (Fix revisions syntax in cfg(ub_checks) test) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#123763 - cuviper:host-rpath-run-make-v2, r=jieyouxu Set the host library path in run-make v2 When the build is configured with `[rust] rpath = false`, we need to set `LD_LIBRARY_PATH` (or equivalent) to what would have been the `RPATH`, so the compiler can find its own libraries. The old `tools.mk` code has this environment prefixed in the `$(BARE_RUSTC)` variable, so we just need to wire up something similar for run-make v2. This is now set while building each `rmake.rs` itself, as well as in the `rust-make-support` helpers for `rustc` and `rustdoc` commands. This is also available in a `set_host_rpath` function for manual commands, like in the `compiler-builtins` test.
When the build is configured with
[rust] rpath = false
, we need to setLD_LIBRARY_PATH
(or equivalent) to what would have been theRPATH
,so the compiler can find its own libraries. The old
tools.mk
code hasthis environment prefixed in the
$(BARE_RUSTC)
variable, so we justneed to wire up something similar for run-make v2.
This is now set while building each
rmake.rs
itself, as well as in therust-make-support
helpers forrustc
andrustdoc
commands. This isalso available in a
set_host_rpath
function for manual commands, likein the
compiler-builtins
test.