Skip to main content

build_instructions/
rustc.rs

1use std::{
2    convert::Infallible,
3    fmt::{Display, Formatter},
4    path::Path,
5};
6
7/// Represents the different kinds of link search paths used by the Rust compiler.
8pub enum LinkSearchKind {
9    /// Only search for transitive dependencies in this directory
10    Dependency,
11    /// Only search for this crate's direct dependencies in this directory
12    Crate,
13    /// Only search for native libraries in this directory
14    Native,
15    /// Only search for macOS frameworks in this directory
16    Framework,
17    /// Search for all library kinds in this directory, except frameworks.
18    /// This is the default if `kind` is not specified
19    All,
20}
21
22impl Display for LinkSearchKind {
23    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
24        let s = match self {
25            LinkSearchKind::Dependency => "dependency",
26            LinkSearchKind::Crate => "crate",
27            LinkSearchKind::Native => "native",
28            LinkSearchKind::Framework => "framework",
29            LinkSearchKind::All => "all",
30        };
31
32        write!(f, "{s}")
33    }
34}
35
36/// Provides utilities for interacting with the Rust compiler through Cargo build instructions.
37pub struct Rustc(Infallible);
38
39impl Rustc {
40    /// Passes a single linker argument to the Rust compiler.
41    pub fn link_arg(flag: impl AsRef<str>) {
42        let flag = flag.as_ref();
43        println!("cargo::rustc-link-arg={flag}");
44    }
45
46    /// Passes a linker argument for a specific binary target.
47    pub fn link_arg_bin(bin: impl AsRef<str>, flag: impl AsRef<str>) {
48        let bin = bin.as_ref();
49        let flag = flag.as_ref();
50        println!("cargo::rustc-link-arg-bin={bin}={flag}");
51    }
52
53    /// Passes a linker argument for all binary targets.
54    pub fn link_arg_bins(flag: impl AsRef<str>) {
55        let flag = flag.as_ref();
56        println!("cargo::rustc-link-arg-bins={flag}");
57    }
58
59    /// Links a library with the specified name.
60    pub fn link_lib(lib: impl AsRef<str>) {
61        let lib = lib.as_ref();
62        println!("cargo::rustc-link-lib={lib}");
63    }
64
65    /// Passes a linker argument specifically for test builds.
66    pub fn link_arg_tests(flag: impl AsRef<str>) {
67        let flag = flag.as_ref();
68        println!("cargo::rustc-link-arg-tests={flag}");
69    }
70
71    /// Passes a linker argument specifically for example builds.
72    pub fn link_arg_examples(flag: impl AsRef<str>) {
73        let flag = flag.as_ref();
74        println!("cargo::rustc-link-arg-examples={flag}");
75    }
76
77    /// Specifies a directory for the Rust compiler to search for libraries.
78    pub fn link_search(path: impl AsRef<Path>, kind: impl Into<Option<LinkSearchKind>>) {
79        let path = path.as_ref().display();
80        let kind = kind.into();
81
82        match kind {
83            Some(kind) => println!("cargo::rustc-link-search={kind}={path}"),
84            None => println!("carg::rustc-link-search={path}"),
85        }
86    }
87
88    /// Passes additional compiler flags to Rust compiler.
89    pub fn flags(flags: impl AsRef<str>) {
90        let flags = flags.as_ref();
91        println!("cargo::rustc-flags={flags}");
92    }
93
94    /// Configures a conditional compilation flag with an optional value.
95    pub fn cfg<'a>(key: impl AsRef<str>, value: impl Into<Option<&'a str>>) {
96        let key = key.as_ref();
97        let value = value.into();
98
99        match value {
100            Some(value) => println!("cargo::rustc-cfg={key}=\"{value}\""),
101            None => println!("cargo::rustc-cfg={key}"),
102        }
103    }
104
105    /// Checks the validity of a conditional compilation flag.
106    pub fn check_cfg(cfg: impl AsRef<str>) {
107        let cfg = cfg.as_ref();
108        println!("cargo::rustc-check-cfg={cfg}");
109    }
110
111    /// Sets an environment variable for the build script.
112    pub fn env(var: impl AsRef<str>, value: impl AsRef<str>) {
113        let var = var.as_ref();
114        let value = value.as_ref();
115        println!("cargo::rustc-env={var}={value}");
116    }
117
118    /// Passes a linker argument specifically for `cdylib` builds.
119    pub fn cdylib_link_arg(flag: impl AsRef<str>) {
120        let flag = flag.as_ref();
121        println!("cargo::rustc-cdylib-link-arg={flag}");
122    }
123}