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 install fails when package uses previous version of its own to build itself #11999

Closed
phorward opened this issue Apr 19, 2023 · 5 comments · Fixed by #12015
Closed

cargo install fails when package uses previous version of its own to build itself #11999

phorward opened this issue Apr 19, 2023 · 5 comments · Fixed by #12015
Labels
C-bug Category: bug regression-from-stable-to-stable Regression in stable that worked in a previous stable release. S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review

Comments

@phorward
Copy link

phorward commented Apr 19, 2023

Problem

Hello!

My package tokay uses a previous version of its own to build itself. It worked until Rust toolchain 1.67.1, but since 1.68.0 this is broken and I cannot find a solution for it.

Here's what happens with Rust toolchain 1.68.2 (stable):

$ cargo install -v tokay
    Updating crates.io index
  Installing tokay v0.6.2
error: failed to compile `tokay v0.6.2`, intermediate artifacts can be found at `/tmp/cargo-installVvDECK`

Caused by:
  There are multiple `tokay` packages in your project, and the specification `tokay` is ambiguous.
  Please re-run this command with `-p <spec>` where `<spec>` is one of the following:
    [email protected]
    [email protected]

The provided hint doesn't help as well, because I cannot specify -p [email protected] together with cargo install, as its probably a cargo build command.

As written, tokay uses a previous version of its own as build-dependency, and also in dependency of a dependency.
Therefore, to build tokay 0.6.2, tokay 0.4.0 is required by build.rs and by tokay-macros.

Here are the dependencies as specified in Cargo.toml:

[package]
name = "tokay"
version = "0.6.2"
edition = "2021"

[build-dependencies]
tokay = "0.4"
glob = "0.3"

[dependencies]
charclass = "0.2"  # use crates.io-version
clap = { version = "4", features = ["derive"] }
indexmap = "1.9"
num = "0.4"
num-bigint = "0.4"
rustyline = "9"
tokay-macros = "0.4"  # use crates.io-version
num-parse = "0.1"  # use crates.io-version

Steps

cargo install tokay

Possible Solution(s)

I don't have any solutions for this problem.

I've tried to use another name for the older package version in the build dependencies, but this also didn't work.

[build-dependencies]
tokay_04 = { package = "tokay", version = "0.4" }
glob = "0.3"

I haven't tried it in the tokay-macros package as well, as I first have to publish this packages, and tokay afterwards, just to test it.

Notes

When I run cargo build or cargo run in my checked out repository, all works as expected, also with the newest 1.68 toolchain.

Thanks for any help!

Version

cargo 1.68.2 (6feb7c9cf 2023-03-26)
release: 1.68.2
commit-hash: 6feb7c9cfc0c5604732dba75e4c3b2dbea38e8d8
commit-date: 2023-03-26
host: x86_64-unknown-linux-gnu
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 7.86.0-DEV (sys:0.4.59+curl-7.86.0 vendored ssl:OpenSSL/1.1.1q)
os: Arch Linux [64-bit]
@phorward phorward added C-bug Category: bug S-triage Status: This issue is waiting on initial triage. labels Apr 19, 2023
@epage
Copy link
Contributor

epage commented Apr 20, 2023

A reproduction test case:

#[cargo_test]
fn self_referetial() {
    Package::new("foo", "0.0.1")
        .file("src/lib.rs", "fn hello() {}")
        .file("src/main.rs", "fn main() {}")
        .file("build.rs", "fn main() {}")
        .publish();
    Package::new("foo", "0.0.2")
        .file("src/lib.rs", "fn hello() {}")
        .file("src/main.rs", "fn main() {}")
        .file("build.rs", "fn main() {}")
        .build_dep("foo", "0.0.1")
        .publish();

    cargo_process("install foo")
        .with_stderr(
            "\
[UPDATING] `[..]` index
[DOWNLOADING] crates ...
[DOWNLOADED] foo v0.0.1 (registry [..])
[INSTALLING] foo v0.0.1
[COMPILING] foo v0.0.1
[FINISHED] release [optimized] target(s) in [..]
[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE]
[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
",
        )
        .run();
    assert_has_installed_exe(cargo_home(), "foo");
}

@epage
Copy link
Contributor

epage commented Apr 20, 2023

This broke in 7dc8be5 (#11067)

@epage
Copy link
Contributor

epage commented Apr 20, 2023

Most likely these lines:

       // When we build this package, we want to build the *specified* package only,
        // and avoid building e.g. workspace default-members instead. Do so by constructing
        // specialized compile options specific to the identified package.
        // See test `path_install_workspace_root_despite_default_members`.
        let mut opts = original_opts.clone();
        opts.spec = Packages::Packages(vec![pkg.name().to_string()]);

@tedinski
Copy link
Contributor

I've run into this sort of issue with another package as well (unfortunately, I no longer have the work machine I used when I hit it... I think it was something tokio related.)

There, the issue was that the "workspace" seemed to contain both a package with a particular name (idk, tokio-something let's call it), and something that depended on it via crates.io as well. (Maybe a test package?) The error that resulted was that cargo build would successfully build tokio-something, but cargo build -p tokio-something would result in this error in that situation as well. This struck me as possibly unwanted behavior... (Though at least in that situation, the suggestion in the error would work.)

So we could either:

  1. Fix that line of code @epage found, which should probably produce a full pkgspec, not just a name of the package. I can't recall if this is easy or not, there might have been something else that got in the way of me doing that the first time around. I do remember the (surprising?) absence of an existing function to go from a Package to a PkgSpec (if I'm remembering the type names correctly, off the top of my head...)
  2. And/or, consider whether cargo should automatically disambiguate package names like this in favor of the one in the local workspace.

Or perhaps most likely: first do 1, then break 2 into a separate issue.

I can take a crack at a fix tomorrow, if someone doesn't beat me to it.

@weihanglo weihanglo added S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review regression-from-stable-to-stable Regression in stable that worked in a previous stable release. and removed S-triage Status: This issue is waiting on initial triage. labels Apr 21, 2023
@weihanglo
Copy link
Member

  1. which should probably produce a full pkgspec

I believe this is the correct way to resolve the issue. PackageIdSpec::from(pkgid).to_string() or something similar should work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug regression-from-stable-to-stable Regression in stable that worked in a previous stable release. S-accepted Status: Issue or feature is accepted, and has a team member available to help mentor or review
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants