How to solve ”Blocking waiting for file lock on build directory“ problem? - rust

I want to generate some .rs code in my rust program, and I create a package gen-proxy-ffi which use bindgen to do that. The following command can generate codes I need.
cargo run --package gen-proxy-ffi --bin gen-proxy-ffi
When the codes are generated, I can then build the whole project by
cargo build
Now, I want cargo build will automaticly generate code by calling cargo run --package gen-proxy-ffi --bin gen-proxy-ffi. I know I can write some code to build.rs to specify rust's compiling routine, so I write the following codes, where make-gen-proxy-ffi.sh encaplsules cargo run --package gen-proxy-ffi --bin gen-proxy-ffi.
// build.rs
use std::process::Command;
use std::io::Write;
fn main() {
let o = Command::new("sh").args(&["make-gen-proxy-ffi.sh"]).output().expect("sh exec error!");
}
However, when running cargo build now, it prints out the following error
+ cargo run --package gen-proxy-ffi --bin gen-proxy-ffi --
Blocking waiting for file lock on build directory
After some searching, I know it is because cargo build on the same project twice at one time.
However, from this post, I found no solution to this, so I wonder if there are any ways I can generate code and build the whole project by one cargo build?

Related

When should I use the --bin option for cargo new?

What is the difference between cargo new <project_name> --bin and cargo new <project_name>?
It seems both commands make exactly the same project; all components are consistent.
I think --bin stands for "binary", but I don't know when to use this option or not.
There is no difference between cargo new and cargo new --bin. From First Steps with Cargo, emphasis mine:
To start a new package with Cargo, use cargo new:
$ cargo new hello_world
Cargo defaults to --bin to make a binary program. To make a library, we would pass --lib, instead.
Likewise, Cargo's command line help tells you the same thing. From cargo new --help, with some irrelevant lines removed:
% cargo new --help
OPTIONS:
--bin Use a binary (application) template [default]
--lib Use a library template
See also
Why does `cargo new` create a binary instead of a library?
What is the difference between library crates and normal crates in Rust?

How to run cargo with features flag

I'm trying to learn rust by writing CLI but i can't do cargo run with features passed and i don't understand why. I read docs / stack and i still don't see why this is happening. It feels like it should work this way https://doc.rust-lang.org/cargo/commands/cargo-run.html
I'm trying to run this code
https://github.com/clap-rs/clap/blob/master/examples/17_yaml.rs
with command cargo run --features=yaml or cargo run --features yaml. I tried many combinations, none of them worked.
My Cargo.toml looks like that:
[dependencies.clap]
version = "*"
default-features = false
features = ["yaml"]
When i run i have error:
:!cargo run --features=yaml
error: Package `fun v0.1.0 (/Users/XXX/Projekty/rust/fun)` does not have these fe
atures: `yaml`
shell returned 101
What am i doing wrong?
Their code expects you to have cloned the clap repository, changed into its directory, and then run cargo run --features yaml --example 17_yaml from there. You can read more about how the cargo examples feature works here.
If you’re planning on copying their code, as noted in that example code, you have to remove this conditional compilation attribute:
// Note: If you're using clap as a dependency and don't have a feature for your users called
// "yaml", you'll need to remove the #[cfg(feature = "yaml")] conditional compilation attribute
#[cfg(feature = "yaml")]
fn main() {
Otherwise it will load this other main implementation and emit that error:
#[cfg(not(feature = "yaml"))]
fn main() {
// As stated above, if clap is not compiled with the YAML feature, it is disabled.
println!("YAML feature is disabled.");
println!("Pass --features yaml to cargo when trying this example.");
}
You don’t actually need to pass --features on the command line unless you are running their example within their crate as described above. You should also remove this whole function if you’re copying their code! It is only relevant when run as an example.

Get the --bin argument in build.rs

I'd like to handle each binary differently in build.rs.
I can use env!("CARGO_PKG_VERSION") to get the version info from Cargo.toml.
Is there something similar for getting the bin argument?
I'd like to get binary_name when running cargo run --bin binary_name.

How do I run a project's example using Cargo?

I'm trying to run the example code from this project. Following the instructions on the Cargo docs, I did the following:
git clone https://github.com/basiliscos/rust-procol-ftp-client
cd rust-procol-ftp-client
cargo run
cargo test
cargo test should also have compiled the example according to the Rust docs.
Although cargo test executes successfully, when I change into the target/debug directory, I don't find an executable for ftp-get (which is the example code). The target/debug/examples directory is also empty.
What is the best way to go about running this example?
You can run a specific example with:
cargo run --example name_of_example
where name_of_example is the base filename (without .rs)
or to run it in release mode:
cargo run --release --example name_of_example
To pass arguments to the example:
cargo run --example name_of_example -- arguments go here
cargo run will automatically build (or rebuild) the program first if it's out of date.
Try the following:
cd rust-procol-ftp-client
cargo build --examples
./target/debug/examples/ftp-get

Is there a simpler way to run clippy on my build script?

In a Cargo project, I can easily run clippy on my src code using this command:
rustup run nightly cargo clippy
However, if I'm using a build script, I'd like to run clippy on that as well. For instance, if my build.rs file looks like this:
fn main() {
let foo = "Hello, world!";
println!("{}", foo);
}
I'd like to see this when I run clippy:
warning: use of a blacklisted/placeholder name `foo`, #[warn(blacklisted_name)] on by default
--> build.rs:2:9
|
2 | let foo = "Hello, world!";
| ^^^
|
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#blacklisted_name
The only way I can think of to run clippy on my build script is to copy it into a cargo new temporary project, run clippy, make my changes there, and copy back, but this is horribly inconvenient and quickly becomes infeasible when build dependencies and the like are added to the mix.
Is there a simpler way to analyze my build script with clippy?
Note: This solution no longer works. The clippy plugin feature has been removed (source).
There are two ways to use Clippy: the cargo clippy command and the clippy compiler plugin. cargo clippy detects the build script as a dependency of the main project, so it doesn't load the compiler plugin.
Therefore, the other option is to use the compiler plugin directly. The instructions for doing this are in clippy's README. We need to make a few adaptations for using it on the build script, though.
First, we need to add clippy as a build dependency:
[build-dependencies]
clippy = { version = "*", optional = true }
[features]
default = []
Adding it to [dependencies] instead will not work (the result is error[E0463]: can't find crate for `clippy`), as Cargo will not pass the path to dependencies to the compiler when building the build script.
Then, we need to add this at the top of build.rs:
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
Finally, we need to build with the clippy feature enabled:
$ cargo build --features clippy
If you want to run clippy on both the build script and on the main project when you use the command above, add the same clippy dependency to [dependencies], then add the cfg_attr attributes to the crate root(s) (lib.rs, main.rs, etc.).

Resources