Rust Command specify cwd

#1
  1. I currently have:

use std::os;
use std::process::Command;

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    println!("cargo:rerun-if-changed=cu/main.cu");
    println!("cargo:rerun-if-changed=cu/a_util/map.cu");
    println!("cargo:rerun-if-changed=cu/a_util/reduce.cu");
    println!("cargo:rerun-if-changed=cu/b_prim/adam_update.cu");
    println!("cargo:rerun-if-changed=cu/b_prim/softmax.cu");

    if cfg!(target_os = "linux") {
        Command::new("make").status().expect("failed to run Make");
    }

}
  1. I want to change the directory the “make” is run from. How do I do this?

  2. This is a followup to: 'pre-hook' on cargo test? , and everything is in a build.rs

'pre-hook' on cargo test?
#2

https://doc.rust-lang.org/std/process/struct.Command.html#method.current_dir

1 Like
#3

Thanks! I now have:

use std::os;
use std::process::Command;

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    println!("cargo:rerun-if-changed=cu/main.cu");
    println!("cargo:rerun-if-changed=cu/Makefile");
    println!("cargo:rerun-if-changed=cu/a_util/map.cu");
    println!("cargo:rerun-if-changed=cu/a_util/reduce.cu");
    println!("cargo:rerun-if-changed=cu/b_prim/adam_update.cu");
    println!("cargo:rerun-if-changed=cu/b_prim/softmax.cu");

    if cfg!(target_os = "linux") {
        Command::new("make")
            .current_dir("cu/")
            .status()
            .expect("failed to run make");
    }
}

Here is the situation. If instead of executing “make”, I execute “ma3ke” (a non existant command), “cargo build” fails – which is good.

However, if I execute “make” – even if executing cu/Makefile fails … the build process still succeeds, which is bad. I want to setup it up so that if executing the Makefile fails, then the "cargo build "should also fail. How can I do that?

In particular, my problem is

cd cu && make <-- this fails
cargo build <-- this succeeds, despite knowing that executing make in ./cu fails
#4

You could have a look at how they use the return from status(): https://doc.rust-lang.org/std/process/struct.Command.html#method.status

Or, if you want to also “see” the output: https://doc.rust-lang.org/std/process/struct.Command.html#method.output

2 Likes
#5

@xftroxgpx : That worked; thanks! Lesson learned – I need to read documentation mor closely. :slight_smile:

2 Likes
#6

I opted to give hints instead, because what you learn sticks best when you figure it out yourself, imho :slight_smile:

1 Like
#7

It might be more robust to use env!("CARGO_MANIFEST_DIR") to construct an absolute path to the cu dir and pass that absolute path to .current_dir().

#8

Depending on what you’re looking for, and presuming you’re indeed only running the command on unix-like systems, you might try exec: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.exec

In case you’re not familiar with exec: instead of running a command a sub-process, exec instead replaces the current process with another process. So if you find yourself running an external command as a final stage in your application/script (and you don’t need to do any sort of exit status translation or custom cleanup post-execution, etc.), exec is a pretty great solution.