-
Notifications
You must be signed in to change notification settings - Fork 2.9k
doc: Update build script examples to use build-rs #16592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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]. | ||||||
hksama marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| ## 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" | ||||||
hksama marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this being in the docs, how are we going to keep it up-to-date? |
||||||
| ``` | ||||||
|
|
||||||
| 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"); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A couple lines above |
||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
|
|
@@ -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" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| 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); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
| 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" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ``` | ||||||
|
|
||||||
| 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"); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we use |
||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
|
|
@@ -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",]); | ||||||
|
Comment on lines
+477
to
+478
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please clean up the code style |
||||||
|
|
||||||
| 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/ | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,14 +15,25 @@ 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment doesn't quite read correctly to me |
||
| 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") | ||
| .compile("hello"); | ||
| } | ||
| ``` | ||
|
|
||
| > **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. | ||
|
Comment on lines
+27
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is partly covered under " Life Cycle of a Build Script". Seems like adding a note about |
||
|
|
||
|
|
||
| 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,38 +183,50 @@ 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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need to recommend this under every entry |
||
|
|
||
| ### `cargo::rustc-link-arg-bin=BIN=FLAG` {#rustc-link-arg-bin} | ||
|
|
||
| The `rustc-link-arg-bin` instruction tells Cargo to pass the [`-C | ||
| 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 | ||
| 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/ | ||
Uh oh!
There was an error while loading. Please reload this page.