I have a library crate and want to publish it on crates.io.
I created my project with cargo new my_lib --lib.
My project structure looks like this:
my_lib/
├─ src/
│ ├─ lib.rs
├─ examples/
│ ├─ example.rs
├─ benches/
│ ├─ benchmark.rs
├─ .gitignore
├─ Cargo.toml
├─ README.md
├─ config.json
My Cargo.toml looks like this:
[package]
name = "my_lib"
version = "0.1.0"
edition = "2018"
description = "Does cool stuff."
license = "MIT"
readme = "README.md"
repository = "https://git.example.com/my_lib"
homepage = "https://git.example.com/my_lib"
include = ["./config.json"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.4"
regex = "1"
serde_json = "1.0.64"
When I run cargo publish --dry-run, I get:
error: failed to verify package tarball
Caused by:
failed to parse manifest at `/home/me/my_lib/target/package/my_lib-0.1.0/Cargo.toml`
Caused by:
no targets specified in the manifest
either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present
It tells me to create a src/lib.rs file, but it's there!
If I try to specify the lib.rs file like this:
...
[lib]
path = "src/lib.rs"
...
I get a new error:
error: couldn't read src/lib.rs: No such file or directory (os error 2)
error: aborting due to previous error
error: could not compile `my_lib`
Why won't it let me push my library crate?
When using include, it's necessary to specify every file that is relevant to compilation.
It needs to look like this:
include = [
"src/**/*",
"Cargo.toml",
"config.json"
]
So be sure to include every file that rustc needs to compile and every file that you want to include in your binary.
Credit goes to #Stargateur.
Related
I'm trying to create a module in Rust and then use it from a different file. This is my file structure:
matthias#X1:~/projects/bitter-oyster$ tree
.
├── Cargo.lock
├── Cargo.toml
├── Readme.md
├── src
│ ├── liblib.rlib
│ ├── lib.rs
│ ├── main.rs
│ ├── main.rs~
│ └── plot
│ ├── line.rs
│ └── mod.rs
└── target
└── debug
├── bitter_oyster.d
├── build
├── deps
├── examples
├── libbitter_oyster.rlib
└── native
8 directories, 11 files
This is Cargo.toml:
[package]
name = "bitter-oyster"
version = "0.1.0"
authors = ["matthias"]
[dependencies]
This is main.rs:
extern crate plot;
fn main() {
println!("----");
plot::line::test();
}
This is lib.rs:
mod plot;
this is plot/mod.rs
mod line;
and this is plot/line.rs
pub fn test(){
println!("Here line");
}
When I try to compile my program using: cargo run I get:
Compiling bitter-oyster v0.1.0 (file:///home/matthias/projects/bitter-oyster)
/home/matthias/projects/bitter-oyster/src/main.rs:1:1: 1:19 error: can't find crate for `plot` [E0463]
/home/matthias/projects/bitter-oyster/src/main.rs:1 extern crate plot;
How do I compile my program? As far as I can tell from online documentations this should work, but it doesn't.
To add to the given answers, a library compiled as a cdylib (docs) can generate this error when you try to reference it in another project. I solved it by separating the code I wished to reuse in a regular lib project.
If you see this error:
error[E0463]: can't find crate for `PACKAGE`
|
1 | extern crate PACKAGE;
| ^^^^^^^^^^^^^^^^^^^^^ can't find crate
it could be that you haven't added the desired crate to the dependencies list in your Cargo.toml:
[dependencies]
PACKAGE = "1.2.3"
See specifying dependencies in the Cargo docs.
You have the following problems:
you have to use extern crate bitter_oyster; in main.rs, because the produced binary uses your crate, the binary is not a part of it.
Also, call bitter_oyster::plot::line::test(); in main.rs instead of plot::line::test();. plot is a module in the bitter_oyster crate, such as line. You are referring to the test function with its fully qualified name.
Make sure, that every module is exported in the fully qualified name. You can make a module public with the pub keyword, like pub mod plot;
You can find more information about Rust's module system here: https://doc.rust-lang.org/book/crates-and-modules.html
A working copy of your module structure is as follows:
src/main.rs:
extern crate bitter_oyster;
fn main() {
println!("----");
bitter_oyster::plot::line::test();
}
src/lib.rs:
pub mod plot;
src/plot/mod.rs:
pub mod line;
src/plot/line.rs :
pub fn test(){
println!("Here line");
}
I got this issue when I had imported my crate in [dev-dependencies] instead of [dependencies]
This can also happen when you don't enable certain "feature flags" for specific crates. Unfortunately, these feature flags can sometimes be undocumented. When feature flags are missing when required, they show the same error ("Can't find crate")
I was using diesel, and was trying to use BigInteger:
Wrong
diesel = { version = "2.0.3", features = ["postgres", "chrono", "r2d2", "serde_json", "biginteger"] }
Correct:
diesel = { version = "2.0.3", features = ["postgres", "chrono", "r2d2", "serde_json", "numeric"] }
I have included a library as a submodule in my program. The structure looks like this:
.
├── my_lib/
├── Cargo.toml
└── src/
├── lib/
├── mod.rs
└── foo.rs
└── main.rs
├── src/
└── main.rs
└── Cargo.toml
In my program's Cargo.toml file I have added the dependency following this answer:
[dependencies]
my_lib = { path = "./my_lib" }
However I'm not able to use this library inside my program, I'm a bit new to Rust and this import system is very confusing to me. I've tried this in main.rs:
use my_lib::foo;
But I get an unresolved import 'my_lib' error.
A crate can be either a library or an executable, not both. Your my_lib contains a main.rs file, which means Cargo will treat it as an executable file. You cannot import from an executable.
You will need to restructure your code. Perhaps you actually meant for my_lib to be a library, in which case it should have a top-level lib.rs. You probably want to:
delete my_lib/src/main.rs
move my_lib/src/lib/mod.rs to my_lib/src/lib.rs
move my_lib/src/lib/foo.rs to my_lib/src/foo.rs
See also:
Rust package with both a library and a binary?
I have multi-workspace Cargo project. It has two workspaces, common and server. common is a lib project and server is a bin project.
The location of the project in Github is here.
Below is the project structure.
.
├── Cargo.toml
├── common
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── README.md
└── server
├── Cargo.toml
└── src
└── main.rs
4 directories, 6 files
And the file contents of ./Cargo.toml file is
[package]
name = "multi_module_cargo_project"
version = "0.1.0"
authors = ["rajkumar"]
[workspace]
members = ["common", "server"]
[dependencies]
When I run the command cargo build --all:
error: failed to parse manifest at `/home/rajkumar/Coding/Rust/ProgrammingRust/multi_module_cargo_project/Cargo.toml`
Caused by:
no targets specified in the manifest
either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present
So I added below in Cargo.toml but still couldn't build the project.
[[bin]]
name = "server/src/main.rs"
How can I build the project. What I'm missing?
You included a [package] section in your main Cargo.toml file. This section indicates that you want to build a main package in addition to the packages in the workspace. However, you don't have any source files for the main package, so Cargo complains.
The solution is to simply omit the [package] section, and only include [workspace]. This configures a virtual workspace – a workspace that is only a container for member packages, but does not build a package itself.
See the main Cargo.toml file of Rocket for a real-world example of a virtual workspace, and Tokio for a real-world example of a workspace with a main package.
I am learning about Cargo workspaces and have set up the following structure:
Top-level:
[package]
name = "workspacer"
version = "0.1.0"
authors = ["ustulation <zzzzzz#gmail.com>"]
[workspace]
members = ["safe_core", "safe_authenticator", "safe_app"]
# If this is removed then each of the sub-projects will have thier own Cargo.lock file
# will build binaries/objects in their own target/ directories. With this present, it's
# always the parent-projects Cargo.lock and target/ directory used. Need to check if this
# is standard behaviour or some bug about to be fixed.
[lib]
crate_type = ["rlib", "cdylib", "staticlib"]
A lib called safe_core which only needs to produce a .rlib
[package]
authors = ["ustulation <zzzzzz#gmail.com>"]
name = "safe_core"
version = "0.1.0"
[dependencies]
maidsafe_utilities = "~0.10.0"
A lib called safe_app which depends on safe_core and needs to produce all 3 .rlib, .a and .so:
[package]
name = "safe_app"
version = "0.1.0"
authors = ["ustulation <zzzzzz#gmail.com>"]
[dependencies]
maidsafe_utilities = "~0.10.0"
safe_core = { path = "../safe_core" }
[lib]
crate_type = ["rlib", "cdylib", "staticlib"]
A lib called safe_authenticator which depends on safe_core and needs to produce all 3 .rlib, .a and .so:
[package]
name = "safe_authenticator"
version = "0.1.0"
authors = ["ustulation <zzzzzz#gmail.com>"]
[dependencies]
safe_core = { path = "../safe_core" }
[lib]
crate_type = ["rlib", "cdylib", "staticlib"]
The tree looks like:
workspacer
├── Cargo.toml
├── safe_app
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── safe_authenticator
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── safe_core
├── Cargo.toml
└── src
└── lib.rs
If I go to safe_core and build, it creates a target/ folder and Cargo.lock files inside the top level workspacer/, which is good.
If I go to safe_authenticator folder and build that it too uses the same target/ and Cargo.lock files and hence does not recompile safe_core which is what I want too. Same with safe_app.
However if I remove the [lib] section from the top-level workspacer/Cargo.toml, each of the sub-projects start creating their own Cargo.lock files and their own /target directories inside their respective sub-directories. I have mentioned this in the inline comment in the Cargo.toml of workspacer above (the 1st snippet above).
Is this an expected behavior or a bug or am I doing something wrong ?
~$ rustc --version && cargo --version
rustc 1.15.0-nightly (ba872f270 2016-11-17)
cargo 0.15.0-nightly (1877f59 2016-11-16)
After confirming it on latest stable:
~$ rustc --version && cargo --version
rustc 1.13.0 (2c6933acc 2016-11-07)
cargo 0.13.0-nightly (eca9e15 2016-11-01)
It seems to be a bug:
All members of workspace should share the same target directory no
matter what!
A bug report was submitted, and it is solved now.
I'm trying to package a library using the cargo package manager for Rust. When I try to run cargo package per the documentation, I get the following output:
error: main function not found
error: aborting due to previous error
failed to verify package tarball
I'm confused. I'm trying to package a library (with useful external functions), so I expect that I don't need a main function. Here is my Cargo.toml:
[package]
name = "package-name"
version = "0.0.1"
authors = [ "Kevin Burke <kev#inburke.com>" ]
Here is my directory structure:
.
├── Cargo.lock
├── Cargo.toml
├── src
│ └── main.rs
What am I missing?
Ah! If you are packaging a library for other programs to use (as I am trying to do), you need to name your file lib.rs.
Alternatively, if you are packaging a binary, name your file main.rs (this was my mistake).