Rust Cargo build and crosscompile for specific CPU - rust

I want to compile two binaries for different target architectures (eg. Skylake and Sandy Bridge).
These are usually two lengthy cargo commands:
RUSTFLAGS="-C target-cpu=skylake" cargo build --target
x86_64-unknown-linux-gnu --release
How can I set up cargo to build both binaries (with different names) from the same main.rs automatically?
Ideally in either the config.toml or the Cargo.toml so I can add it to a repository.

You can add the following text to your config.toml:
[build]
target = x86_64-unknown-linux-gnu
rustflags = ["-C","target-cpu=skylake"]
[profile.dev] #do not need to add `--release` now
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
lto = false
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
But it seems like it can't compile for two different target architectures with one config.toml, so you may have to create two config.toml and use cargo --manifest-path PATH/TO/CONFIG to compile two binaries separately.

Related

Why `cargo build` immediately after `cargo check` recompiles some dependencies?

What could be a possible reason for cargo build immediately after cargo check recompiling many (but not all) dependencies?
Cargo.toml
[package]
name = "greeter"
version = "0.1.0"
authors = ["Near Inc <hello#near.org>"]
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
near-sdk = "3.1.0"
[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "z"
lto = true
debug = false
panic = "abort"
# Opt into extra safety checks on arithmetic operations https://stackoverflow.com/a/64136471/249801
overflow-checks = true
[workspace]
members = []
cargo check is not a build. It simply checks that your code would compile, but doesn't necessarily build anything. See here for more information.
So cargo build will need to actually build some crates, that where not built during cargo check. Other crates may need to be fully compiled to check (for example crates used in a build.rs script or by procedural macros), and where therefore already compiled when you ran cargo build.

How can I optionally pass rustc flags depending on a Cargo feature?

The program I'm writing runs much faster when the -C target-cpu=native flag is passed to rustc. I want to give users a simple, platform-independent way to enable this when compiling, so I added a Cargo feature cpu_native = [] in Cargo.toml and created this Cargo config in my project:
[target.'cfg(cpu_native)']
rustflags = ["-C", "target-cpu=native"]
However, this has no effect on my program, and passing --features cpu_native to Cargo does not even trigger a recompile. Changing to the following Cargo config does force re-compilation with faster instructions:
[build]
rustflags = ["-C", "target-cpu=native"]
However, this will compile with target-cpu=native with the default Cargo features, which was not what I wanted. From the Cargo book, what I want seems to be possible, but I don't see what I'm doing wrong.
I don't think this is supported (yet?). I enhanced Cargo to print out what config flags are checked against when resolving:
[
Name("debug_assertions"),
Name("proc_macro"),
KeyPair("target_arch", "x86_64"),
KeyPair("target_endian", "little"),
KeyPair("target_env", ""),
KeyPair("target_family", "unix"),
KeyPair("target_os", "macos"),
KeyPair("target_pointer_width", "64"),
Name("unix"),
]
[target.'cfg(cpu_native)']
This is the incorrect syntax for a Cargo feature; it would normally be cfg(feature = "cpu_native").

How can I set default build target for Cargo?

I tried to make 'Hello World' in Rust using this tutorial, but the build command is a bit verbose:
cargo +nightly build --target wasm32-unknown-unknown --release
Is it possible to set the default target for cargo build?
You could use a Cargo configuration file to specify a default target-triple for your project. In your project's root, create a .cargo directory and a config.toml file in it with the following contents:
[build]
target = "wasm32-unknown-unknown"
As listed in the Cargo documentation, you can create a .cargo/config and specify the target:
[build]
target = "my-custom-target"
If you're able to use unstable features, following documentation and especially per-package-target feature add this to you crate manifest that usually named Cargo.toml
cargo-features = ["per-package-target"]
[package]
forced-target = "wasm32-unknown-unknown"
# and/or:
default-target = "wasm32-unknown-unknown"
This requires nightly toolchain.

Specific profiles for workspace members

Is it possible to specify specific profiles for members of a workspace?
If I write a profile into the member Cargo.toml I get:
warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
I also tried to put a specific profile into workspace root's Cargo.toml:
[profile.release]
opt-level = 3
[profile.release.hal]
# optimizer kills assembly code
opt-level = 1
However, it seems to be ignored too, as the applied options in the the verbose output show:
Running `rustc --crate-name hal src/hal/lib.rs --crate-type lib -C opt-level=3 --emit=dep-info,link [...]
Is there any other way beside avoiding workspaces at all?
This is now supported and stabilized since Rust 1.43:
[profile.release]
opt-level = 3
[profile.release.package.hal]
# optimizer kills assembly code
opt-level = 1
See: https://doc.rust-lang.org/cargo/reference/profiles.html#overrides

Does Cargo support custom profiles?

I often want to compile in release mode with debug = true so that I can read the generated assembly a bit easier. I am currently doing this:
[profile.release]
debug = true
but I don't want any debug symbols in my final release build. I'd like to do something like:
[profile.custom]
debug = true
opt-level = 3
rpath = false
lto = true
debug-assertions = false
codegen-units = 1
panic = 'unwind'
And then run
cargo build --custom
I've read the documentation to no avail.
As of Rust v1.57.0, the custom profiles feature is now stable.
Add a profile section, specify a base profile to inherit from, and tweak as you see fit:
[profile.production]
inherits = "release"
lto = true
Specify the profile to use via the --profile <name> flag to cargo.
Does Cargo support custom profiles?
No, stable releases of Cargo do not support this. It is available as an unstable nightly feature.
If you are using a nightly version of Cargo, you can create custom profiles in your Cargo.toml:
cargo-features = ["named-profiles"]
[profile.release-lto]
inherits = "release"
lto = true
And then use them:
cargo +nightly build --profile release-lto -Z unstable-options

Resources