How to compile some dependencies with release - rust

I'd like to build my rust app with "dev" profile, but some of the dependencies with "release" profile (because otherwise they are really slow). How can I selectively specify profiles for my crate dependencies?

Cargo is able to override profile for a specific package.
From the reference :
Profile settings can be overridden for specific packages and
build-time crates. To override the settings for a specific package,
use the package table to change the settings for the named package:
# The `foo` package will use the -Copt-level=3 flag.
[profile.dev.package.foo]
opt-level = 3
While compiling with dev profile, this will override optimize level for foo package.
If you want to optimize few dependency with a default value from dev profile and more from a release profile:
#override target package to build with dev default(opt-level)
[profile.dev.package.bar]
opt-level = 0
#override all other dependencies to build with release default(opt-level)
[profile.dev.package."*"]
opt-level = 3
If you want to optimize all of your dependencies except your
application(also workspace members)
[profile.dev.package."*"]
opt-level = 3
See also :
Default Profiles with their default settings
Reference of Profile Settings

Related

How to set up conditional dependency for Stack project?

I'm trying to enable my Stack-based Haskell project to apply a certain GHC plugin when the user requires it.
I have successfully added the -fplugin flags through the ghc-options. As far as I know I have to add the plugin package as a dependency in my package.yaml file. However I would like to configure the project so that the extra dependency is only added if the user requires it (with a flag set, environment variable or some other means).
I have tried to use the when keyword in the package.yaml to conditionally enable the dependency:
when:
- condition: flag(useplugin)
then:
dependencies: [ myplugin ]
else:
dependencies: []
However this results in an error coming from cabal:
- 0:0: These flags are used without having been defined: myplugin
I couldn't find the option for package.yaml which would generate the flag definition (like described here) in the generated cabal file.

Cargo package doesn't work with Rust's workspace?

I create a "workspace" with several folder within it following the tutorial I read here
It runs successfully with cargo run or cargo build
if all of the package were independent from each other, cargo package would run successfully. But as soon as one package depends on the other the cargo package will fail.
It displays: no matching package named "foo_2" found. location searched: registry "crates-io". Which is pretty weird, since I specifically add a local path on the dependencies.
Is this an intended behavior? if so, then why should I bother with workspace at all ?
The root Cargo.toml
[workspace]
members = [
"foo_1",
"foo_2",
]
foo_1/Cargo.toml
[package]
name = "foo_1"
version = "0.1.0"
edition = "2021"
# error here. It can't found the foo_2 package.
[dependencies]
foo_2 = { path = "../foo_2", version = "0.1.0" }
foo_2/Cargo.toml
[package]
name = "foo_2"
version = "0.1.0"
edition = "2021"
[dependencies]
Error message:
PS E:\Works\Experimentals\rust-workspace> cargo package --workspace
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
Packaging foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\foo_1)
Verifying foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\foo_1)
Updating crates.io index
error: failed to verify package tarball
Caused by:
no matching package named `foo_2` found
location searched: registry `crates-io`
required by package `foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\target\package\foo_1-0.1.0)`
Packaging and publishing crates requires all dependencies of said crate to also be available in a registry. For publishing this is relatively obvious, since consumers also need to be able to fetch and build transitive dependencies. Creating tarballs also happens to have the same constraints at the moment, so it is not possible if they are not meant to be published.
Whenever you have a project with many crates in a single workspace and wish to publish them on crates.io, you would start with the crate without dependencies and work your way up to the other crates.
cargo publish -p foo_2
cargo publish -p foo_1
Or, using cargo-workspaces:
cargo workspaces publish
Is this an intended behavior?
One can still publish crates in a workspace, so long as this is done in the right order. For packaging, it is a limitation at the time of writing. The current behavior could be linked with packaging being primarily part of publishing, so this could probably be improved.
If so, then why should I bother with workspace at all?
Tangential to the matter here. Workspaces exist mainly to settle other concerns, such as having a single source of compiled dependencies with a shared dependency lock. This distinction is described in that same link.

Can I activate a dependency's feature only for debug profile?

I have just started looking into the Bevy game engine for Rust. It has a feature called dynamic, which enables dynamic linking, to speed up compilation time during development. We are, however, advised to disable this when building for release.
Is there a way to tell Cargo to enable the dynamic feature for a debug build, but disable it for a release build? Or do I have to personally remember to change bevy = { version = "0.5.0", features = ["dynamic"] } to bevy = "0.5.0" in Cargo.toml before running cargo build --release?
Along the lines of Rodrigo's comment, can confirm the following seems to work well:
[dependencies]
bevy = { version = "0.5.0" }
[features]
default = ["fast-compile"]
fast-compile = ["bevy/dynamic"]
Then for development, simply: cargo build
And for release: cargo build --release --no-default-features

How to activate an optional dependency?

Cargo.toml:
[features]
parallel = ["rayon"]
[dependencies.rayon]
version = "1.5"
optional = true
lib.rs:
#[cfg(feature = "parallel")]
pub mod par;
Rust Analyzer:
code is inactive due to #[cfg] directives: feature = "parallel" is disabled
How to enable the optional dependency?
You can set the Rust Analyzer configuration option rust-analyzer.cargo.features to an array containing a list of features that you want RA to consider active.
You can also set rust-analyzer.cargo.allFeatures to true, in order to enable all features in the project.
Methods for setting these vary according to the IDE you are using - for example, if using VS Code, you can set it via the "Extension Settings" for Rust Analyzer.
This assumes you are asking how to activate the features within Rust Analyzer - to activate them when building or running from Cargo, just use the --features option.
See: Rust Analyzer Manual
All non-default features need to be specified when running. So run with:
# Option 1
cargo run --features parallel
# Option 2
cargo run --all-features
Check cargo run --help for more help.

Is it possible to disable a dependency's feature when building with RLS?

I have the following dependency configuration in Cargo.toml.
[dependencies.ffmpeg-sys]
version = "3.4.1"
default-features = false
features = ["avcodec", "avformat", "swresample", "static", "build"]
Adding the build feature hugely increases compile time and I only need to do it when building in release mode.
Is there a way to disable features of a dependency based on the build type (debug, release, RLS)?

Resources