I want to group executables of rust with attributes as cargo build --release - rust

I've made the following configuration and I can successfully make executables called media and strings. Moreover I want to make executables of media.rs and str.rs. Is it possible to do?
Concretely, I desire executables which are named with media/image, strings/parse so that I can group executables with some attributes.
.
├── Cargo.lock
├── Cargo.toml
└── src
└── bin
├── media
│ ├── image.rs
│ └── main.rs
└── strings
├── main.rs
└── parse.rs
This official document implies that I may can't achieve what I want to do though.

Cargo/Rust does not have a built-in way for you to do this. However, you can use cargo-make. Similar to cargo clippy or cargo fmt, cargo-make is an extension to the cargo command that gives you access to cargo make. It can be installed with cargo install (The --force just tells it to overwrite any previous version of cargo-make).
cargo install --force cargo-make
You can batch together building multiple crates, binaries, or arbitrary shell commands. The main benefit it has over something like a traditional Makefile is it is cross-platform and is optimized so it will build multiple crates at the same time when possible. After installing it with cargo make [task]. Here is an example from their docs of what a Makefile.toml could look like:
[tasks.format]
install_crate = "rustfmt"
command = "cargo"
args = ["fmt", "--", "--emit=files"]
[tasks.clean]
command = "cargo"
args = ["clean"]
[tasks.build]
command = "cargo"
args = ["build"]
dependencies = ["clean"]
[tasks.test]
command = "cargo"
args = ["test"]
dependencies = ["clean"]
[tasks.my-flow]
dependencies = [
"format",
"build",
"test"
]

Related

How do I run cargo flamegraph on unit-tests in lib crate

I have a library crate which I want to profile using cargo flamegraph. But however I try to run cargo flamegraph, I get error messages. The library has the following structure:
utilrs
├── Cargo.lock
├── Cargo.toml
└── src
├── fileprocessor.rs
├── filesplit.rs
├── forwardstar.rs
├── lib.rs
├── persistence.rs
└── xmlparser.rs
What I am looking for is to exectue a test called split_and_process_file within a tests module within the fileprocessor.rs file.
I tried different command line combinations, but they all resulted in errors. Some of the things I tried are:
cargo flamegraph --unit-test -- fileprocessor::tests::split_and_process_file resulting in :Error: crate has no automatically selectable target
and
cargo flamegraph --unit-test utilrs -- fileprocessor::tests::split_and_process_file resulting in error: no bin target named `utilrs`.
System Information:
|Component | Version|
|----------|--------|
|Operating System|Windows 10, 64-bit|
|cargo |cargo 1.65.0-nightly (4ed54cecc 2022-08-27)|
|rustc|rustc 1.65.0-nightly (84f0c3f79 2022-09-03)|
As the error indicates: error: no bin target named 'split_and_process_file', there is no bin target.
A target for cargo is something like lib, bin, etc. That said, there is no such called split_and_process_file function in your main.rs file.
Oops, you don't have main.rs, then you should create one and add your function. Then, run flamegraph with your bin files.. Don't forget to use the --release with cargo run.
As the flamegraph crate page says:
by default, --release profile is used,
but you can override this: cargo flamegraph --dev
If you still want to use a lib but not a bin, then use the --dev thingy.

Local crate not found when trying to update edition via cargo fix

Context:
I have a local C library called 'libmaths' that then uses Bindgen to create a 'libmaths-sys' crate that is locally stored in the same directory as my project.
Issue:
I want to use some of the features in the 2021 edition of Rust and currently my project is built off 2018. I am trying to update the project by following the instructions at:
https://doc.rust-lang.org/cargo/commands/cargo-fix.html
Run cargo fix --edition. Consider also using the --all-features flag if your project has multiple features. You may also want to run cargo
fix --edition multiple times with different --target flags if your
project has platform-specific code gated by cfg attributes.
Modify Cargo.toml to set the edition field to the new edition.
Run your project tests to verify that everything still works. If new
warnings are issued, you may want to consider running cargo fix again
(without the --edition flag) to apply any suggestions given by the
compiler.
To run cargo fix --edition I am told by the compiler to remove the edition="2018" in cargo toml. Following this I receive a compile error stating that libmaths-sys cannot be found. The code compiles and executes normally in 2018 but not without this edition tag.
I can not find anyone with a similar issue, this is my first stackoverflow question so not sure how best to show my code given its a context of a small project.
Error code
error[E0432]: unresolved import `libmaths_sys`
--> src/main.rs:1:5
|
1 | use libmaths_sys::*; // lib.rs in sys crate
| ^^^^^^^^^^^^ maybe a missing crate `libmaths_sys`?
File Structure and general overview of project
.
├── Cargo.lock
├── Cargo.toml
├── libmaths
│   ├── add.c
│   ├── add.h
│   └── subtract.c
├── libmaths-sys
│   ├── build.rs
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── src
│   │   └── lib.rs
│   └── wrapper.h
├── README.md
└── src
  ├── lib.rs
  └── main.rs
