Skip to content
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

Feature request: cargo run --no-build #11507

Closed
mcclure opened this issue Dec 23, 2022 · 5 comments
Closed

Feature request: cargo run --no-build #11507

mcclure opened this issue Dec 23, 2022 · 5 comments
Labels
A-layout Area: target output directory layout, naming, and organization C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-run

Comments

@mcclure
Copy link

mcclure commented Dec 23, 2022

Problem

I want to run cargo run. But I don't want to build first. I just want to run the last built executable.

Why might I want this? Two good-ish reasons might be

  1. The build is slow (null builds are pretty fast! … unless your program takes microseconds to run in which case maybe you start to think about runtime).

  2. Say I want to pass a --cfg flag to rustc. Also say I'm in a situation¹ where I can't easily set environment variables. The best way I have figured out how to do this with cargo is:

     cargo.exe rustc -- --cfg 'mycfg="val"' && cargo.exe run -- program-arguments
    

    But wait!! This breaks because cargo.exe run doesn't have the --cfg, so it triggers a rebuild without the cfg.

    (Maybe there's a better way to do this specific thing [pass a --cfg to rustc through cargo], but that's not the point, the point is I find myself in a situation which is easy to resolve if a cargo can run without building and awkward if it can't.)

Proposed Solution

cargo run should have a --no-build or perhaps --previous-build option. If there is no previous build of the desired configuration (debug/run), it quits with an error.

Notes

Why not just run the executable?

The executable paths are at short, but nonobvious paths like target/release/someexe.exe. You might not know the executable name without looking it up; and under mildly unusual circumstances, there may be more than one exe in the target/config folder (for example, try doing cargo run, changing the executable name in Cargo.toml, then doing cargo run again) which can frustrate using tab-completion. I couldn't tell you off the top of my head, when you cargo run an --example, where that executable gets stored. cargo run incidentally spits out the executable path for you, which is super nice, but some other ways of building (like cargo rustc) don't, and maybe you cleared your terminal or something.

In short, cargo run has zero-friction, magic builtin logic for running the executables it created and you develop muscle memory for using it. But we are only given access to that logic when performing a build. There are many non-build situations when it would be most convenient to use cargo's logic instead of resorting to using the human brain, a machine that took 3.7 billion years to develop and is vastly overqualified for this task, to figure the path out

Could this be an external app?

One could imagine an external plugin crate that added a cargo run-no-build verb to cargo, but it would be best to do it through cargo run itself because this would ensure all the various sub-logics (--example, --release) are exactly in sync with the user's cargo version.

¹ WSL1

@mcclure mcclure added the C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` label Dec 23, 2022
@weihanglo
Copy link
Member

Thank you for this proposal. This is quite interesting. However, Cargo currently has no mechanism of memorizing each build. It's not easy for Cargo to find which artifact was built from the previous build. For example, using --out-dir changes output paths of artifacts. Another is specifying --target triple. Cargo needs to guess what have been built previous, which is not reliable.

At this moment, a tip from old me is using JSON message format with jq, such as

# !!! Use at your own risk
cargo build --message-format=json -q | jq -r 'select(.target.kind[0] == "bin") | .executable'

@weihanglo weihanglo added Command-run A-layout Area: target output directory layout, naming, and organization labels Dec 29, 2022
@weihanglo
Copy link
Member

BTW, is it a kind of duplicate of #3670?

@mcclure
Copy link
Author

mcclure commented Dec 29, 2022

#3670 does seem to be a more developed version of the same proposal.

Cargo needs to guess what have been built previous, which is not reliable.

Here's a question. If I run:

$ cargo.exe run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target\debug\rps.exe`

It printed the .exe at that moment, so it knew it at that moment what the "run" executable name was, as long as I ran run and not build. But it seems this information is getting thrown away?

Could Cargo remember the last path printed in that "Running" bark, or possibly remember a separate last-path for each configuration/--example? That would seem (?) to provide a simple way to implement, at least, something like a cargo rerun. It would only work if run has been run once already, but it would still be useful for some purposes, and would have some advantages over that message-format hack (for example, if a build command produces more than one executable, would the json hack definitely produce the right results?). This suggestion is starting to sound too sloppy for a core Cargo feature though.

@weihanglo
Copy link
Member

for example, if a build command produces more than one executable, would the json hack definitely produce the right results?

jq parses JSON messages line by line so it should work as expected.

Could Cargo remember the last path printed in that "Running" bark, or possibly remember a separate last-path for each configuration/--example?

It could, but needs more design works that looks after other parts of Cargo. For example, Cargo team has discussed an idea of embedding a database in Cargo for storing caches and artifacts information. Cargo then can provide a way to query them on-demand. We can extend that proposal to persist information of each build. This is still in exploration, though.

#3670 does seem to be a more developed version of the same proposal.

If you feel good, I'll suggest closing this in favor of #3670 :)

@mcclure
Copy link
Author

mcclure commented Dec 29, 2022

If you feel good, I'll suggest closing this in favor of #3670 :)

Well, I'd like to see #3670 implemented, but otherwise yes.

@mcclure mcclure closed this as completed Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-layout Area: target output directory layout, naming, and organization C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-run
Projects
None yet
Development

No branches or pull requests

2 participants