#macro #config-macro #link #no-alloc #config

no-std build cargo-build

Wrapper around cargo instructions accesible in build.rs with better type safety and support for modern features. Includes functions by default. Macros are optional, but do provide better experience when there is need to do formatting and variable number of arguments at the same time which is ideal for DSLs.

7 releases (1 stable)

1.0.0 Sep 23, 2025
0.7.3 Aug 30, 2025
0.1.1 Aug 29, 2025

#90 in Value formatting

Download history 4/week @ 2026-02-03 6/week @ 2026-02-17 18/week @ 2026-02-24 15/week @ 2026-03-03 20/week @ 2026-03-10 20/week @ 2026-03-17 33/week @ 2026-03-24 5/week @ 2026-03-31 9/week @ 2026-04-07

81 downloads per month

MIT license

130KB
2K SLoC

Cargo build

cargo-build is a wrapper around cargo instructions accesible in build.rs with better type safety and support for modern features.

Includes functions by default. Macros are optional, but do provide better experience when there is need to do formatting and variable number of arguments at the same time which is ideal for DSLs.

Add this crate as build-dependency

[build-dependencies]
cargo-build = "0.1.0" # no macros

[build-dependencies]
cargo-build = { version = "0.1.0", features = ["macros"] }

https://doc.rust-lang.org/cargo/reference/build-scripts.html

Those instructions are usually implemented by println!("cargo::") call. This crate provides easy to use wrapper-functions around those instructions.

Benefits:

  • Less code.
  • Easier to modify later.
  • Harder to make typos.

With cargo-build using functions:

cargo_build::rustc_link_arg_bin("server", "-Wl,--cref");

cargo_build::rustc_link_arg_bin("client", [
        "-mlongcalls",
        "-ffunction-sections",
        "-Wl,--cref",
]);

Without cargo-build:

println!("cargo::rustc-link-arg-bin=server=-Wl,--cref");
println!("cargo::rustc-link-arg-bin=client=-mlongcalls");
println!("cargo::rustc-link-arg-bin=client=-ffunction-sections");
println!("cargo::rustc-link-arg-bin=client=-Wl,--cref");

With cargo-build using functions:

cargo_build::rustc_check_cfgs("cuda");
cargo_build::rustc_cfg("cuda");

cargo_build::rustc_check_cfg("api_version", ["1", "2", "3"]);
cargo_build::rustc_cfg(("api_version", "1"));

Without cargo-build:

  • Note the inconsistancy of cfg
  • Note the need for escape sequences
println!("cargo::rustc-check-cfg=cfg(cuda)");
println!("cargo::rustc-cfg=cuda");

println!("cargo::rustc-check-cfg=cfg(api_version, values(\"1\", \"2\", \"3\"))");
println!("cargo::rustc-cfg=api_version-\"1\"");

Macros example (enable features = ["macros"] in Cargo.toml):

let env_var = "HOST";

if std::env::var(env_var).is_ok() {
    cargo_build::warning!("Warning during compilation: {} is not set", env_var);
    cargo_build::error!("Unable to finish compilation: {} is not set", env_var);
}

cargo_build::rustc_link_arg!(cdylib: "-mlongcalls"; "-ffunction-sections");

cargo_build::rustc_link_arg!(
    bin "client":
      "-mlongcalls";
      "-ffunction-sections";
      "-Wl,--cref";
      "stack-size={}", { 8 * 1024 * 1024 };
);

cargo_build::rustc_link_lib!(
    static: "+whole-archive", "+verbatim", "+bundle" =
      "nghttp2";
      "libssl";
      "libcrypto";
      "mylib:{}", "renamed_lib";
);

cargo_build::rustc_check_cfg!("api_version": "1", "2", "3");
cargo_build::rustc_cfg!("api_version" = "1");

Why use cargo-build when cargo emit already exists:

  • Support for modern features (such as error, rustc_check_cfg).
  • Support for 'keywords' (such as link-lib:KIND is not a string but defined set of values (static, dylib, framework)).
  • Better syntax overall (such as static: "lib1"; "lib2:{}", "renamed_lib2"; "lib3" in macros - no need to declare each lib static).
  • Extended examples and documentation for modern use cases.
  • Macros are feature - library works even without macros. Enable them by using features = ["macros"] in Cargo.toml

Note: The order of instructions in the build script may affect the order of arguments that cargo passes to rustc. In turn, the order of arguments passed to rustc may affect the order of arguments passed to the linker. Therefore, you will want to pay attention to the order of the build script’s instructions. For example, if object foo needs to link against library bar, you may want to make sure that library bar's rustc-link-lib instruction appears after instructions to link object foo.\

https://doc.rust-lang.org/cargo/reference/build-scripts.html

No runtime deps

Features