-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Provide access to project paths for tests #2841
Comments
The root directory may be accessible somehow through the Does that help? |
Same for most other environment variables which might contain useful paths, the exception being I was able to get the paths I want anyway, but it's a horrible hack. // Get absolute path to the "target" directory ("build" dir)
fn get_target_dir() -> PathBuf {
let bin = env::current_exe().expect("exe path");
let mut target_dir = PathBuf::from(bin.parent().expect("bin parent"));
while target_dir.file_name() != Some(OsStr::new("target")) {
target_dir.pop();
}
target_dir
}
// Get absolute path to the project's top dir, given target dir
fn get_top_dir<'a>(target_dir: &'a Path) -> &'a Path {
target_dir.parent().expect("target parent")
} |
I'm somewhat wary of just keeping to pile on tons of environment variables, in general strategies like this are pretty brittle because there's no guarantee these directories exist when the binary is actually run as any number of events could have happened between compile time and execution time. Ah but yeah I believe |
I wouldn't want to compile the output directory into a release binary, but paths are needed somehow and test binaries don't usually move. The question is which is the least brittle assumption?
What I'm saying is that Cargo docs should cover this somehow. I don't see anything too evil about adding a few environment variables either, so long as the documentation is kept up-to-date. |
Ah yeah of those assumptions I think (2) is the least brittle, and I'd be totally fine documenting it! |
Since Cargo supports out-of-source builds neither options (1) or (2) will work reliably. IMO "trying not to pile on a ton of environment variables" sounds a bit like Cargo is trying to bind the hands of developers, rather than help them. Cargo is just a tool and should include the features users need. |
EDIT: I had a look at the code, things are more complicated than I thought, so nevermind :) long read: If Basically As to why would I need this for my particular case: I need to hardcode the compiledexe fullpath filename so that when I detect hardlinks to this exe(by other means), I can then show a message pointing to the real exe which would be the only updated(recompiled) one. (the hardlink binary would be the outdated one) EDIT: ok this is what I'm gonna be using locally: diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs
index ea9294fd..3e1f2595 100644
--- a/src/cargo/ops/cargo_rustc/mod.rs
+++ b/src/cargo/ops/cargo_rustc/mod.rs
@@ -889,6 +902,36 @@ fn build_base_args<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
opt(cmd, "-C", "linker=", cx.linker(unit.kind).map(|s| s.as_ref()));
cmd.args(&cx.incremental_args(unit)?);
+ let mut bin_outfile_full_path=Option::None;
+ for &(ref dst, ref link_dst, file_type) in cx.target_filenames(&unit)?.iter() {
+ if file_type != TargetFileType::Normal {
+ continue
+ }
+ let bindst = match *link_dst {
+ Some(ref link_dst) => link_dst,
+ None => dst,
+ };
+
+ if bin_outfile_full_path.is_some() {
+ error!("!! Already set bin_outfile_full_path='{}' This is unexpected. Should've been set only once! FIXME: investigate what caused this!",bin_outfile_full_path.clone().unwrap());
+ assert!(bin_outfile_full_path.is_none());
+ } else {
+ bin_outfile_full_path=Option::Some(bindst.display().to_string());
+ cmd.env("CARGO_TARGET_BINFILE_FULLPATH",bindst.display().to_string()); //alright this makes it work in src/main.rs with env!() macro! eg. const OUTPUT_EXE_AT_COMPILETIME: &'static str = env!("CARGO_TARGET_BINFILE_FULLPATH");
+ //the following is needed specifically for build.rs availability of the same env. var:
+ {
+ let a=cx.compilation.extra_env.entry(
+ unit.pkg.package_id().clone()
+ )
+ .or_insert_with(Vec::new);
+ a.push(("CARGO_TARGET_BINFILE_FULLPATH".to_string(), bin_outfile_full_path.clone().unwrap_or("".to_string()))); //for build.rs availability! via eg. println!("Here's CARGO_TARGET_BINFILE_FULLPATH={}", env::var("CARGO_TARGET_BINFILE_FULLPATH").unwrap());
+ }
+ debug!("CARGO_TARGET_BINFILE_FULLPATH={}",bin_outfile_full_path.clone().unwrap_or("".to_string()));
+ }
+ //debug!("!! 3333333333333333333 {}", bindst.display());
+ }//for
+
+
Ok(())
}
|
As there hasn't been any activity here in over 6 months I've marked this as stale and if no further activity happens for 7 days I will close it. I'm a bot so this may be in error! If this issue should remain open, could someone (the author, a team member, or any interested party) please comment to that effect? The team would be especially grateful if such a comment included details such as:
Thank you for contributing! (The cargo team is currently evaluating the use of Stale bot, and using #6035 as the tracking issue to gather feedback.) If you're reading this comment from the distant future, fear not if this was closed automatically. If you believe it's still an issue please leave a comment and a team member can reopen this issue. Opening a new issue is also acceptable! |
This issue is definitely stale (no active interest), but I don't believe it was solved. There are a host of environment variables available, but I don't see a documented way of accessing the source path or creating temporary files for tests. Build scripts do have documented access to the source (the working directory) and the output ( And now I've just spend five minutes summarizing a stale issue because of this bot; not sure whether that's a good or bad thing. |
I've found summaries help move issues forward, so thank you! |
Because this was quite a while ago now: has anything changed since this issue was created? Since Cargo has tests for itself and (presumably) modifies the filesystem during them, how does Cargo handle it? |
Reading files from the project can be done by accessing For writing, using a temp directory is probably the safest choice. The Cargo's testsuite writes to the |
This is a hack which doesn't work for doc-tests but the previous approach didn't work for workspaces. Given that the expectation is that these files will most likely be used in integration tests I'm going with this approach. See: rust-lang/cargo#2841
Has there been any progress on this? I've just hit the same issue: my tests need external data files and I need to access the path to those files from the tests. |
Add CARGO_TARGET_TMPDIR env var for integration tests & benches Hi. Recently I [ran into](https://github.com/vojtechkral/bard/blob/main/tests/util/mod.rs#L32) the problem that integration tests don't have a good way to figure out where `target` dir is. Knowing where `target` is is useful for integration tests that need to setup some filesystem structure for test cases. In fact `cargo` itself does this too (and figures out the path rather clumsily). Another popular way of doing this is to create a directory in `/tmp` (or quivalent on other systems), however, I believe using subdirectory in `target` is better as testcases are easier to debug that way and temporary locations aren't polluted. I think this would also address some concerns in #2841 Another solution might be to provide a dedicated subdirectory in `target` for this, something like `target/scratchpad`, but I'm not convinced this is warranted... Edit: That's what was decided to do, see below... Let me know what you think 🙂
Now that #9375 is merged, I'd propose to close this issue, seems like it's been addressed.
|
Thanks for the summary @vojtechkral. I'll close as recommended since I currently have no use-case to test with. |
I need a test binary to read some data files from the project's repository and write some new files to a temporary location.
I've done this before with CMake, which provides variables like
CMAKE_SOURCE_DIR
,CMAKE_CURRENT_SOURCE_DIR
,CMAKE_BINARY_DIR
(doc) which can be substituted into "configured" source code/script files or passed to tests. The distinction between source and binary directories is important especially since the source directory may not be writable; is this also the case with Cargo?It is possible for Cargo tests to get the path to the current binary as well as the working directory, but I'd prefer a documented way of getting the project's root directory (e.g. via an environment variable or optional command-line argument), and some recommendations on where to put temporary files.
The text was updated successfully, but these errors were encountered: