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 allows you to have a different name in [lib] and [package] when publishing #6827

Open
Manishearth opened this issue Apr 7, 2019 · 11 comments
Labels
A-cargo-targets Area: selection and definition of targets (lib, bins, examples, tests, benches) A-manifest Area: Cargo.toml issues C-bug Category: bug S-needs-team-input Status: Needs input from team on whether/how to proceed.

Comments

@Manishearth
Copy link
Member

Problem

In Cargo, currently the crate name you use in [dependencies] marks where the crate is supposed to come from; it matches the package.name key in the dependency's Cargo.toml.

The crate name you use in extern crate foo or foo:: has to match the actual on-disk compiled artifact name. This is not the package name, but is instead the lib.name key in the dependency's Cargo.toml.

If these don't match, you can have unexpected behavior (being unable to use crates by the name you'd expect them to use) as well as nonlocal bugs where one transitive dependency can break another by choosing the same [lib]

Steps

  1. Publish two crates with different package keys but the same lib key
  2. Try to use both in a single crate
  3. Get this multiple rlib candidates error:
error[E0465]: multiple rlib candidates for `manish_test_crate_clashes` found
 --> src/main.rs:1:1
  |
1 | extern crate manish_test_crate_clashes;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: candidate #1: /home/manishearth/sand/bar/crates/manish_test/target/debug/deps/libmanish_test_crate_clashes-6647f0eb7f7797e9.rlib
 --> src/main.rs:1:1
  |
1 | extern crate manish_test_crate_clashes;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2: /home/manishearth/sand/bar/crates/manish_test/target/debug/deps/libmanish_test_crate_clashes-a2862f19598a10de.rlib
 --> src/main.rs:1:1
  |
1 | extern crate manish_test_crate_clashes;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Possible Solution(s)

I'm not actually sure if this is a bug: Having this ability doesn't seem completely useless. And for unpublished git/path packages the lib name does matter.

It may be worth forbidding crates with a lib.name that doesn't match package.name from being published, after checking crates.io for any offenders. https://github.com/messense/rustc-test is one (and is how I discovered this bug, we've been confused about a libtest thing for a while and it seems like this crate is the culprit)

Notes

Output of cargo version: cargo 1.34.0-nightly (5c6aa46 2019-02-22)

@Manishearth
Copy link
Member Author

Overall I've always found the lib.name key to be super confusing because it adds to the dashes-vs-underscore ambiguity, which sometimes crops up with crates which use dashes in package.name and underscores in lib.name and while that kind of works it doesn't always work because now you need to use lib.name for specifying patches.

@ehuss
Copy link
Contributor

ehuss commented Apr 7, 2019

I think it is fairly common, I found about 569 crates on crates.io which do this. An additional 476 crates only differ in - vs _.

It might be worthwhile to peruse that list to get a better understanding why some people do this. I fear some of them are done because of crates.io namespace collisions.

The crate name you use in extern crate foo or foo:: has to match the actual on-disk compiled artifact name.

This isn't always true. Things such as crate renaming can use different names. Crate renaming should also provide a workaround to avoid the multiple rlib candidate error. I'm wondering if there would be a way to provide a better error message?

@dtolnay
Copy link
Member

dtolnay commented Apr 7, 2019

I use this infrequently but to what I consider desirable effect.

  • In dtolnay/syn@606e794 I was able to publish some early iteration on a major version of Syn under a different name to experiment with it in the ecosystem, without requiring any Rust code change in my example code or in downstream imports.

  • In proc-macro-workshop's test runner: Cargo.toml and test code.

@Manishearth
Copy link
Member Author

This isn't always true. Things such as crate renaming can use different names

Right, but that kinda makes it worse, since the impression given off by this feature is that "the package name is the crate name, unless you explicitly rename it", which isn't true. The lib name is the crate name, unless you explicitly rename it.

was able to publish some early iteration on a major version of Syn under a different name to experiment with it in the ecosystem,

Hmm, this seems to be a valid use case.

We should at least warn in cases where it's more than just underscores, though.

@carols10cents
Copy link
Member

I think it is fairly common, I found about 569 crates on crates.io which do this. An additional 476 crates only differ in - vs _.

@ehuss do you happen to still have the code that generated this list...? asking for a friend

@ehuss
Copy link
Contributor

ehuss commented Nov 18, 2019

I don't remember for sure, but I have the source for all the crates.io crates extracted locally. I then have a small rust script which uses walkdir to find all Cargo.toml files, then uses toml to parse them, and then it is a simple matter of comparing the package name to the lib name and seeing if they are different.

Here, I'll just recreate it real quick:
script: https://gist.github.com/ehuss/b65122f9bfd835da1c612aa71b1efd28
output: https://gist.github.com/ehuss/831d311fb3985483d16600a36fa32a5f

@Manishearth
Copy link
Member Author

Thanks a ton!

@ehuss ehuss added A-cargo-targets Area: selection and definition of targets (lib, bins, examples, tests, benches) A-manifest Area: Cargo.toml issues labels Apr 6, 2020
@Manishearth
Copy link
Member Author

I wonder if we should try and fix this sooner rather than later to avoid more of it happening. At least with a warning.

It might also help to just improve diagnostics around this situation.

@maxdymond
Copy link

Just wanted to chime in that the "package.name != lib.name" is useful when you're dealing in both rlib and cdylib; if my package is called libexample and the crate_types include "cdylib" then the resulting shared object has the name liblibexample.so. To normalize it back you have to set lib.name to example, e.g.

master # md@PC:~/code/md/libexample$ cat Cargo.toml
[package]
name = "libexample"
version = "0.1.0"
authors = ["Max Dymond"]
edition = "2018"
publish = false

[lib]
name = "example"
crate_type = ["cdylib", "lib"]


master # md@PC:~/code/md/libexample$ cargo build
   Compiling libexample v0.1.0 (/home/md/code/md/libexample)
    Finished dev [unoptimized + debuginfo] target(s) in 0.75s


master # md@PC:~/code/md/libexample$ ls target/debug/
build  deps  examples  incremental  libexample.d  libexample.rlib  libexample.so

@anacrolix
Copy link

I recently ran into this and found it useful to have different package and lib names. In this case it turns out possum was already taken, but there's no reason not to use possum as the lib name but possum-db for the package. https://crates.io/crates/possum-db

@epage
Copy link
Contributor

epage commented Jan 11, 2024

As a user, I find it confusing when maintainers do not match package names to lib names and would consider it a bad practice that should only be used in exception cases, like what dtolnay said above.

This is more common in the python ecosystem (since you have to explicitly state both) and I have appreciated that its not done in the Rust community as a general rule.

There isn't much we can do about this now because of compatibility but I think once we have #12235, we should have a warning discouraging this practice for general use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cargo-targets Area: selection and definition of targets (lib, bins, examples, tests, benches) A-manifest Area: Cargo.toml issues C-bug Category: bug S-needs-team-input Status: Needs input from team on whether/how to proceed.
Projects
None yet
Development

No branches or pull requests

7 participants