I want to run the following commands side by side
cargo watch "check"
cargo watch "build"
I want to run cargo watch build in the background and use cargo watch check to look at the error messages.
The problem is that cargo watch check always runs after cargo watch build and then also needs to wait on the file lock
cargo check
Blocking waiting for file lock on build directory
I don't think that a file lock would be required for cargo check. Is it possible to disable file locking in cargo?
I don't think that a file lock would be required for cargo check.
I can think of in one reason: build scripts. A build script can generate files that are included in the crate, checking the crate without generating the files would probably produce errors. Running 2 instances of a build script in parallel is not a good idea (conflicting file writes, etc), so the locking is required.
I want to run the following commands side by side
You have two options:
Sequential: install cargo-do and run
cargo watch "do check, build"
this will first run cargo check and then cargo build (if cargo check did not find an error).
Parallel: change the target-dir for one of the two cargo commands:
CARGO_TARGET_DIR=/tmp cargo watch check
Related
I'm trying to use GNU autotools to configure, make, and install a program. I'm running into problems when I configure and make the program inside a GitLab job. It builds without errors, the problem is when I try to run the binary I built in the test jobs it errors out saying the binary doesn't exist because the config file still has the absolute path from the build job? Can I update the config.h without recompiling? I just need to be able to use the binary without errors?
On Linux, if I build my project with cargo build, the result will be placed in target/debug. If I instead build it with cargo build --target x86_64-unknown-linux-gnu, the result is put in target/x86_64-unknown-linux-gnu/debug, even though the result is the same.
It's inconvenient to supply the --target argument when I run commands manually. Setting build.target in .cargo/config.toml isn't very convenient either as I'd have to make sure to always do that. Our build scripts on the other hand need an explicit --target, because those scripts may run on different systems. For example, we want to make Windows builds on a Linux machine or vice versa.
If I mix manual commands (where I don't want to manually type out --target) and scripts (that use --target to make sure they build for the correct platform), Cargo will spend a lot of time rebuilding the same thing in two different directories.
So, that's why I wonder if it is possible to configure Cargo so that it puts the result in target/<target>/<mode> even when there is no explicit --target argument.
I have a simple Program written in Rust.
When I type cargo run in terminal it always shows:
Updating crates.io index...
And this takes around 40 seconds.
But I just wan to execute my Program and I think cargo does not need to update the index every time I run the Program, since this makes testing very slow...
Is there an option to skip that?
I figured it out:
Since I am running cargo in a Docker container, I need to store the cargo cache persistently because it resets every time the container restarts.
There is The Cargo Book that contains all the information you'd ever want to know about cargo. See this for disabling index update.
I've tried to use this feature myself, and here's the command that worked:
cargo +nightly run -Z no-index-update
The +nightly thing is new to me as well, but I find it here.
This answer has been brought up by users thefeiter and Captain Fim but I think a more complete answer could be cool rust/linux newcomers
When we use docker run, the index is updated every time the container is run because the cache is not shared between runs. So to skip the index update, as Captain Fim mentioned, you need to set the CARGO_HOME environment variable on the container. This environment variable should contain the path to a persistent folder. One simple solution is using the docker volumes to share cache between host and container.
In my case, I created at cargo_home folder in my project (could be somewhere else) on my host. I have passed the whole project folder to the container and set the docker env variable of CARGO_HOME to the container path to the cargo_home folder.
The command to build my app looks like this
docker run --rm --user "$(id -u)":"$(id -g)" -e CARGO_HOME=/usr/src/myapp/cargo_home -v "$PWD":/usr/src/myapp -w /usr/src/myapp rust-compiler cargo build
The first time you will run this command, it will take some time, but you should see the cargo_home folder getting filled with files. The next time you run the command, it should use the cargo_home folder as cache. This should be almost instant if your app source code did not change.
While I am learning rust, I have a crude means of building a non-rust c/c++ library that lives in a submodule. My build script (build.rs) now looks like:
use std::process::Command;
fn main() {
// EXTERN_C
// Build the c-library
Command::new("make").args(&["-C", "cadd"]).status().unwrap();
// The name of the library to link to, i.e. like: -l<lib>
println!("cargo:rustc-link-lib=dylib=add_x64Linuxd");
// The library search path for linking, i.e. like -L<path>
println!("cargo:rustc-link-search=native=cadd/lib");
// The run-time library search path (LD_LIBRARY_PATH)
println!("cargo:rustc-env=LD_LIBRARY_PATH=cadd/lib");
}
This is working nicely, the makefile within cadd/ sorts out any build/re-build deps etc. The only thing I can't do at the moment is hook in make -C cadd clean when I run cargo clean. Ideally I would like it to run the clean make target at the same time. The command would look like:
Command::new("make").args(&["-C", "cadd", "clean"]).status().unwrap();
But I don't know how to get such a command to run during cargo clean. Is there a "clean script" like there is a "build script" - or another method?
Eventually I will get around to learning how to wrap up my makefile project into a cargo crate (I think that's the right terminology) - so I know this is not the optimal way to do this, but I want to get this working in a basic way first (so my head does not explode!).
The cargo clean command simply deletes the cargo target directory.
One solution is for your Makefile to output its compilation artifacts(all files it generates) into the target directory.
You could also change the directory cargo outputs its artifacts to, either via the --target-dir CLI option or by adding the following to the .cargo/config:
[build]
target-dir = "some/path"
How can I make a program in Rust which can be executed from anywhere without using cargo run, by just clicking on the file?
Is there any crate? I have written code for snake game and I want to run it by just clicking on a file.
If you compile a Rust application with:
cargo build --release
it will place a binary file in ./target/release. So if your application is called snake_game, you can run it with ./target/release/snake_game, or by double-clicking on that file.
This binary is completely self-contained, so you can move or copy it to somewhere else on your computer.
First build your binary for release
cargo build --release
Next handle permissions
Typically chmod +x target/release/whateverYourProgramIsCalled to make executable, but cargo did this for us already
You can check it's Octal Permissions
ls -l target/release/whateverYourProgramIsCalled
chmod +x target/release/whateverYourProgramIsCalled
ls -l target/release/whateverYourProgramIsCalled
As you can see nothing has changed... the permissions were already correct for executing
Run that executable
./whateverYourProgramIsCalled
Optional: run from anywhere
You can run that binary anywhere from the command line
To do this you need to add it to your path
For mac you can add to your path from /etc/paths
whatever editor you prefer.... vi, code, etc...
sudo code /etc/paths
I added a path like this, saved and authenticated with a password
/Users/`whoami`/code/rust/binaries
whoami command is surrounded by `
next copy your new binary over to where it needs to be, in that binaries folder
cp whateverYourProgramIsCalled /Users/`whoami`/code/rust/binaries
Then open a new terminal window
Check your command is in your path
where whateverYourProgramIsCalled
Run your command from anywhere
whateverYourProgramIsCalled
Rejoice
There is another method you can do by using rustc. It will create an executable binary file in the same directory where your file exists.
Make sure you are in the src directory and the name of your file is main.rs.
rustc main.rs
./main
The advantage of using rustc is that you can run any file not only main.rs. just do:
rustc filename.rs
./filename
You can run it from terminal and also by clicking on that file.
Just wanted to add another answer here, not sure if it's related to a more recent version of rust.
If in the root of your project you just run the command cargo install --path . it will add it to cargo and allow you to run the binary just with project name.