Search code examples
rustrust-cargo

Is there a Cargo environment variable for the workspace directory?


I have the following projects in a workspace:

Workspacefolder
 |
 +-- Project A
 |    |
 |    +-- build.rs
 |
 +-- Dep
 |    |
 |    +-- test.json  
 |
 +-Cargo.toml

In Project A, there is build.rs that wants to open test.json in a way that doesn't rely on platform and that works well with CI.

I'm looking for a CARGO_WORKSPACE environment variable, because then I can say Path::new(&workspace_dir).join("/Dep/test.json").


Solution

  • No, not for the version of Cargo bundled with Rust 1.16.0. You can verify this yourself by printing out all of the environment variables in the build script:

    use std::fs::File;
    use std::io::Write;
    
    fn main() {
        let mut dump = File::create("/tmp/dump").expect("unable to open");
        for (k, v) in std::env::vars() {
            writeln!(&mut dump, "{} -> {}", k, v).expect("unable to write")
        }
    }
    

    On my machine, this produces:

    $ sort /tmp/dump | grep CARGO
    CARGO_CFG_DEBUG_ASSERTIONS ->
    CARGO_CFG_TARGET_ARCH -> x86_64
    CARGO_CFG_TARGET_ENDIAN -> little
    CARGO_CFG_TARGET_ENV ->
    CARGO_CFG_TARGET_FAMILY -> unix
    CARGO_CFG_TARGET_OS -> macos
    CARGO_CFG_TARGET_POINTER_WIDTH -> 64
    CARGO_CFG_UNIX ->
    CARGO_HOME -> /Users/shep/.cargo
    CARGO_MANIFEST_DIR -> /private/tmp/the-workspace/project-a
    CARGO_PKG_AUTHORS -> An Devloper <an.devloper@example.com>
    CARGO_PKG_DESCRIPTION ->
    CARGO_PKG_HOMEPAGE ->
    CARGO_PKG_NAME -> project-a
    CARGO_PKG_VERSION -> 0.1.0
    CARGO_PKG_VERSION_MAJOR -> 0
    CARGO_PKG_VERSION_MINOR -> 1
    CARGO_PKG_VERSION_PATCH -> 0
    CARGO_PKG_VERSION_PRE ->
    

    I'm not sure why you can't just do

    Path::new(&manifest_dir).join("..").join("Dep").join("test.json")
    

    I've split each directory into a separate call — avoiding the need to specify the directory separator at all to be platform agnostic.