libmaths contains add.c that returns a + b and subtract.c which returns a - b, with a header add.h directing to both .c files
The Rust code generated by bindgen is attached via lib.rs in the libmath-sys crate which links to the OUT DIR which I have omitted from the tree to save 200 lines of file names.
Try updating edition="2018" to edition="2021"; otherwise it defaults to edition="2015" which requires usage of extern crate.
As #Solomon Ucko directed me to, rustup update held the key.
Running rustup update produced:
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: syncing channel updates for '1.48-x86_64-unknown-linux-gnu'
info: checking for self-updates
stable-x86_64-unknown-linux-gnu unchanged - rustc 1.59.0 (9d1b2106e 2022-02-23)
1.48-x86_64-unknown-linux-gnu unchanged - rustc 1.48.0 (7eac88abb 2020-11-16)
info: cleaning up downloads & tmp directories
In the end, rustup was using the old 1.48 version and not the installed 1.59 version.
To switch to the newer vesion I ran:
rustup default stable
I then could follow the instructions from the link in the original question to change the edition.

Why is cargo build cache invalidating?

I have a barebones workspace project:
.
├── build-debug.sh
├── Cargo.lock
├── Cargo.toml
├── common
│   ├── Cargo.toml
│   └── src
│   └── lib.rs
├── rs-test.iml
├── server
│   ├── Cargo.toml
│   └── src
│   └── main.rs
└── wui
├── Cargo.toml
└── src
└── lib.rs
The rs files either empty or just an empty main function.
The server and the wui depends on common: common = { path = "../common" }.
The common project has one crates.io dependency with I suppose build script or proc macro dependency.
The build script:
cargo build -p wui --target wasm32-unknown-unknown
cargo build -p server
The problem:
When I rebuild the unchanged project, some wui dependencies are getting invalidated/rebuilt, then the same for server.
Either:
remove the wasm32 target flag
replace the dependency with a simple crate without build time compiled dependencies
It does not rebuild the subprojects anymore.
Is this a cargo bug? What can I do?
It's probably not a cargo bug. What is likely happening here is that your crates.io dependency (you don't mention what it is, which might have been useful) has different dependencies or features depending on the target architecture. Thus, as you alternate between building the WASM target and your host target, stuff is being rebuilt.
Perhaps it would be better in this case to stop using the Cargo workspace and build the server and wui separately; this way you'll have separate target directories for the server and wui, which takes some extra disk space and takes longer for non-incremental compilation, but will prevent you from having to rebuild that stuff all the time as you build both.

Building submodule binary crates with cargo

I have the following crate structure:
|── proj/
└── src/
└── bin/
└── foo-bin-rs/
└── src/
└── main.rs
└── Cargo.toml
└── main.rs
└── Cargo.toml
└── build.rs
foo-bin-rs is a submodule. I'd like to find a clean way to issue a build
command through cargo that would build foo-bin-rs as a part of the build
command used for proj. I've not found any documentation that uses the
src/bin directory with binaries that are their own separate crate, just
single files. My first thought was to have a build.rs that issued its own
cargo command, but I couldn't find a flag for cargo that allowed passing a
directory to use as root. What is the canonical solution for this?
My first thought was to have a build.rs that issued its own cargo command, but I couldn't find a flag for cargo that allowed passing a directory to use as root.
There is a command-line argument, but it doesn't expect a directory; rather, it expects a full path to the Cargo.toml file. The argument is named --manifest-path, and it's available on many subcommands, such as build and run. It's used like this (note that relative paths are also valid):
$ cargo build --manifest-path=/path/to/proj/src/bin/foo-bin-rs/Cargo.toml
If you need to run the executable from your build script, you can simply use cargo run to build and run in one go, as usual.

How do I tell Cargo to build files other than main.rs?

Here is my directory structure:
lowks#lowkster ~/src/rustlang/gettingrusty $ tree .
.
├── Cargo.lock
├── Cargo.toml
├── foo.txt
├── src
│   ├── boolean_example.rs
│   ├── function_goodbye_world.rs
│   ├── listdir.rs
│   ├── looping.rs
│   ├── main.rs
│   ├── pattern_match.rs
│   └── write_to_file.rs
└── target
├── build
├── deps
├── examples
├── gettingrusty
└── native
6 directories, 11 files
When I run 'cargo build', it seems to only build main.rs. How should I change Cargo.toml to build the rest of the files too?
Put other.rs file into bin subfolder of src folder (./src/bin/other.rs). And run cargo build --bin other or cargo run --bin other
The Rust compiler compiles all the files at the same time to build a crate, which is either an executable or a library. To add files to your crate, add mod items to your crate root (here, main.rs) or to other modules:
mod boolean_example;
mod function_goodbye_world;
mod listdir;
mod looping;
mod pattern_match;
mod write_to_file;
To access items defined in another module from your crate root, you must qualify that item with the module name. For example, if you have a function named foo in module looping, you must refer to it as looping::foo.
You can also add use statements to import names in the module's scope. For example, if you add use looping::foo;, then you can just use foo to refer to looping::foo.
For more information, see Separating Modules into Different Files in The Rust Programming Language.
There are a few different types of binaries or targets that cargo recognizes:
binaries
libraries
benchmarks
integration tests
examples
For example, if the file boolean_example.rs is a standalone example that you want to run you can put in inside an examples directory and tell cargo about it like so:
[[example]]
name = "boolean" # examples/boolean.rs
This lets you invoke your example with cargo run --example boolean
Read the cargo book's page on package layout as well to see how these target directories can be structured.
you can include your testing in the main.rs file as following >>
Filename: src/main.rs
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn this_test_will_pass() {
let value = 4;
assert_eq!(4, value);
}
#[test]
fn this_test_will_fail() {
let value = 8;
assert_eq!(5, value);
}
}
Or call them from your tests file.
then run them using test command: cargo test
from filename: lib/tests.rs
mod tests;
tests::run();
in this case main.rs will be built but only tests.rs file will be
executed.
more prove:

Resources