How do I specify my target chip as a feature - rust

I would like to program a bare attiny85 with rust. No existing development board, just my own layout. I figured that attiny-hal would be what I need, but I'm stuck at this error:
$ cargo check
Checking attiny-hal v0.1.0 (https://github.com/rahix/avr-hal?rev=4c9c44c314eb061ee20556ef10d45dea36e75ee4#4c9c44c3)
error: This crate requires you to specify your target chip as a feature.
Please select one of the following
* attiny85
* attiny88
* attiny167
* attiny2313
I tried these (and many other) settings in Crate.toml without success:
[package]
name = "avr01"
version = "0.1.0"
edition = "2021"
[features]
attiny85 = []
[dependencies.arduino-hal]
git = "https://github.com/rahix/avr-hal"
rev = "4c9c44c314eb061ee20556ef10d45dea36e75ee4"
features = ["attiny-hal"]
How do I select the target chip?

In your dependencies you have listed arduino-hal but you say you're programming a bare attiny85. You should include the attiny-hal crate directly and specify one of those features on the crate for example using this cargo command for an attiny85:
cargo add --git "https://github.com/rahix/avr-hal" attiny-hal -F attiny85
Which for some reason (I believe it's a bug) currently thinks attiny85 isn't a feature of attiny-hal but you can just specify it
in your Cargo.toml. The key for attiny-hal should include the required feature:
[dependencies.attiny-hal]
git = "https://github.com/rahix/avr-hal"
version = "*"
features = ["attiny85"]

Related

Empty rust file creates massive WASM build

Building the following rust file is producing a binary of 720KB.
I would expect a virtually empty build, what am I missing here? Is the full core libary getting included somehow?
Here's the code
#![no_std]
#[panic_handler]
fn handle_panic(_: &core::panic::PanicInfo) -> ! {
unreachable!()
}
And the cargo.toml
[package]
name = "wasm_test"
version = "0.0.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[profile.release]
opt-level = 's'
lto = true
And the command I'm using to build:
cargo build --target wasm32-unknown-unknown
Ok turns out I had two problems:
I was building this as a crate in a workspace, and that apparently ignores crate specific profiles
When i copied the crate out to mess around with it and isolate the problem, i was forgetting to add the --release flag, thanks #isaactfa.
In other cases i have received this warning.
warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
for some reason I wasn't getting it when doing the workspace builds.
I've added the crate to the workspace exclude list and am building it seperately, and its compiling to a far more appropriate 411 bytes, down from 727151 bytes.

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

Which files from the target directory are actually required by the executable?

After compiling my program 'zagir', the release folder has the size of more than 200MiB, which is ridiculous for the program I have written. So, I tried to check whether only the 'zagir' executable runs in isolation and it did.
But the confusion is that, release folder also includes libzagir.rlib file along with .d files and a bunch of other folders.
What exactly are they?
Are they really required?
Am I going to get error during execution when those files are ignored?
What are the files I should bundle for a complete executable?
Cargo.toml
[package]
authors = ["Sharad Chand"]
name = "zagir"
version = "0.1.0"
[dependencies]
bcrypt = "0.1.3"
dotenv = "0.10.1"
image = "0.17.0"
log = "0.3.8"
r2d2 = "0.7.3"
r2d2-diesel = "0.16.0"
rand = "0.3.16"
rocket = "0.3.2"
rocket_codegen = "0.3.2"
serde = "1.0.11"
serde_derive = "1.0.11"
serde_json = "1.0.2"
validator = "0.6.0"
validator_derive = "0.6.0"
[dependencies.bigdecimal]
features = ["serde"]
version = "0.0.10"
[dependencies.chrono]
features = ["serde"]
version = "0.4.0"
[dependencies.diesel]
features = [
"mysql",
"chrono",
"unstable",
"numeric",
"huge-tables",
]
version = "0.16.0"
[dependencies.diesel_codegen]
features = ["mysql"]
version = "0.16.0"
[dependencies.rocket_contrib]
features = ["handlebars_templates"]
version = "0.3.2"
[dependencies.uuid]
features = ["v4"]
version = "0.4"
Which files from the target directory are actually required by the executable
None of them, other than the executable itself. By default, Rust produces statically-linked binaries.
The other files are merely build artifacts maintained by Cargo in order to make rebuilding your code more efficient. They include things like your dependencies.
A non-exhaustive sampling of some of the files you might find:
*.d — Makefile-compatible dependency lists
*.rlib — Rust library files. Contain the compiled code of a dependency
build — Directories for build scripts to use as scratch space
deps — Your compiled dependencies
examples — Binaries from the examples directory
incremental — A directory for the incremental compilation cache
*-{hash} — Binaries from cargo test
executables — Your target binaries
Some of this is documented in the Cargo source code.

How do I use conditional compilation with `cfg` and Cargo?

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

Resources