Search code examples
rustrust-cargorust-crates

Why does clap fail to compile when added to Cargo.toml?


Summary

I'm fairly new to Rust and decided to use it to port an existing project into it. I intended to use clap to handle CLI options, but I keep getting errors.

What do I need to do for clap to install correctly so that it's usable in my project as a dependency (e.g. extern crate clap; [...] use clap::App; [...]?

I haven't had problems with other crates (so far), so I'm not sure what's so different here or if there's a problem with the crate itself.

I've already seen a few questions (e.g. this one), which simply suggests that the dependency be added into the .toml file or don't seem to provide a solution to what I'm seeing.

I'm in Ubuntu Linux, if that makes a difference.

What I Tried

Adding clap = "2.33.0" to my Cargo.toml file (see https://crates.io/crates/clap) causes VSCode (through RLS) to log the following:

{
    "resource": "[...]/Projects/takeout/Cargo.toml",
    "owner": "rust",
    "severity": 8,
    "message": "Could not compile `clap`.\nprocess didn't exit successfully: `[...]/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rls --crate-name clap [...]/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-2.33.0/src/lib.rs --color never --crate-type lib --emit=dep-info,metadata -C debuginfo=2 --cfg 'feature=\"ansi_term\"' --cfg 'feature=\"atty\"' --cfg 'feature=\"color\"' --cfg 'feature=\"default\"' --cfg 'feature=\"strsim\"' --cfg 'feature=\"suggestions\"' --cfg 'feature=\"vec_map\"' -C metadata=630980a214d5fd10 -C extra-filename=-630980a214d5fd10 --out-dir [...]/Projects/takeout/target/rls/debug/deps -L dependency=[...]/Projects/takeout/target/rls/debug/deps --extern ansi_term=[...]/Projects/takeout/target/rls/debug/deps/libansi_term-1510a9addefc0253.rmeta --extern atty=[...]/Projects/takeout/target/rls/debug/deps/libatty-7c4847fd9fc1e3d9.rmeta --extern bitflags=[...]/Projects/takeout/target/rls/debug/deps/libbitflags-8369a9aec15a5abb.rmeta --extern strsim=[...]/Projects/takeout/target/rls/debug/deps/libstrsim-301d1cf239e9cd24.rmeta --extern textwrap=[...]/Projects/takeout/target/rls/debug/deps/libtextwrap-a799d71e2d028df4.rmeta --extern unicode_width=[...]/Projects/takeout/target/rls/debug/deps/libunicode_width-58e38dd9d658dcfb.rmeta --extern vec_map=[...]/Projects/takeout/target/rls/debug/deps/libvec_map-4f8e59c92e9953d8.rmeta --cap-lints allow --error-format=json --sysroot [...]/.rustup/toolchains/stable-x86_64-unknown-linux-gnu` (exit code: 101)",
    "startLineNumber": 1,
    "startColumn": 1,
    "endLineNumber": 10000,
    "endColumn": 1
}

According to the README in the clap repo itself, just adding it should work:

For full usage, add clap as a dependency in your Cargo.toml to use from crates.io:

[dependencies]
clap = "~2.33"

But it doesn't.

I've tried it with and without the ~ prefix as well as clap = {version = "2.33", features = ["yaml"]}, which is also shown in the repo, but no luck. (Yes, I'm trying to load the CLI options from a .yaml file.)

Trying cargo install clap --version 2.33.0 from the shell simply returns an error message saying: error: specified package has no binaries.

Aiming directly at the Git repo also produces the same error message:

cargo install --git https://github.com/clap-rs/clap.git --tag v2.31.2 --features yaml                                                  101 ↵
    Updating git repository `https://github.com/clap-rs/clap.git`
  Installing clap v2.31.2 (https://github.com/clap-rs/clap.git?tag=v2.31.2#07c15d28)
error: specified package has no binaries

Note that there's no v2.33.0 tag in the Git repo (at the time of this writing).


Bonus if you know how to get VSCode to stop marking everything as an error:

VSCode marks everything as an error


Solution

  • cargo install

    There's misunderstanding about the cargo install command. You can learn more about it here.

    This command manages Cargo’s local set of installed binary crates. Only packages which have executable [[bin]] or [[example]] targets can be installed, and all executables are installed into the installation root’s bin folder.

    It's not your case. The only thing you have to do is to list clap in the dependencies section (Cargo.toml). That's all. No need to use cargo install at all. cargo build, cargo run, ... commands will download & compile & statically link all dependencies.

    An example

    Folder structure:

    .
    ├── Cargo.toml
    └── src
        ├── cli.yaml
        └── main.rs
    

    Current directory:

    $ pwd
    /Users/robertvojta/Projects/stackoverflow/clap-yaml
    

    Cargo.toml content:

    [package]
    name = "clap-yaml"
    version = "0.1.0"
    authors = ["Zrzka"]
    edition = "2018"
    
    [dependencies]
    clap = { version = "2.33.0", features = ["yaml"] }
    

    src/cli.yaml content:

    name: clap-yaml
    version: "1.0"
    author: Zrzka
    about: Stackoverflow sample
    args:
      - lang:
          short: l
          long: lang
          default_value: cz
          takes_value: true
          possible_values:
            - cz
            - en
    

    src/main.rs content:

    use clap::{App, load_yaml};
    
    fn main() {
        let yaml = load_yaml!("cli.yaml");
        let matches = App::from_yaml(yaml).get_matches();
    
        match matches.value_of("lang").unwrap() {
            "cz" => println!("Ahoj"),
            "en" => println!("Hello"),
            _ => unreachable!("see possible_values in yaml, handled by clap"),
        };
    }
    

    Run it with cargo:

    $ cargo -q run -- --lang en
    Hello
    

    Run it directly:

    $ cargo build
        ...
        Finished dev [unoptimized + debuginfo] target(s) in 0.01s
    $ target/debug/clap-yaml --lang cz
    Ahoj
    

    Visual Studio Code

    I still have vscode complaining and underlining everything in red in the Cargo.toml file. Any suggestions to fix this completely? It seems close to a full resolution.

    I can confirm that this problem do exist in Rust 1.34.0. I did install this version and I've got same symptoms:

    • could not compile clap
    • the whole Cargo.toml is underlined (error)

    There're two ways how to fix this.

    Update your Cargo.toml file dependencies section manually if you'd like to stick with Rust 1.34.0:

    [dependencies]
    bitflags = "=1.0.4"
    clap = { version = "2.33.0", features = ["yaml"] }
    

    Or update your Rust toolchain to >= 1.35.0.

    I just tested both ways and it works.

    Related issues: