Description
EDIT: 90% of this is solved by --message-format=json
flag.
Hi! This is a followup of #1924 and #1726.
Problem
Sometimes one needs to run an executable produced by Cargo (be it example, binary or doc/unit/integration test) directly.
The most common use case is debugger integration in the IDE, but other examples include strace
, perfrecord
and similar tools.
Peculiarities
cargo test
can produce more than one binary. We need to handle this somehow.
Both cargo run
and cargo test
have different flavors for specifying profiles, features, targets and arguments for the binary. Ideally, it should be easy to learn the name of output file by the cargo command.
Cargo can setup LD_LIBRARY_PATH
when running a binary, it would be good to be able replicate this as well.
Solutions
--with
wrapper
Add a --with
option to the run family of commands to allow to specify a custom wrapper. There's a stale pull request implementation in #1763.
This would probably be the most useful option on the command line. However, it is not flexible enough: there's still an intermediate Cargo process around, and this won't be enough for IntellJ Rust: we launch debugger process first and then send it a command to launch the debugee.
Also, this can be implemented as an external subcommand on top of other options, so that you can run
cargo with-wrapper strace run --release --bin foo
.
--output-file
option
We can implement #1706, than clients could specify the name they want. This is a nice option, but it's not perfect: the binary may assume certain location and use something like ../../foo/bar
to get resources at run time or something like that. While arguably you should not do this, ideally we should be able able to run binaries exactly as Cargo does. Also with explicit output file the client has to manage temporary directories, which is some extra work.
Stable file names
We can make the names of binaries predictable. This is perhaps the simplest option, but I don't like it for various reasons:
-
We already have
debug
andrelease
profiles, which affect the output path. This means that clients should implement some logic to get the current profile, which may be brittle. -
This requires stabilizing target directory layout and may make future features harder. What if one day we would like to add custom profiles and an ability to configure the custom profile via environment variables/config files?
-
This does not allow to easily derive the binary name given the cargo command, which again means some logic on the client's side.
Add file names to cargo metadata
This is very similar to the previous option, and does not solve the profiles problem at all.
Print the resulting file name with --no-run
This is my favorite option :)
-
It is naturally forward compatible.
-
It's naturally extendable to print more information about the environment which is used to run the process (
LD_LIBRARY_PATH
, command line flags). -
We
almostdo this already: with--message-format=json
we print the path to binaryif it is not fresh. I suggest that we always output this info, even we don't actually rebuild the binary. Perhaps we should use a new, separate message, to make it easier to extend it to support additional and to make it easier for the clients to separate dependencies from the actual end binaries.(Emit more info on --message-format=json #3319, Always produce artifact messages #3752) -
It would be trivial to match cargo commands with binary names: just add
--no-run
option (I'd like to add this flag tocargo run
as well). -
I like that on the client side, you have to actually build the binary before trying to use it. This solves debugging stale binaries problem by construction.
I'll be glad to implement any of these options :)