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 run --example false positive "is a library and cannot be executed" #6159

Closed
Walther opened this issue Oct 10, 2018 · 2 comments · Fixed by #6330
Closed

cargo run --example false positive "is a library and cannot be executed" #6159

Walther opened this issue Oct 10, 2018 · 2 comments · Fixed by #6330
Assignees
Labels
A-examples Area: example targets A-manifest Area: Cargo.toml issues C-bug Category: bug

Comments

@Walther
Copy link

Walther commented Oct 10, 2018

RustAudio/vst-rs#71

In rust-vst's Cargo.toml, there is the following definition:

[[example]]
name = "simple_host"
crate-type = ["bin"]

among other example declarations which are crate-type = ["cdylib"] instead.

Trying to run it:

cargo run --example simple_host
error: example target `simple_host` is a library and cannot be executed

However, if you simply remove the line crate-type = ["bin"], it starts working.

<&mbrubeck> Walther: I think the bug is here https://github.com/rust-lang/cargo/blob/master/src/cargo/core/manifest.rs#L654-L658
<&mbrubeck> Any non-empty list is treated as ExampleLib, which triggers https://github.com/rust-lang/cargo/blob/master/src/cargo/ops/cargo_run.rs#L40-L45

@Walther
Copy link
Author

Walther commented Oct 10, 2018

Looking at

pub fn example_target(
name: &str,
crate_targets: Vec<LibKind>,
src_path: PathBuf,
required_features: Option<Vec<String>>,
edition: Edition,
) -> Target {
let kind = if crate_targets.is_empty() {
TargetKind::ExampleBin
} else {
TargetKind::ExampleLib(crate_targets)
};
it seems there's a heavy assumption that examples will only ever be libraries.

If one changes the type signature to Vec<TargetKind>, line 655 TargetKind::ExampleLib(crate_targets) errors because ExampleLib cannot take TargetKind as an input. Additionally, there's a new error in line 355

fn clean_examples(
features: &Features,
toml_examples: Option<&Vec<TomlExampleTarget>>,
package_root: &Path,
edition: Edition,
autodiscover: Option<bool>,
warnings: &mut Vec<String>,
errors: &mut Vec<String>,
) -> CargoResult<Vec<Target>> {
let inferred = infer_from_directory(&package_root.join("examples"));
let targets = clean_targets(
"example",
"example",
toml_examples,
&inferred,
package_root,
edition,
autodiscover,
warnings,
errors,
"autoexamples",
)?;
let mut result = Vec::new();
for (path, toml) in targets {
let crate_types = match toml.crate_types() {
Some(kinds) => kinds.iter().map(|s| s.into()).collect(),
None => Vec::new(),
};
let mut target = Target::example_target(
&toml.name(),
crate_types,
path,
toml.required_features.clone(),
edition,
);
configure(features, &toml, &mut target)?;
result.push(target);
}
Ok(result)
}
caused by the .into() call:

the trait `std::convert::From<&std::string::String>` is not implemented for `core::manifest::TargetKind`

How should this be handled?

  • Should we change the type of crate_targets in fn example_target(), and implement the conversion from string to TargetKind as well? How could that be done cleanly, with minimal repetition ref. LibKind's conversion method?
  • Should we instead create some sort of an ExampleKind wrapper so that within fn clean_examples() method in targets.rs the into() call can be more restricted?
  • Should we just keep the type as crate_targets: Vec<LibKind>, and blindly rely on the LibKind::Other -catch-all in the conversion, and parse for an Other-type and see if it contains a "bin" value? This would feel a bit dirty. On the other hand, that's exactly the codepath that is happening right now for examples with "bin" declared as the type
  • On an even broader scope, how should we handle these crate_targets being Vec's - is it valid to have an example with both "lib" and "bin" target? What should happen then? What about possible other lists of targets?

(Additionally, while looking through the code, it seems that LibKind type doesn't even know about cdylib at all in manifest.rs. Should it? If so, that's probably a subject for a new issue? )

@alexcrichton
Copy link
Member

Thanks for the report, this definitely sounds like a bug! I agree that we should do some actual parsing here and realize that the string bin is a binary, not actually a library.

I'd be down for basically any fix that works here, feel free to refactor as necessary!

@alexcrichton alexcrichton added C-bug Category: bug A-examples Area: example targets A-manifest Area: Cargo.toml issues labels Oct 11, 2018
@dwijnand dwijnand self-assigned this Nov 18, 2018
bors added a commit that referenced this issue Nov 19, 2018
Allow crate_type=bin examples to run

Fixes #6159
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-examples Area: example targets A-manifest Area: Cargo.toml issues C-bug Category: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants