From 458ea5117883d80970ca2669824a5c0038d4d08c Mon Sep 17 00:00:00 2001 From: EvilGenius1010 Date: Thu, 5 Feb 2026 17:41:55 +0530 Subject: [PATCH] doc: Update build script examples to use build-rs --- .../src/reference/build-script-examples.md | 43 ++++++++------ src/doc/src/reference/build-scripts.md | 57 ++++++++++++++++++- 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/doc/src/reference/build-script-examples.md b/src/doc/src/reference/build-script-examples.md index 567870c5c6c..7d08130a470 100644 --- a/src/doc/src/reference/build-script-examples.md +++ b/src/doc/src/reference/build-script-examples.md @@ -22,6 +22,8 @@ available. The following is a sample of some popular crates[^†]: [^†]: This list is not an endorsement. Evaluate your dependencies to see which is right for your project. +Note: The examples in this guide use the `build-rs` crate. This is the recommended way to emit build script instructions, as it ensures type safety and correct formatting. To use it, add build-rs to your [build-dependencies]. + ## Code generation Some Cargo packages need to have code generated just before they are compiled @@ -50,6 +52,9 @@ Here we can see that we have a `build.rs` build script and our binary in name = "hello-from-generated-code" version = "0.1.0" edition = "2024" + +[build-dependencies] +build-rs= "0.3.0" ``` Let’s see what’s inside the build script: @@ -71,7 +76,7 @@ fn main() { } " ).unwrap(); - println!("cargo::rerun-if-changed=build.rs"); + build_rs::output::rerun_if_changed("build.rs"); } ``` @@ -156,6 +161,9 @@ Pretty similar to before! Next, the manifest: name = "hello-world-from-c" version = "0.1.0" edition = "2024" + +[build-dependencies] +build-rs= "0.3.0" ``` For now we’re not going to use any build dependencies, so let’s take a look at @@ -180,9 +188,9 @@ fn main() { .current_dir(&Path::new(&out_dir)) .status().unwrap(); - println!("cargo::rustc-link-search=native={}", out_dir); - println!("cargo::rustc-link-lib=static=hello"); - println!("cargo::rerun-if-changed=src/hello.c"); + build_rs::output::rustc_link_search(out_dir); + build_rs::output::rustc_link_lib_kind("static", "hello"); + build_rs::output::rerun_if_changed("src/hello.c"); } ``` @@ -210,6 +218,7 @@ crate](https://crates.io/crates/cc) from [crates.io]. First, add it to the ```toml [build-dependencies] cc = "1.0" +build-rs= "0.3.0" ``` And rewrite the build script to use this crate: @@ -221,7 +230,7 @@ fn main() { cc::Build::new() .file("src/hello.c") .compile("hello"); - println!("cargo::rerun-if-changed=src/hello.c"); + build_rs::output::rerun_if_changed("src/hello.c"); } ``` @@ -310,6 +319,7 @@ links = "z" [build-dependencies] pkg-config = "0.3.16" +build-rs = "0.3.0" ``` Take note that we included the `links` key in the `package` table. This tells @@ -323,7 +333,7 @@ The build script is fairly simple: fn main() { pkg_config::Config::new().probe("zlib").unwrap(); - println!("cargo::rerun-if-changed=build.rs"); + build_rs::output::rerun_if_changed("build.rs"); } ``` @@ -399,6 +409,7 @@ libz-sys = "1.0.25" [build-dependencies] cc = "1.0.46" +build-rs = "0.3.0" ``` Here we have included `libz-sys` which will ensure that there is only one @@ -415,7 +426,7 @@ fn main() { cfg.include(include); } cfg.compile("z_user"); - println!("cargo::rerun-if-changed=src/z_user.c"); + build_rs::output::rerun_if_changed("src/z_user.c"); } ``` @@ -447,7 +458,7 @@ script looks something [like this](https://github.com/sfackler/rust-openssl/blob/dc72a8e2c429e46c275e528b61a733a66e7877fc/openssl-sys/build/main.rs#L216): ```rust,ignore -println!("cargo::metadata=version_number={openssl_version:x}"); +build_rs::output::metadata("version_number","openssl_version"); ``` This instruction causes the `DEP_OPENSSL_VERSION_NUMBER` environment variable @@ -463,26 +474,26 @@ values](https://github.com/sfackler/rust-openssl/blob/dc72a8e2c429e46c275e528b61 ```rust,ignore // (portion of build.rs) -println!("cargo::rustc-check-cfg=cfg(ossl101,ossl102)"); -println!("cargo::rustc-check-cfg=cfg(ossl110,ossl110g,ossl111)"); +build_rs::output::rustc_check_cfgs(&["ossl101","ossl102",]); +build_rs::output::rustc_check_cfgs(&["ossl110","ossl110g","ossl111",]); if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") { let version = u64::from_str_radix(&version, 16).unwrap(); if version >= 0x1_00_01_00_0 { - println!("cargo::rustc-cfg=ossl101"); + build_rs::output::rustc_check_cfgs(&["ossl101"]); } if version >= 0x1_00_02_00_0 { - println!("cargo::rustc-cfg=ossl102"); + build_rs::output::rustc_check_cfgs(&["ossl102"]); } if version >= 0x1_01_00_00_0 { - println!("cargo::rustc-cfg=ossl110"); + build_rs::output::rustc_check_cfgs(&["ossl110"]); } if version >= 0x1_01_00_07_0 { - println!("cargo::rustc-cfg=ossl110g"); + build_rs::output::rustc_check_cfgs(&["ossl110g"]); } if version >= 0x1_01_01_00_0 { - println!("cargo::rustc-cfg=ossl111"); + build_rs::output::rustc_check_cfgs(&["ossl111"]); } } ``` @@ -512,5 +523,5 @@ libraries, which could cause problems. [`rustc-cfg` instructions]: build-scripts.md#rustc-cfg [`openssl` crate]: https://crates.io/crates/openssl [`openssl-sys` crate]: https://crates.io/crates/openssl-sys - +[`build-rs` crate]: https://crates.io/crates/build-rs [crates.io]: https://crates.io/ diff --git a/src/doc/src/reference/build-scripts.md b/src/doc/src/reference/build-scripts.md index 71509ba3af8..d0492e666de 100644 --- a/src/doc/src/reference/build-scripts.md +++ b/src/doc/src/reference/build-scripts.md @@ -15,7 +15,8 @@ that script and execute it just before building the package. // Example custom build script. fn main() { // Tell Cargo that if the given file changes, to rerun this build script. - println!("cargo::rerun-if-changed=src/hello.c"); + //recommended method(using the build_rs crate) + build_rs::rerun_if_changed("src/hello.c"); // Use the `cc` crate to build a C file and statically link it. cc::Build::new() .file("src/hello.c") @@ -23,6 +24,16 @@ fn main() { } ``` +> **Note** +> Build scripts communicate with Cargo by printing specially formatted lines to stdout. +> While you can print these lines manually (e.g., `println!("cargo::rerun-if-changed=build.rs")`), +> we recommend using the [`build-rs`](https://crates.io/crates/build-rs) crate. +> It provides a type-safe API that ensures your build instructions are formatted correctly. +> +> The examples in this reference guide use `build-rs` to demonstrate best practices, +> while the section headers preserve the raw protocol strings for specification purposes. + + Some example use cases of build scripts are: * Building a bundled C library. @@ -157,6 +168,9 @@ option][link-arg] to the compiler, but only when building supported targets highly platform specific. It is useful to set the shared library version or linker script. +**Recommended:** Use [`build_rs::output::rustc_link_arg`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg.html) from the `build-rs` crate. + + [link-arg]: ../../rustc/codegen-options/index.md#link-arg ### `cargo::rustc-link-arg-cdylib=FLAG` {#rustc-cdylib-link-arg} @@ -169,6 +183,8 @@ to set the shared library version or the runtime-path. For historical reasons, the `cargo::rustc-cdylib-link-arg` form is an alias for `cargo::rustc-link-arg-cdylib`, and has the same meaning. +**Recommended:** Use [`build_rs::output::rustc_cdylib_link_arg`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_cdylib_link_arg.html) from the `build-rs` crate. + ### `cargo::rustc-link-arg-bin=BIN=FLAG` {#rustc-link-arg-bin} The `rustc-link-arg-bin` instruction tells Cargo to pass the [`-C @@ -176,6 +192,8 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building the binary target with name `BIN`. Its usage is highly platform specific. It is useful to set a linker script or other linker options. +**Recommended:** Use [`build_rs::output::rustc_link_arg_bin`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg_bin.html) from the `build-rs` crate. + ### `cargo::rustc-link-arg-bins=FLAG` {#rustc-link-arg-bins} The `rustc-link-arg-bins` instruction tells Cargo to pass the [`-C @@ -183,24 +201,32 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building a binary target. Its usage is highly platform specific. It is useful to set a linker script or other linker options. +**Recommended:** Use [`build_rs::output::rustc_link_arg_bins`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg_bins.html) from the `build-rs` crate. + ### `cargo::rustc-link-arg-tests=FLAG` {#rustc-link-arg-tests} The `rustc-link-arg-tests` instruction tells Cargo to pass the [`-C link-arg=FLAG` option][link-arg] to the compiler, but only when building a tests target. +**Recommended:** Use [`build_rs::output::rustc_link_arg_tests`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg_tests.html) from the `build-rs` crate. + ### `cargo::rustc-link-arg-examples=FLAG` {#rustc-link-arg-examples} The `rustc-link-arg-examples` instruction tells Cargo to pass the [`-C link-arg=FLAG` option][link-arg] to the compiler, but only when building an examples target. +**Recommended:** Use [`build_rs::output::rustc_link_arg_examples`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg_examples.html) from the `build-rs` crate. + ### `cargo::rustc-link-arg-benches=FLAG` {#rustc-link-arg-benches} The `rustc-link-arg-benches` instruction tells Cargo to pass the [`-C link-arg=FLAG` option][link-arg] to the compiler, but only when building a benchmark target. +**Recommended:** Use [`build_rs::output::rustc_link_arg_benches`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_arg_benches.html) from the `build-rs` crate. + ### `cargo::rustc-link-lib=LIB` {#rustc-link-lib} The `rustc-link-lib` instruction tells Cargo to link the given library using @@ -222,6 +248,8 @@ through the library target's public API. The optional `KIND` may be one of `dylib`, `static`, or `framework`. See the [rustc book][option-link] for more detail. +**Recommended:** Use [`build_rs::output::rustc_link_lib`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_lib.html) from the `build-rs` crate. + [option-link]: ../../rustc/command-line-arguments.md#option-l-link-lib [FFI]: ../../nomicon/ffi.md @@ -241,6 +269,8 @@ difficult to use the resulting binary. In general, it is best to avoid creating dynamic libraries in a build script (using existing system libraries is fine). +**Recommended:** Use [`build_rs::output::rustc_link_search`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_link_search.html) from the `build-rs` crate. + [option-search]: ../../rustc/command-line-arguments.md#option-l-search-path ### `cargo::rustc-flags=FLAGS` {#rustc-flags} @@ -250,6 +280,8 @@ flags to the compiler. This only allows the `-l` and `-L` flags, and is equivalent to using [`rustc-link-lib`](#rustc-link-lib) and [`rustc-link-search`](#rustc-link-search). +**Recommended:** Use [`build_rs::output::rustc_flags`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_flags.html) from the `build-rs` crate. + ### `cargo::rustc-cfg=KEY[="VALUE"]` {#rustc-cfg} The `rustc-cfg` instruction tells Cargo to pass the given value to the @@ -270,6 +302,8 @@ of `feature=`). Or an arbitrary key/value pair may be used with an `=` symbol like `cargo::rustc-cfg=my_component="foo"`. The key should be a Rust identifier, the value should be a string. +**Recommended:** Use [`build_rs::output::rustc_cfg`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_cfg.html) from the `build-rs` crate. + [cargo features]: features.md [conditional compilation]: ../../reference/conditional-compilation.md [option-cfg]: ../../rustc/command-line-arguments.md#option-cfg @@ -287,9 +321,12 @@ The instruction can be used like this: ```rust,no_run // build.rs -println!("cargo::rustc-check-cfg=cfg(foo, values(\"bar\"))"); +build_rs::output::rustc_check_cfg_values( + "foo", + &["bar"], +); if foo_bar_condition { - println!("cargo::rustc-cfg=foo=\"bar\""); + build_rs::output::rustc_cfg_value("foo", "bar"); } ``` @@ -303,6 +340,8 @@ avoid typos, missing check-cfg, stale cfgs... See also the [conditional compilation][conditional-compilation-example] example. +**Recommended:** Use [`build_rs::output::rustc_check_cfgs`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_check_cfgs.html) from the `build-rs` crate. + > **MSRV:** Respected as of 1.80 [checking-conditional-configurations]: ../../rustc/check-cfg.html @@ -326,6 +365,8 @@ Cargo][env-cargo]. > Normally, these environment variables should only be checked at compile-time > with the `env!` macro. +**Recommended:** Use [`build_rs::output::rustc_env`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.rustc_env.html) from the `build-rs` crate. + [env-macro]: ../../std/macro.env.html [env-cargo]: environment-variables.md#environment-variables-cargo-sets-for-crates @@ -340,6 +381,9 @@ has finished running, and then fail the build. > The caller can then decide whether or not to display the `Err` variant > using `cargo::error`. + +**Recommended:** Use [`build_rs::output::error`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.error.html) from the `build-rs` crate. + > **MSRV:** Respected as of 1.84 ### `cargo::warning=MESSAGE` {#cargo-warning} @@ -351,6 +395,8 @@ out in [crates.io] crates are not emitted by default, unless the build fails. The `-vv` "very verbose" flag may be used to have Cargo display warnings for all crates. +**Recommended:** Use [`build_rs::output::warning`](https://docs.rs/build-rs/0.3.3/build_rs/output/fn.warning.html) from the `build-rs` crate. + ## Build Dependencies Build scripts are also allowed to have dependencies on other Cargo-based crates. @@ -407,6 +453,8 @@ automatically handles whether or not the script itself needs to be recompiled, and of course the script will be re-run after it has been recompiled. Otherwise, specifying `build.rs` is redundant and unnecessary. +**Recommended**: Use `build_rs::rerun_if_changed` to emit this instruction safely. The behavior is similar to `cargo::rerun-if-changed`. + ### `cargo::rerun-if-env-changed=NAME` {#rerun-if-env-changed} The `rerun-if-env-changed` instruction tells Cargo to re-run the build script @@ -423,6 +471,8 @@ source code will automatically detect changes and trigger rebuilds. `rerun-if-env-changed` is no longer needed for variables already referenced by these macros. +**Recommended**: Use `build_rs::output::rerun_if_env_changed` to monitor environment variables. Its behavior similar to that of `cargo::rerun-if-env-changed`. + [option-env-macro]: ../../std/macro.option_env.html ## The `links` Manifest Key @@ -548,4 +598,5 @@ at the same time. [`cc` crate]: https://crates.io/crates/cc [`jobserver` crate]: https://crates.io/crates/jobserver [jobserver protocol]: http://make.mad-scientist.net/papers/jobserver-implementation/ +[`build-rs` crate]: https://crates.io/crates/build-rs [crates.io]: https://crates.io/