This question already has answers here:
Can Cargo download and build dependencies without also building the application?
(6 answers)
Closed 10 months ago.
The Rust Cargo.toml specification file allows for development dependencies section, e.g. [dev-dependencies]
Cargo.toml:
[dev-dependencies]
tempdir = "0.3"
What is the command to fetch and compile those development dependencies?
To be clear, I want to fetch and compile only the [dev-dependencies]. The Linked questions differ in that they address fetching and compiling all dependencies and then building the application.
I do not have enough reputation so I just answer.
As declare by your link and rust-by-example, it is impossible to "build" a binary from dev-dependencies.
Sometimes there is a need to have dependencies for tests (or examples,
or benchmarks) only. Such dependencies are added to Cargo.toml in the
[dev-dependencies] section
To be sneaky, may be you can put some function under #[cfg(test)] and run cargo test so that your goal can be achieved.
A more appropriate way to selectively build by cargo using the feature flag, in cargo.toml and cargo command. You can take a look at the cargo command to toggle feature here and optional dependencies which help control categorizing of features.
Related
I was reading this at the guessing game tutorial inside the rust book
Ensuring Reproducible Builds with the Cargo.lock File
Cargo has a mechanism that ensures you can rebuild the same artifact every time you or anyone else builds your code: Cargo will use only the versions of the dependencies you specified until you indicate otherwise. For example, say that next week version 0.8.4 of the rand crate comes out, and that version contains an important bug fix, but it also contains a regression that will break your code. To handle this, Rust creates the Cargo.lock file the first time you run cargo build, so we now have this in the guessing_game directory.
When you build a project for the first time, Cargo figures out all the versions of the dependencies that fit the criteria and then writes them to the Cargo.lock file. When you build your project in the future, Cargo will see that the Cargo.lock file exists and use the versions specified there rather than doing all the work of figuring out versions again. This lets you have a reproducible build automatically. In other words, your project will remain at 0.8.3 until you explicitly upgrade, thanks to the Cargo.lock file.
but didn't quite understand how cargo garantees that we have/need the correct version of a dependency. For instance, if we put in the [dependecies] rand="0.8.3" it will not exactly download the crate at this version, but the crate the match the needs of our program but it's compatible with this version(?)
Please clarify this logic!
When specifying a crate in Cargo.toml, you can give an exact version (e.g. =0.8.3) or more general indications (e.g. 0.8.*).
If you specify rand = "=0.8.3" in Cargo.toml, then cargo will take version 0.8.3 (note the extra = inside the version requirement). But if you specify rand = "*", then the first time you build your crate it will take the latest version and write this version to Cargo.lock. That way if you rebuild your crate later cargo will reuse the same version even if a new version has been published on crates.io in the meantime.
Note btw that specifying rand = "0.8.3" does not mean "exactly version 0.8.3", but instead means "any version >=0.8.3 and <0.9": link.
I'm writing the back-end for a web application and would like to reuse some logic for client-side. I want to use wasm to generate a library which Javascript can use. Suppose the logic is in lib.rs. What should I do, so that:
The back-end can import and use the code in lib.rs as normal, also cargo build generates a binary as expected.
Rust generates a wasm library for lib.rs
I tried adding these to my cargo file (by following this: Rust package with both a library and a binary?):
[lib]
crate-type = ["cdylib", "rlib"]
[[bin]]
name = "mybin"
path = "src/main.rs"
But it seems like cargo is building my binary for the browser, so it is missing all the sys crate.
You can ask for only your library to be built using the --lib option.
cargo build --lib --target wasm32-unknown-unknown
So my current approach is to create a separate package for lib.rs and use it as a dependency for the back-end, as outlined in here:
What is an idiomatic way to have shared utility functions for integration tests and benchmarks?
It seems to work well enough.
This question already has an answer here:
"a bin target must be available for 'cargo run'"
(1 answer)
Closed 3 years ago.
I am quite new using Rust language. I try to execute this cargo project/lib from github repository.
https://github.com/smallnest/benchpi
However, after cloning and run cargo run, I got this error error: a bin target must be available for 'cargo run'
How to properly run this cargo library? Thanks.
cargo run will look for a file called src/main.rs or src/bin/*.rs or some other file that's defined to be an application/binary in Cargo.toml. However, this project does not have one of these files. It is only a library with src/lib.rs. Without writing more code that calls the functions provided by this library, you can only run its unit tests and benchmarking suite.
You can run its unit tests on the latest Rust stable release by running cargo test. However, to run the benchmarks, you'll need to have the Rust nightly release installed. If you're using rustup to manage your Rust installation, you can install the nightly version of rust and use it to run the benchmarks like:
$ rustup install nightly
$ cargo +nightly bench
I'm facing this problem when I try to cargo build:
error: native library openssl is being linked to by more than one version of the same package, but it can only be linked once; try updating or pinning your dependencies to ensure that this package only shows up once
openssl-sys v0.6.7
openssl-sys v0.7.13
Cargo and Rust versions:
$ cargo --version
cargo 0.11.0-nightly (3ff108a 2016-05-24)
$ rustc --version
rustc 1.11.0-nightly (7746a334d 2016-05-28)
Files:
Cargo.toml
Cargo.lock
can't get why this doesn't compile and how to solve this problem.
Thank you!
The way that linking works, you can only have a single version of a native library linked, otherwise you end up with duplicate symbols. Cargo's links manifest key helps prevent you from accidentally linking to the same set of symbols twice.
To solve it, you need to read through your Cargo.lock (it's not a difficult file format to understand). Find the crates that have the offending library as a dependency and note which ones have conflicting versions.
Then you have to manually resolve your dependencies so that their dependencies use the same version of the native library.
In this case, the important aspects of the dependency chain are:
server (0.0.1) => cookie (0.2.4) => openssl (0.7.13)
=> hyper (0.6.16) => cookie (0.1.21) => openssl (0.6.7)
To fix it, modify your Cargo.toml to use the same version of cookie as hyper. Then you will implicitly get the same version of openssl.
To be honest, this is one of the roughest parts of Rust at the moment. At least this version of the "multiple different versions of the same crate" strangeness provides a straight-forward Cargo error.
I want to conditionally compile my source code using cfg with Cargo,
after Googling for a while,
it seems that the solution is to use cargo --features.
http://doc.crates.io/manifest.html
I tried adding a few
#[cfg(feature = "foo")]
in the source code and
cargo build --features foo
, but it says
Package `xxx v0.0.1 (file:///C:/yyy/xxx)` does not have these features: `foo`
How can I let cargo identify the features? Do I have to add something in Cargo.toml?
Here's the version of rustc and cargo I am using:
C:\>rustc --version
rustc 0.13.0-nightly (42deaa5e4 2014-12-16 17:51:23 +0000)
C:\>cargo --version
cargo 0.0.1-pre-nightly (5af754d 2014-12-18 01:50:48 +0000)
You have to introduce the existing features in your Cargo.toml.
I was able to conditionally compile by doing the following:
In Cargo.toml, create a features section and introduce a certain feature name:
[features]
customfeature = [] # feature has no explicit dependencies
If you want your feature to have specific dependencies check the examples in the documentation.
In your code, use #[cfg(feature="customfeature")]
Run cargo build --features customfeature
Since your steps 2 & 3 seem to be fine, there must probably be a problem with your Cargo.toml.
As stated in other answers, you can use features for this. I would like to add that features do not only allow you to conditionally compile parts of your code but also to conditionally include dependencies that may be part of that code. Consider the following snippets:
You can activate the conditional code using a feature flag as already described in other anwsers:
cargo build --features customfeature
You need to mark your conditional code to exist only when your customfeature is enabled:
#[cfg(feature = "customfeature")]
fn my_func() {
my_optional_dependency::do_something();
}
// This includes dependencies only when customfeature is enabled
#[cfg(feature = "customfeature")]
extern crate my_optional_dependency;
....
#[cfg(feature = "customfeature")]
use my_optional_dependency::*;
....
Your Cargo.toml needs to have the following sections:
[dependencies.my_optional_dependency]
version = "1.2.3"
optional = true
[features]
customfeature = ["my_optional_dependency"]
This allows you to activate certain parts of your code along with their dependencies only if a feature is enabled.
Alternatively, you could create a cargo configuration file in your project, by creating a .cargo subdir in your project main folder, adding in it a config.toml file,
then inserting this section in .cargo/config.toml:
[build]
rustflags = "--cfg my_cfg_flag"
This will make cargo call rustc with flags --cfg my_cfg_flag
See here for details:
https://doc.rust-lang.org/cargo/reference/config.html