rust-cross / cargo-zigbuild

Compile Cargo project with zig as linker
MIT License
1.43k stars 51 forks source link

Command::new("cargo-zigbuild") doesn't shutdown when aborting #194

Closed cybersoulK closed 10 months ago

cybersoulK commented 10 months ago
let mut process = tokio::process::Command::new("cargo-zigbuild")
                .args(["zigbuild", "--bin", &bin, "--target", &target, release])
                .spawn().unwrap();

 tokio::time::sleep(Duration::from_secs(4)).await;
let res = process.kill().await; 
println!("{res:?}");

process.wait().await.unwrap();

It prints Ok(()) to console, but continues running.

tried the following as well: (both std::process and tokio::process have the same issue)

Command::new("cargo-zigbuild").arg("build") 
and
 Command::new("cargo").arg("zigbuild")

The following works:

 Command::new("cargo").arg("build") 

I asked the rust community, they think this behaviour is weird. This is what they suggested the issue was:

Perhaps they forgot to install this signal handler.

I need the correct behaviour for automating my builds, and allow it to abort on an external signal. thank you!

cybersoulK commented 10 months ago

oh, my compilation machine OS is mac ventura 13.4 if that's useful.

messense commented 10 months ago

You are welcome to investigate and send PRs to fix it.

konnorandrews commented 10 months ago

For anyone else that encounters this you can use https://docs.rs/command-group/latest/command_group/index.html to spawn cargo-zigbuild in a process group which then can be killed. This is what a terminal does (and why ctrl-c works as expected). It may still be a good idea to add a custom ctrl-c handler to cargo-zigbuild to make this usecase easier.

For those that don't want to use command_group you can use the following.

// Set the process group to the child's process ID (works only on unix systems)
command.process_group(0);

...

// Perform the kill by sending a signal to the *process group* instead of just the one process.
// signal is from the nix crate
signal::killpg(Pid::from_raw(child.id() as _), Signal::SIGINT).unwrap(); // note the signal used here can be changed if needed.

// continue with child cleanup like .wait()
cybersoulK commented 10 months ago

This worked! Thank you so much!

I forked zigbuild and i tried for several hours, but i don't have enough experience to make this feature work.