How to force --document-private-items from Cargo.toml? - rust

Is there a way of forcing private items documentation on docs build?
It can be done manually adding the doc flag --document-private-items, but I would like to force it in Cargo.toml level for example.

You can do this not with Cargo.toml but cargo's config. In your project (or in $CARGO_HOME if you want this to apply for all of your projects) create .cargo/config.toml with following contents:
[build]
rustdocflags = ["--document-private-items"]
Here is the link to the documentation.

Related

What the difference between Cargo.toml and .cargo/config.toml

I am learning to write a kernel by using Rust.
I added [dependencies] bootloader = "0.9.8" to .cargo/config.toml, but I got an error.
I forgot the specific error, but when I move [dependencies] bootloader = "0.9.8" to Cargo.toml and then run "cargo bootimage" on terminal, everything goes well.
Cargo.toml is where you put everything your project need. Dependencies, project details, project settings etc..
cargo/config.toml is a configuration file for Cargo. You usually don't need to touch it, and it usually uses more advanced things. It can be configured per project, although also globally. It sets for example what commands Cargo will run, what environment variables it will set, etc..
All details about both are in the documentation - Cargo.toml, config.toml.

How to find the current version of a Rust library?

The Cargo.toml file requires me to state the version of a dependency, e.g. rand = "0.6".
I want to use the package rand_pcg, but don't know the version. How may I find it?
Use the web
crates.io
Navigate to https://crates.io/, type your crate name into the search box, and see the version. You can also click the clipboard icon to copy the complete dependency to add to Cargo.toml.
docs.rs
Navigate to https://docs.rs/, type your crate name into the search box, and see the version. If you click through to the crate, you can then click the clipboard icon to copy the complete dependency to add to Cargo.toml.
lib.rs
Navigate to https://lib.rs/, type your crate name into the search box, and see the version. If you click through to the crate, you can then click on the "installation" tab to see the complete dependency to add to Cargo.toml.
Use the command line
cargo build
Add the wildcard dependency to your Cargo.toml (e.g. rand_pcg = "*"). Run cargo build and note the version it picked (e.g. Compiling rand_pcg v...) or look in Cargo.lock for the entry for the crate. Edit Cargo.toml to use this version.
cargo add
Install cargo edit then run cargo add rand_pcg. This is my preferred route.
See Is there a command to automatically add a crate to my Cargo.toml? for more.
cargo search
As mentioned by user2722968, you can run cargo search rand-pcg and it will output the dependency line.

How can I force `build.rs` to run again without cleaning my whole project?

How can I force build.rs to run again without cleaning my whole project? I checked cargo build --help but I couldn't find anything related to build.rs.
If you print
"cargo:rerun-if-changed=<FILE>"
the build will be triggered every time the file has changed.
rerun-if-changed=PATH is a path to a file or directory which indicates that the build script should be re-run if it changes (detected by a more-recent last-modified timestamp on the file). Normally build scripts are re-run if any file inside the crate root changes, but this can be used to scope changes to just a small set of files. -- source
I'm not aware of a solution without changing a file manually (I just put a whitespace anywhere in my build.rs, it will be removed by rustfmt though).
I have several buildscripts in my projects, and mostly these two lines give me a nice solution:
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=path/to/Cargo.lock");
but I guess you are looking for a command rustc/cargo command. Anyway, you can put in a small script, which will edit a certain file, which will trigger the build-process.
Register build.rs as a crate's bin target:
Add this to your Cargo.toml file:
[package]
edition = "2018"
build = "build.rs"
[[bin]]
name = "force-build"
path = "build.rs"
required-features = ["build_deps"] # only needed for build-dependencies
If you have any [build-dependencies] (e.g. some_crate = "1.2.3"), you need to add those to (the main) [dependencies] (sadly no [bin-dependencies] as of yet), but you can make them optional:
[dependencies]
some_crate = { version = "1.2.3", optional = true }
[features]
build_deps = ["some_crate"]
Then you can run the build script with:
$ cargo run --bin force-build --features build_deps
(or $ cargo run --bin force-build when no [build-dependencies])
You can even disable the automatic call of the build script by replacing the build = "build.rs" line in Cargo.toml with build = false
Note: since the OUT_DIR env var is not present for bin targets, if your build.rs script uses env!("OUT_DIR"), you may "fix this" by using concat!(env!("CARGO_MANIFEST_DIR"), "/target/") instead.
If build.rs changes, Cargo already rebuilds the project:
Note that if the build script itself (or one of its dependencies) changes, then it's rebuilt and rerun unconditionally, so cargo:rerun-if-changed=build.rs is almost always redundant (unless you want to ignore changes in all other files except for build.rs). doc
On Linux, I will just do touch build.rs && cargo build. For Windows, see Windows equivalent of the Linux command 'touch'?
If you got target under gitignore (which you should) this might be useful for any file changes when you're developing and testing the build script.
if Path::new(".git/HEAD").exists() {
println!("cargo:rerun-if-changed=.git/HEAD");
}
if you're trying to rebuild based on non-rust or include!() files that might've changed, you can use
const _: &[u8] = include_bytes!("foobar.baz");
to ensure that any changes to those files will trigger a new build. pretty sure this solution adds neither time nor filesize.
you can shove this into a macro too, so its easy to do a bunch of files.
macro_rules! build_on{($file:literal) => {
const _: &[u8] = include_bytes!($file);
}
build_on!("foobar.baz");

How to package source code from outside the project directory with Cargo?

I am trying to create Rust bindings for the C++ library cryptominisat. The actual code works, but I'm not sure how to properly package it up with Cargo.
The git repository looks like
src/
c++ code here
.gitignore
readme, etc.
I added a rust directory, and created my Cargo project inside of it like so
rust/
cryptominisat/
Cargo.toml
build.rs
src/
rust code here
src/
c++ code here
.gitignore
readme, etc.
Unfortunately, cargo package doesn't seem to want to package up anything outside of the rust/cryptominisat directory, which means it doesn't include the C++ code needed to actually build the library. What can I do? I don't want to move the entire repository into the rust directory if I can avoid it, since that would make it impossible to merge upstream.
The way it's generally solved:
Use a git submodule (or a script run before publishing) to embed a copy of the C++ repo inside the Rust repo (e.g. in rust/cryptominisat/vendor/). During development you could use a symlink instead to avoid having two copies of the C++ code.
Use build.rs to download a tarball/clone/rsync the code at build time. You can dump it into OUT_DIR env var specified by Cargo to avoid polluting user-visible directories.
Make the C++ code a system-level library. The Rust package would not build it, but expect it's already installed, and only search for it and specify link flags for it. That's how most *-sys crates work.

How do I tell Cargo to check a local directory for a replacement dependency and use it?

I am trying to understand how to change a broken dependency in Rust. I cloned the code from GitHub and updated the dependencies in the Cargo.toml so it can compile, but how do I use it in my project?
Check out the Cargo documentation on overriding a dependency:
Cargo looks for a directory named .cargo up the directory hierarchy of your project [...] To specify overrides, create a .cargo/config file in some ancestor of your project’s directory [...] Inside that file, put this:
paths = ["/path/to/project"]
This array should be filled with directories that contain a Cargo.toml.

Resources