Specify build file for an example - rust

I have a build script that is unnecessary for the library but required to build some examples. How do I specify a build file for an example with Cargo? I tried the following:
[[example]]
name = "basic"
build = "examples/build.rs"
but Cargo tells me the build key is unused.

Related

How to pass rustflags to artifact dependency binary?

I want to find a way to pass rustflags to artifact dependency bin.
Below is the story.
I write my toy OS currently, and using artifact dependency because this is suggested at rust-osdev/bootloader repositiory(descriptions are Booting section of this README) and I thought this is a useful way. However, I find that this way seems not to pass rustflags I attached in .cargo/config.toml in my kernel workspace like below.
[build]
target = "x86_64-unknown-none"
rustflags = ["-C", "relocation-model=static", "-C", "link-arg=-no-pie"]
[unstable]
build-std = ["core", "compiler_builtins"]
build-std-features = ["compiler-builtins-mem"]
In above config, I expect that kernel elf type is EXEC, but actually, that type is DYN, i.e. I got PIE Elf file even though I write static and no pie flags.
I tried some patterns like below.
run cargo build directly in kernel workspace directory
set invalid rustflags like link-args=hoge and run cargo build in root project directory
As a result
non pie elf (Elf type is EXEC) is created with no errors.
no errors appeared while compile even if I run cargo clean before build.
That's why, I suspect the rustflags I wrote in .cargo/config.toml does not work when its workspace is treated as binary artifact dependency.
Reproduction code is here.
If there is a way to pass rustflags, please teach me.
Add your build.rs in workspace, <project root path>/<kernel workspace name>/build.rs in my case, and put script like below in it.
fn main() {
println!("cargo:rust-link-arg=-no-pie");
}

Cargo build includes path in output binary

I'm using cargo build to compile my project.
However, for dependencies the full absolute path is logged in the outputbinary when using strings on the binary.
For example: /home/evrey/.cargo/registry/src/test.net-2dcc6299db9ec823/winit-0.20.0-alpha6/src/platform_impl/linux/x11/window.rs.
How can I remove the private paths from the compiled binary using cargo build?

Depend on the binary of another workspace package being built by cargo

I have a workspace project with multiple packages. The two important ones are:
flowc - which is a lib and a binary
flowstdlib
flowc is a kind of compiler that I build as part of the project.
flowstdlib has a build script, that uses the flowc built binary to build that package (generate "code", files etc), so I need the flowc compiler ready when flowstdlib is to be built.
In cargo.toml of flowstdlib I define flowc as a build dependency:
[build-dependencies]
flowc = {path = "../flowc", version = "0.31.0" }`
(I've tried making it also a dependency, but no change)
in the build.rs of flowstdlib I look for it in the path, and if not found in the ../target/debug/flowc location:
let flowc = if Path::new(env!("CARGO_MANIFEST_DIR")).join("../target/debug/flowc").exists() {
"../target/debug/flowc"
} else if Simpath::new("PATH").find_type("flowc", FileType::File).is_ok() {
"flowc"
} else {
""
};
When I run the build, it looks like it's trying to build multiple packages at the same time in parallel:
Compiling flowstdlib v0.31.0 (/Users/andrew/workspace/flow/flowstdlib)
Compiling flowsamples v0.31.1 (/Users/andrew/workspace/flow/samples)
warning: Could not find `flowc` in $PATH or `target/debug`, so cannot build flowstdlib
error: failed to run custom build command for `flowsamples v0.31.1 (/Users/andrew/workspace/flow/samples)`
and the flowstdlib build fails as flowc binary is not built yet.
Since the build continues and eventually finishes building flowc, if I re-run the build, it will work the second time around (as flowc binary is now found).
So:
it looks like a build-dependency does wait for the depended-on binary to be built (maybe it waits for the library to be built, hard to tell)
Question
How I can make the build of flowstdlib wait for the completion of the flowc binary?
(without forcing a non-parallel build)
Pending the RFC landing, my workaround is to split the build into two commands (I'm using a Makefile to invoke them currently):
* cargo build -p flowc # will complete the build of the flowc binary
* cargo build # will build the entire workspace, including flowstdlib

How to specify an environment variable using the rustc-env flag?

I want to set rustc-env=VAR=VALUE so that I could access it using env::var("VAR") in my code. However, I'm not clear on where to specify it. Can I set the environment variable VAR in the Makefile?
TL;DR
build.rs
fn main() {
println!("cargo:rustc-env=VAR=VALUE");
}
src/main.rs
fn main() {
let var = env!("VAR");
}
The documentation that you linked is for a Cargo build script:
The Rust file designated by the build command (relative to the package root) will be compiled and invoked before anything else is compiled in the package, allowing your Rust code to depend on the built or generated artifacts. By default Cargo looks up for "build.rs" file in a package root (even if you do not specify a value for build). Use build = "custom_build_name.rs" to specify a custom build name or build = false to disable automatic detection of the build script.
On the same page, there's a section that describes outputs of build.rs
All the lines printed to stdout by a build script are written to a file [...] Any line that starts with cargo: is interpreted directly by Cargo. This line must be of the form cargo:key=value, like the examples below:
cargo:rustc-env=FOO=bar
It then details rustc-env:
rustc-env=VAR=VALUE indicates that the specified environment variable will be added to the environment which the compiler is run within. The value can be then retrieved by the env! macro in the compiled crate. This is useful for embedding additional metadata in crate's code, such as the hash of Git HEAD or the unique identifier of a continuous integration server.
env! is a macro.
access it using env::var("VAR")
No. env::var is for reading environment variables set when the program runs, not when the program is compiled.
See also:
Is it possible to initialize a variable from an environment variable at compilation time when using no_std?

How to build or run a specific Rust binary project in Atom?

I am using multiple main files using a single Cargo.toml:
[package]
name = "rust_example"
version = "0.1.0"
authors = [""]
[dependencies]
[[bin]]
name = "main"
path = "src/main.rs"
[[bin]]
name = "fibonachi"
path = "src/fibonachi/main.rs"
I tested on console
cargo run --bin main` and `cargo run --bin fibonachi
And it compiles correctly.
I installed Atom along with several plugins (build, build-cargo, busy, language-rust, linter). When I compile with Atom, it shows these lines:
error: `cargo run` requires that a project only have one executable; use the `--bin` option to specify which one to run
error: `cargo run` requires that a project only have one executable; use the `--bin` option to specify which one to run
I can't find how to specify which binary I'd like to build from within Atom.

Resources