build-rs-0.1.2/.cargo_vcs_info.json0000644000000001360000000000100125550ustar { "git": { "sha1": "6655e485135d1c339864b4e4f4147cb60144ec48" }, "path_in_vcs": "" }build-rs-0.1.2/.github/workflows/publish.yml000064400000000000000000000007050072674642500171650ustar 00000000000000on: push: tags: - '*' jobs: publish: name: Publish runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install stable uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - name: Publish run: cargo publish env: CARGO_REGISTRY_TOKEN: ${{secrets.CRATES_IO_API_TOKEN}} build-rs-0.1.2/.gitignore000064400000000000000000000000240072674642500133610ustar 00000000000000/target /Cargo.lock build-rs-0.1.2/Cargo.toml0000644000000015570000000000100105630ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "build-rs" version = "0.1.2" description = "Convenience wrapper for cargo buildscript input/output" keywords = ["buildscript", "build-script", "cargo"] categories = ["development-tools::build-utils"] license = "MIT OR Apache-2.0 OR 0BSD OR CC0-1.0 OR CDDL-1.0 OR MIT-0 OR Unlicense OR WTFPL" repository = "https://github.com/cad97/build-rs" resolver = "2" [lib] name = "build" build-rs-0.1.2/Cargo.toml.orig000064400000000000000000000006140072674642500142650ustar 00000000000000[package] name = "build-rs" version = "0.1.2" edition = "2021" description = "Convenience wrapper for cargo buildscript input/output" repository = "https://github.com/cad97/build-rs" license = "MIT OR Apache-2.0 OR 0BSD OR CC0-1.0 OR CDDL-1.0 OR MIT-0 OR Unlicense OR WTFPL" keywords = ["buildscript","build-script","cargo"] categories = ["development-tools::build-utils"] [lib] name = "build" build-rs-0.1.2/README.md000064400000000000000000000052140072674642500126560ustar 00000000000000A convenience wrapper for cargo buildscript input/output. ## Why? The cargo buildscript API is (necessarily) stringly-typed. This crate helps you avoid typos, at least in the name of the instruction to cargo or environment variable that you're reading. Additionally, [potentially multi-valued variables][irlo] have a subtle footgun, in that when they're a single value, you might match on `target_family="unix"`, whereas `target_family="unix,wasm"` is also a valid variable, and would wrongly be excluded by the naive check. Using this crate forces you to be correct about multi-valued inputs. [irlo]: https://internals.rust-lang.org/t/futher-extensions-to-cfg-target-family-and-concerns-about-breakage/16313?u=cad97 ## License This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. If this is insufficient, you may also use this software under any of the following licenses: - [MIT License](https://spdx.org/licenses/MIT.html) - [Apache License 2.0](https://spdx.org/licenses/Apache-2.0.html) - [BSD Zero Clause License](https://spdx.org/licenses/0BSD.html) - [Creative Commons Zero v1.0 Universal](https://spdx.org/licenses/CC0-1.0.html) - [Common Development and Distribution License 1.0](https://spdx.org/licenses/CDDL-1.0.html) - [MIT No Attribution](https://spdx.org/licenses/MIT-0.html) - [The Unlicense](https://spdx.org/licenses/Unlicense.html) (the above text) - [Do What The F*ck You Want To Public License](https://spdx.org/licenses/WTFPL.html) and if for some reason that is insufficient, open a PR (and maybe ask your lawyer some questions about the other libraries you're using). build-rs-0.1.2/src/input.rs000064400000000000000000000325330072674642500136770ustar 00000000000000use std::{env, ffi::OsString, path::PathBuf}; macro_rules! export { () => {}; ($(#[$meta:meta])* $f:ident -> String = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> String { env::var_os(stringify!($var)) .expect(concat!("cargo buildscript env var $", stringify!($var), " not found")) .into_string() .expect(concat!("cargo buildscript env var $", stringify!($var), " contained invalid UTF-8")) } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> Option = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> Option { env::var_os(stringify!($var)).map(|it| it .into_string() .expect(concat!("cargo buildscript env var $", stringify!($var), " contained invalid UTF-8")) ) } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> usize = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> usize { env::var_os(stringify!($var)) .expect(concat!("cargo buildscript env var $", stringify!($var), " not found")) .into_string() .expect(concat!("cargo buildscript env var $", stringify!($var), " contained invalid UTF-8")) .parse() .expect(concat!("cargo buildscript env var $", stringify!($var), " did not parse as `usize`")) } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> Vec = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> Vec { env::var_os(stringify!($var)) .expect(concat!("cargo buildscript env var $", stringify!($var), " not found")) .into_string() .expect(concat!("cargo buildscript env var $", stringify!($var), " contained invalid UTF-8")) .split(',') .map(Into::into) .collect() } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> bool = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> bool { env::var_os(stringify!($var)) .is_some() } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> PathBuf = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> PathBuf { env::var_os(stringify!($var)) .expect(concat!("cargo buildscript env var $", stringify!($var), " not found")) .into() } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> Option = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> Option { env::var_os(stringify!($var)) .map(Into::into) } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> OsString = $var:ident $(; $($rest:tt)*)? ) => { $(#[$meta])* pub fn $f() -> OsString { env::var_os(stringify!($var)) .expect(concat!("cargo buildscript env var $", stringify!($var), " not found")) } $(export! { $($rest)* })? }; ($(#[$meta:meta])* $f:ident -> $out:ty = $var:ident $(; $($rest:tt)*)? ) => { compile_error!(concat!("Provided unknown output type ", stringify!($out), " to export!")); $(export! { $($rest)* })? }; } export! { /// Path to the `cargo` binary performing the build. cargo -> PathBuf = CARGO; /// The directory containing the manifest for the package being built (the /// package containing the build script). Also note that this is the value /// of the current working directory of the build script when it starts. cargo_manifest_dir -> PathBuf = CARGO_MANIFEST_DIR; /// The manifest links value. cargo_manifest_links -> String = CARGO_MANIFEST_LINKS; /// Contains parameters needed for Cargo's jobserver implementation to /// parallelize subprocesses. Rustc or cargo invocations from build.rs /// can already read CARGO_MAKEFLAGS, but GNU Make requires the flags /// to be specified either directly as arguments, or through the MAKEFLAGS /// environment variable. Currently Cargo doesn't set the MAKEFLAGS /// variable, but it's free for build scripts invoking GNU Make to set it /// to the contents of CARGO_MAKEFLAGS. cargo_makeflags -> OsString = CARGO_MAKEFLAGS; /// Set on [unix-like platforms](https://doc.rust-lang.org/reference/conditional-compilation.html#unix-and-windows). cargo_cfg_unix -> bool = CARGO_CFG_UNIX; /// Set on [windows-like platforms](https://doc.rust-lang.org/reference/conditional-compilation.html#unix-and-windows). cargo_cfg_windows -> bool = CARGO_CFG_WINDOWS; /// The [target family](https://doc.rust-lang.org/reference/conditional-compilation.html#target_family). cargo_cfg_target_family -> Vec = CARGO_CFG_TARGET_FAMILY; /// The [target operating system](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os). cargo_cfg_target_os -> String = CARGO_CFG_TARGET_OS; /// The CPU [target architecture](https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch). cargo_cfg_target_arch -> String = CARGO_CFG_TARGET_ARCH; /// The [target vendor](https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor). cargo_cfg_target_vendor -> String = CARGO_CFG_TARGET_VENDOR; /// The [target environment](https://doc.rust-lang.org/reference/conditional-compilation.html#target_env) ABI. cargo_cfg_target_env -> String = CARGO_CFG_TARGET_ENV; /// The CPU [pointer width](https://doc.rust-lang.org/reference/conditional-compilation.html#target_pointer_width). cargo_cfg_pointer_width -> usize = CARGO_CFG_TARGET_POINTER_WIDTH; /// Teh CPU [target endianness](https://doc.rust-lang.org/reference/conditional-compilation.html#target_endian). cargo_cfg_target_endian -> String = CARGO_CFG_TARGET_ENDIAN; /// List of CPU [target features](https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature) enabled. cargo_cfg_target_feature -> Vec = CARGO_CFG_TARGET_FEATURE; /// The folder in which all output should be placed. This folder is inside /// the build directory for the package being built, and it is unique for /// the package in question. out_dir -> PathBuf = OUT_DIR; /// The target triple that is being compiled for. Native code should be /// compiled for this triple. See the [Target Triple] description for /// more information. /// /// [Target Triple]: https://doc.rust-lang.org/cargo/appendix/glossary.html#target target -> String = TARGET; /// The host triple of the Rust compiler. host -> String = HOST; /// The parallelism specified as the top-level parallelism. This can be /// useful to pass a `-j` parameter to a system like `make`. Note that care /// should be taken when interpreting this environment variable. For /// historical purposes this is still provided but recent versions of /// Cargo, for example, do not need to run `make -j`, and instead can set /// the `MAKEFLAGS` env var to the content of `CARGO_MAKEFLAGS` to activate /// the use of Cargo's GNU Make compatible [jobserver] for sub-make /// invocations. /// /// [jobserver]: https://www.gnu.org/software/make/manual/html_node/Job-Slots.html num_jobs -> String = NUM_JOBS; /// Value of the corresponding variable for the profile currently being built. opt_level -> String = OPT_LEVEL; /// Value of the corresponding variable for the profile currently being built. debug -> String = DEBUG; /// `release` for release builds, `debug` for other builds. This is /// determined based on if the profile inherits from the [`dev`] or /// [`release`] profile. Using this environment variable is not /// recommended. Using other environment variables like `OPT_LEVEL` /// provide a more correct view of the actual settings being used. /// /// [`dev`]: https://doc.rust-lang.org/cargo/reference/profiles.html#dev /// [`release`]: https://doc.rust-lang.org/cargo/reference/profiles.html#release profile -> String = PROFILE; /// The compiler that Cargo has resolved to use, passed to the build script /// so it might use it as well. rustc -> PathBuf = RUSTC; /// The documentation generator that Cargo has resolved to use, passed to /// the build script so it might use it as well. rustdoc -> PathBuf = RUSTDOC; /// The `rustc` wrapper, if any, that Cargo is using. See /// [`build.rustc-wrapper`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper). rustc_wrapper -> Option = RUSTC_WRAPPER; /// The `rustc` wrapper, if any, that Cargo is using for workspace members. /// See [`build.rustc-workspace-wrapper`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-workspace-wrapper). rustc_workspace_wrapper -> Option = RUSTC_WORKSPACE_WRAPPER; /// The path to the linker binary that Cargo has resolved to use for the /// current target, if specified. rustc_linker -> Option = RUSTC_LINKER; /// The full version of your package. cargo_pkg_version -> String = CARGO_PKG_VERSION; /// The major version of your package. cargo_pkg_version_major -> usize = CARGO_PKG_VERSION_MAJOR; /// The minor version of your package. cargo_pkg_version_minor -> usize = CARGO_PKG_VERSION_MINOR; /// The patch version of your package. cargo_pkg_version_patch -> usize = CARGO_PKG_VERSION_PATCH; /// The pre-release of your package. cargo_pkg_version_pre -> String = CARGO_PKG_VERSION_PRE; /// The name of your package. cargo_pkg_name -> String = CARGO_PKG_NAME; /// The description from the manifest of your package. cargo_pkg_description -> String = CARGO_PKG_DESCRIPTION; /// The home page from the manifest of your package. cargo_pkg_homepage -> String = CARGO_PKG_HOMEPAGE; /// The repository from the manifest of your package. cargo_pkg_repository -> String = CARGO_PKG_REPOSITORY; /// The license from the manifest of your package. cargo_pkg_license -> String = CARGO_PKG_LICENSE; /// The license file from the manifest of your package. cargo_pkg_license_file -> String = CARGO_PKG_LICENSE_FILE; } /// For each activated feature of the package being built, this will be true. pub fn cargo_feature(name: &str) -> bool { let key = format!("CARGO_FEATURE_{}", name.to_uppercase().replace('-', "_")); env::var_os(key).is_some() } /// For each [configuration option] of the package being built, this will /// contain the value of the configuration. Boolean configurations are present /// if they are set, and not present otherwise. This includes values built-in /// to the compiler (which can be seen with `rustc --print=cfg`) and values set /// by build scripts and extra flags passed to `rustc` (such as those defined /// in `RUSTFLAGS`). /// /// [configuration option]: https://doc.rust-lang.org/reference/conditional-compilation.html pub fn cargo_cfg(cfg: &str) -> Option> { let key = format!("CARGO_CFG_{}", cfg.to_uppercase().replace('-', "_")); let val = env::var_os(&key)?.into_string().unwrap_or_else(|_| { panic!("cargo buildscript env var ${key} contained invalid UTF-8"); }); Some(val.split(',').map(Into::into).collect()) } /// Each build script can generate an arbitrary set of metadata in the form of /// key-value pairs. This metadata is passed to the build scripts of /// **dependent** packages. For example, if the package `bar` depends on `foo`, /// then if `foo` generates `key=value` as part of its build script metadata, /// then the build script of `bar` will have the environment variables /// `DEP_FOO_KEY=value`. pub fn dep(name: &str, key: &str) -> Option { let key = format!( "DEP_{}_{}", name.to_uppercase().replace('-', "_"), key.to_uppercase().replace('-', "_") ); let val = env::var_os(&key)?.into_string().unwrap_or_else(|_| { panic!("cargo buildscript env var ${key} contained invalid UTF-8"); }); Some(val) } /// Extra flags that Cargo invokes rustc with. See [`build.rustflags`]. Note /// that since Rust 1.55, `RUSTFLAGS` is removed from the environment; scripts /// should use `CARGO_ENCODED_RUSTFLAGS` instead. /// /// [`build.rustflags`]: https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags pub fn cargo_encoded_rustflags() -> Vec { let val = env::var_os("CARGO_ENCODED_RUSTFLAGS") .expect("cargo buildscript env var $CARGO_ENCODED_RUSTFLAGS") .into_string() .expect("cargo buildscript env var $CARGO_ENCODED_RUSTFLAGS contained invalid UTF-8"); val.split('\x1f').map(Into::into).collect() } /// List of authors from the manifest of your package. pub fn cargo_pkg_authors() -> Vec { let val = env::var_os("CARGO_PKG_AUTHORS") .expect("cargo buildscript env var $CARGO_PKG_AUTHORS") .into_string() .expect("cargo buildscript env var $CARGO_PKG_AUTHORS contained invalid UTF-8"); val.split(':').map(Into::into).collect() } build-rs-0.1.2/src/lib.rs000064400000000000000000000014070072674642500133020ustar 00000000000000//! Convenience wrappers for cargo buildscript input/output. //! //! # Example //! //! ```rust //! build::rerun_if_changed("build.rs"); // only rerun for buildscript changes //! build::rustc_cfg("has_buildrs"); // set #[cfg(has_buildrs)] //! dbg!(build::cargo()); // path to the cargo executable //! dbg!(build::cargo_manifest_dir()); // the directory of the build manifest //! ``` /// Inputs to the build script, in the form of environment variables. pub mod input; /// Outputs from the build script, in the form of `cargo:` printed lines. /// /// _Does not print a leading newline._ Thus, if you ever write to stdout and /// don't lock until a trailing newline, these instructions will likely fail. pub mod output; #[doc(no_inline)] pub use crate::{input::*, output::*}; build-rs-0.1.2/src/output.rs000064400000000000000000000212240072674642500140730ustar 00000000000000use std::{ffi::OsStr, path::Path}; /// The rustc-link-arg instruction tells Cargo to pass the /// [`-C link-arg=FLAG` option](https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg) /// to the compiler, but only when building supported targets (benchmarks, /// binaries, cdylib crates, examples, and tests). Its usage is highly platform /// specific. It is useful to set the shared library version or linker script. pub fn rustc_link_arg(flag: &str) { println!("cargo:rustc-link-arg={flag}"); } /// The `rustc-link-arg-bin` instruction tells Cargo to pass the /// [`-C link-arg=FLAG` option](https://doc.rust-lang.org/rustc/codegen-options/index.html#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. pub fn rustc_link_arg_bin(bin: &str, flag: &str) { println!("cargo:rustc-link-arg-bin={bin}={flag}"); } /// The `rustc-link-arg-bins` instruction tells Cargo to pass the /// [`-C link-arg=FLAG` option](https://doc.rust-lang.org/rustc/codegen-options/index.html#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. pub fn rustc_link_arg_bins(flag: &str) { println!("cargo:rustc-link-arg-bins={flag}"); } /// The `rustc-link-lib` instruction tells Cargo to link the given library /// using the compiler's [`-l` flag]. This is typically used to link a native /// library using [`FFI`]. /// /// The `-l` flag is only passed to the library target of the package, unless /// there is no library target, in which case it is passed to all targets. This /// is done because all other targets have an implicit dependency on the /// library target, and the given library to link should only be included once. /// This means that if a package has both a library and a binary target, the /// _library_ has access to the symbols from the given lib, and the binary /// should access them through the library target's public API. /// /// The optional `KIND` may be one of `dylib`, `static`, or `framework`. /// See the [rustc book] for more detail. /// /// [`-l` flag]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-link-lib /// [rustc book]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-link-lib pub fn rustc_link_lib(name: &str) { println!("cargo:rustc-link-lib={name}"); } /// See [`rustc_link_lib`]. pub fn rustc_link_lib_kind(kind: &str, name: &str) { println!("cargo:rustc-link-lib={kind}={name}"); } /// The `rustc-link-search` instruction tells Cargo to pass the [`-L flag`] to /// the compiler to add a directory to the library search path. /// /// The optional `KIND` may be one of `dependency`, `crate`, `native`, /// `framework`, or `all`. See the [rustc book] for more detail. /// /// These paths are also added to the /// [dynamic library search path environment variable] if they are within the /// `OUT_DIR`. Depending on this behavior is discouraged since this makes it /// 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). /// /// [`-L flag`]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-search-path /// [rustc book]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-search-path /// [dynamic library search path environment variable]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#dynamic-library-paths pub fn rustc_link_search(path: impl AsRef) { let path = path .as_ref() .as_os_str() .to_str() .expect("cannot print non-UTF8 path"); println!("cargo:rustc-link-search={path}"); } /// See [`rustc_link_search`]. pub fn rustc_link_search_kind(kind: &str, path: impl AsRef) { let path = path .as_ref() .as_os_str() .to_str() .expect("cannot print non-UTF8 path"); println!("cargo:rustc-link-search={kind}={path}"); } /// The `rustc-flags` instruction tells Cargo to pass the given space-separated /// flags to the compiler. This only allows the `-l` and `-L` flags, and is /// equivalent to using `rustc-link-lib` and `rustc-link-search`. pub fn rustc_flags(flags: &str) { println!("cargo:rustc-flags={flags}"); } /// The `rustc-cfg` instruction tells Cargo to pass the given value to the /// [`--cfg` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html#option-cfg) /// to the compiler. This may be used for compile-time detection of features to /// enable [conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html). /// /// Note that this does not affect Cargo's dependency resolution. This cannot /// be used to enable an optional dependency, or enable other Cargo features. /// /// Be aware that Cargo features use the form `feature="foo"`. `cfg` values /// passed with this flag are not restricted to that form, and may provide just /// a single identifier, or any arbitrary key/value pair. For example, emitting /// `cargo:rustc-cfg=abc` will then allow code to use `#[cfg(abc)]` (note the /// lack 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. pub fn rustc_cfg(key: &str) { println!("cargo:rustc-cfg={key}") } /// See [`rustc_cfg`]. pub fn rustc_cfg_value(key: &str, value: &str) { println!("cargo:rustc-cfg={key}={value}"); } /// The `rustc-env` instruction tells Cargo to set the given environment /// variable when compiling the package. The value can be then retrieved by the /// [`env! macro`](env!) 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. pub fn rustc_env(var: &str, value: &str) { println!("cargo:rustc-env={var}={value}"); } /// The `rustc-cdylib-link-arg` instruction tells Cargo to pass the /// [`-C link-arg=FLAG` option](https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg) /// to the compiler, but only when building a cdylib library target. Its usage /// is highly platform specific. It is useful to set the shared library version /// or the runtime-path. pub fn rustc_cdylib_link_arg(flag: &str) { println!("cargo:rustc-cdylib-link-arg={flag}"); } /// The `warning` instruction tells Cargo to display a warning after the build /// script has finished running. Warnings are only shown for path dependencies /// (that is, those you're working on locally), so for example warnings printed /// out in crates.io crates are not emitted by default. The `-vv` "very verbose" /// flag may be used to have Cargo display warnings for all crates. pub fn warning(message: &str) { println!("cargo:warning={message}"); } /// The `rerun-if-changed` instruction tells Cargo to re-run the build script /// if the file at the given path has changed. Currently, Cargo only uses the /// filesystem last-modified "mtime" timestamp to determine if the file has /// changed. It compares against an internal cached timestamp of when the build /// script last ran. /// /// If the path points to a directory, it will scan the entire directory for /// any modifications. /// /// If the build script inherently does not need to re-run under any /// circumstance, then emitting `cargo:rerun-if-changed=build.rs` is a simple /// way to prevent it from being re-run (otherwise, the default if no /// `rerun-if` instructions are emitted is to scan the entire package /// directory for changes). Cargo 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. pub fn rerun_if_changed(path: impl AsRef) { let path = path .as_ref() .as_os_str() .to_str() .expect("cannot print non-UTF8 path"); println!("cargo:rerun-if-changed={path}"); } /// The `rerun-if-env-changed` instruction tells Cargo to re-run the build /// script if the value of an environment variable of the given name has /// changed. /// /// Note that the environment variables here are intended for global /// environment variables like `CC` and such, it is not necessary to use this /// for environment variables like `TARGET` that Cargo sets. pub fn rerun_if_env_changed(name: impl AsRef) { let name = name .as_ref() .to_str() .expect("cannot print non-UTF8 env key"); println!("cargo:rerun-if-env-changed={name}"); }