architect 0.0.0

A cargo interface for build scripts
Documentation
//! <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts>
//!
//! Cargo sets several environment variables when build scripts are run.

use std::env;
use std::ffi::OsString;

macro_rules! decl_var_os {
	($($(#[$meta:meta])* $env:ident)*) => {
		$(paste::paste! {
			$(#[$meta])*
			pub fn [<$env:lower _os>]() -> Option<OsString> {
				env::var_os(stringify!($env))
			}
		})*
	};
}

decl_var_os! {
	/// Path to the `cargo` binary performing the build.
	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
	/// The path to the manifest of your package.
	CARGO_MANIFEST_PATH
	/// The manifest `links` value.
	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`.
	///
	/// [jobserver]: https://www.gnu.org/software/make/manual/html_node/Job-Slots.html
	CARGO_MAKEFLAGS

	/// The folder in which all output and intermediate artifacts 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
	/// 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
	/// The host triple of the Rust compiler.
	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
	/// Values of the corresponding variables for the profile currently being built.
	OPT_LEVEL
	/// Values of the corresponding variables for the profile currently being built.
	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.
	///
	/// [profile]: https://doc.rust-lang.org/cargo/reference/profiles.html
	/// [dev]: https://doc.rust-lang.org/cargo/reference/profiles.html#dev
	/// [release]: https://doc.rust-lang.org/cargo/reference/profiles.html#release
	PROFILE

	/// The compiler and documentation generator that Cargo has resolved to use, passed to the build script so it might use it as well.
	RUSTC
	/// The compiler and documentation generator that Cargo has resolved to use, passed to the build script so it might use it as well.
	RUSTDOC
	/// The `rustc` wrapper, if any, that Cargo is using. See [build.rustc-wrapper].
	///
	/// [build.rustc-wrapper]: https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper
	RUSTC_WRAPPER
	/// The `rustc` wrapper, if any, that Cargo is using for workspace members. See [build.rustc-workspace-wrapper].
	///
	/// [build.rustc-workspace-wrapper]: https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-workspace-wrapper
	RUSTC_WORKSPACE_WRAPPER
	/// The path to the linker binary that Cargo has resolved to use for the current target, if specified. The linker can be changed by editing `.cargo/config.toml`; see the documentation about [cargo configuration] for more information.
	///
	/// [cargo configuration]: https://doc.rust-lang.org/cargo/reference/config.html
	RUSTC_LINKER
	/// Extra flags that Cargo invokes `rustc` with, separated by a `0x1f` character (ASCII Unit Separator). 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
	CARGO_ENCODED_RUSTFLAGS

	/// Each activated feature of the package being built.
	CARGO_CFG_FEATURE
	/// Set on [unix-like platforms].
	///
	/// [unix-like platforms]: https://doc.rust-lang.org/reference/conditional-compilation.html#unix-and-windows
	CARGO_CFG_UNIX
	/// Set on [windows-like platforms].
	///
	/// [windows-like platforms]: https://doc.rust-lang.org/reference/conditional-compilation.html#unix-and-windows
	CARGO_CFG_WINDOWS
	/// The [target family].
	///
	/// [target family]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_family
	CARGO_CFG_TARGET_FAMILY
	/// The [target operating system].
	///
	/// [target operating system]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
	CARGO_CFG_TARGET_OS
	/// The CPU [target architecture].
	///
	/// [target architecture]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
	CARGO_CFG_TARGET_ARCH
	/// The [target vendor].
	///
	/// [target vendor]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor
	CARGO_CFG_TARGET_VENDOR
	/// The [target environment] ABI.
	///
	/// [target environment]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_env
	CARGO_CFG_TARGET_ENV
	/// The [target ABI].
	///
	/// [target ABI]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_abi
	CARGO_CFG_TARGET_ABI
	/// The CPU [pointer width].
	///
	/// [pointer width]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_pointer_width
	CARGO_CFG_TARGET_POINTER_WIDTH
	/// The CPU [target endianness].
	///
	/// [target endianness]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_endian
	CARGO_CFG_TARGET_ENDIAN
	/// List of CPU [target features] enabled.
	///
	/// [target features]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature
	CARGO_CFG_TARGET_FEATURE

	/// The full version of your package.
	CARGO_PKG_VERSION
	/// The major version of your package.
	CARGO_PKG_VERSION_MAJOR
	/// The minor version of your package.
	CARGO_PKG_VERSION_MINOR
	/// The patch version of your package.
	CARGO_PKG_VERSION_PATCH
	/// The pre-release version of your package.
	CARGO_PKG_VERSION_PRE
	/// Colon separated list of authors from the manifest of your package.
	CARGO_PKG_AUTHORS
	/// The name of your package.
	CARGO_PKG_NAME
	/// The description from the manifest of your package.
	CARGO_PKG_DESCRIPTION
	/// The home page from the manifest of your package.
	CARGO_PKG_HOMEPAGE
	/// The repository from the manifest of your package.
	CARGO_PKG_REPOSITORY
	/// The license from the manifest of your package.
	CARGO_PKG_LICENSE
	/// The license file from the manifest of your package.
	CARGO_PKG_LICENSE_FILE
	/// The Rust version from the manifest of your package. Note that this is the minimum Rust version supported by the package, not the current Rust version.
	CARGO_PKG_RUST_VERSION
	/// Path to the README file of your package.
	CARGO_PKG_README
}

/// For each activated feature of the package being built, this environment
/// variable will be present where `<name>` is the name of the feature
/// uppercased and having `-` translated to `_`.
pub fn cargo_feature(name: &str) -> bool {
	env::var_os(format!(
		"CARGO_FEATURE_{}",
		name.to_uppercase().replace('-', "_")
	))
	.is_some()
}

/// For each activated feature of the package being built, this environment
/// variable will be present where `<name>` is the name of the feature
/// uppercased and having `-` translated to `_`.
pub fn cargo_features() -> Vec<String> {
	env::vars_os()
		.filter_map(|(var, _)| {
			var.into_string()
				.ok()?
				.strip_prefix("CARGO_FEATURE_")
				.map(ToOwned::to_owned)
		})
		.collect()
}

/// For each [configuration option] of the package being built, this environment
/// variable will contain the value of the configuration, where `<cfg>` is the
/// name of the configuration uppercased and having `-` translated to `_`.
/// Boolean configurations are present if they are set, and not present
/// otherwise. Configurations with multiple values are joined to a single
/// variable with the values delimited by `,`. 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`). Some examples of what these variables are:
///
/// [configuration option]: https://doc.rust-lang.org/reference/conditional-compilation.html
pub fn cargo_cfg_os(cfg: &str) -> Option<OsString> {
	env::var_os(format!(
		"CARGO_CFG_{}",
		cfg.to_uppercase().replace('-', "_")
	))
}

/// For each [configuration option] of the package being built, this environment
/// variable will contain the value of the configuration, where `<cfg>` is the
/// name of the configuration uppercased and having `-` translated to `_`.
/// Boolean configurations are present if they are set, and not present
/// otherwise. Configurations with multiple values are joined to a single
/// variable with the values delimited by `,`. 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`). Some examples of what these variables are:
///
/// [configuration option]: https://doc.rust-lang.org/reference/conditional-compilation.html
pub fn cargo_cfgs_os() -> Vec<(String, OsString)> {
	env::vars_os()
		.filter_map(|(var, value)| {
			var.into_string()
				.ok()?
				.strip_prefix("CARGO_CFG_")
				.map(|k| (k.to_owned(), value))
		})
		.collect()
}

/// For more information about this set of environment variables, see build
/// script documentation about [links].
///
/// [links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key
pub fn cargo_dep_os(name: &str, key: &str) -> Option<OsString> {
	env::var_os(format!(
		"DEP_{}_{}",
		name.to_uppercase().replace('-', "_"),
		key.to_uppercase().replace('-', "_")
	))
}

/// For more information about this set of environment variables, see build
/// script documentation about [links].
///
/// [links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key
pub fn cargo_deps_os() -> Vec<(String, String, OsString)> {
	env::vars_os()
		.filter_map(|(var, value)| {
			var.into_string()
				.ok()?
				.strip_prefix("DEP_")
				.and_then(|s| s.split_once('_'))
				.map(|(d, k)| (d.to_owned(), k.to_owned(), value))
		})
		.collect()
}