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

Cargo metadata doesn't include actual filename of binary targets #5866

Open
kornelski opened this issue Aug 5, 2018 · 12 comments
Open

Cargo metadata doesn't include actual filename of binary targets #5866

kornelski opened this issue Aug 5, 2018 · 12 comments
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-metadata S-needs-team-input Status: Needs input from team on whether/how to proceed.

Comments

@kornelski
Copy link
Contributor

I'm writing a tool that needs to compile a Cargo project, and copy all executables out of it. This seems to be impossible to do with only the information that Cargo provides.

cargo metadata includes a list of binary targets and their names, but mapping from name to filename is target-specific (e.g. .exe appended on Windows). This is further complicated by cross-compilation, so std's EXE_SUFFIX constant is not sufficient.

Could you expand cargo metadata output to include names of executables? Ideally with a path including the target directory, because that too is variable depending on environment and target.

@ehuss
Copy link
Contributor

ehuss commented Aug 5, 2018

This is similar to #3670.

Do you explicitly need to use cargo metadata? One option is to use cargo build --message-format=json which will tell you the full path names (included exe suffix).

@kornelski
Copy link
Contributor Author

Yes, it's preferred as I want to set up my config/paths before running the build. I also have an option to let user call the build themselves and just let me pack the results, so even build output wouldn't be sufficient in all cases.

@alexcrichton alexcrichton added Command-metadata C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` labels Aug 6, 2018
@matklad
Copy link
Member

matklad commented Aug 7, 2018

@kornelski curious, would --out-dir help here? Running cargo build -Z unstable-options --out-dir ./out --bin foo puts the binary to the ./out dir, and you can grab it from there.

The "binary name" is a tricky business, because binary is not necessary a single file. Debug info might be a separate file, and I believe at least at some point WASM targter generated a .wasm and .js files for a binary.

@kornelski
Copy link
Contributor Author

Nah, it's hacky. I'd have to scan the directory and guess what is a main binary and what is some debug or temp file.

Could you expose something like:

"main_binary": "target/triple/release/file.exe",
"auxiliary_files": ["target/triple/release/file.dsym"],

@matklad
Copy link
Member

matklad commented Aug 7, 2018

what is some debug or temp file.

--out-dir does not produce temp files. Ie, it's completely not like the target dir, which is a kitchen sink. It does include debug-info though, and there's no non-hacky solutions to filter that out (except for not producing a debug info in the first place).

@ehuss
Copy link
Contributor

ehuss commented Jun 24, 2019

This may be a dupe of #2508.

@epage epage added the S-needs-team-input Status: Needs input from team on whether/how to proceed. label Oct 23, 2023
@bitdivine
Copy link

Given that the subject seems to be executables, does it make sense to put such functionality behind a sort of --dry-run flag for cargo run? After all, carg run has to solve the same problem of figuring out what executables there are internally. Maybe cargo run --dry-run combined with some flag to make the output machine readable?

@bitdivine
Copy link

A different angle of attack - how complicated is this logic actually? Isn't the list of executables given by something like:

git ls-files | grep -E '\/Cargo.toml$' | xargs -I{} yq -oy '.package.name as $pn | .bin[] |.name // $pn' {}

i.e. for every [bin] in a Cargo.toml get the .name field, defaulting to the package name if it is not there.

@bitdivine
Copy link

Finding the TARGET_DIR might be a bit harder as the platform varies between projects. The platform can be specified in the .cargo/config, so for example:

some-embedded-project$ yq -p toml -oy '"target/" + ((.build.target | . + "/") // "") + "release"' < .cargo/config 
target/thumbv7em-none-eabihf/release

and

a-native-project$ yq -p toml -oy '"target/" + ((.build.target | . + "/") // "") + "release"' < .cargo/config 
target/release

and of course a project might not have a config file at all. One would have to look at the cargo specs to be sure that this covers all options.

@epage
Copy link
Contributor

epage commented Nov 6, 2023

If you are ok doing this with a build, you can use something like escargot to run a build and to capture what executables were made. I use this in compile-examples to test my examples.

@bitdivine
Copy link

In my case there is required to be a strict separation between building and other steps so escargot won't work for that project but I might try it somewhere else. Thanks for the pointer!

@kornelski
Copy link
Contributor Author

This is still an issue. In both cargo-xcode and cargo-deb I have to hardcode assumptions about the directory and file name of the binaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted` Command-metadata S-needs-team-input Status: Needs input from team on whether/how to proceed.
Projects
None yet
Development

No branches or pull requests

6 participants