| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 1 | use std::fmt::{self, Debug}; |
| 2 | use std::marker::PhantomData; |
| David Tolnay | bd54b6f | 2020-11-04 22:49:41 -0800 | [diff] [blame] | 3 | use std::path::Path; |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 4 | |
| David Tolnay | 983ccf8 | 2020-10-08 17:03:35 -0700 | [diff] [blame] | 5 | /// Build configuration. See [CFG]. |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 6 | pub struct Cfg<'a> { |
| David Tolnay | 0b1a6b3 | 2020-11-05 17:31:06 -0800 | [diff] [blame] | 7 | /// See [`CFG.include_prefix`][CFG#cfginclude_prefix]. |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 8 | pub include_prefix: &'a str, |
| David Tolnay | 0b1a6b3 | 2020-11-05 17:31:06 -0800 | [diff] [blame] | 9 | /// See [`CFG.exported_header_dirs`][CFG#cfgexported_header_dirs]. |
| David Tolnay | bd54b6f | 2020-11-04 22:49:41 -0800 | [diff] [blame] | 10 | pub exported_header_dirs: Vec<&'a Path>, |
| David Tolnay | 0b1a6b3 | 2020-11-05 17:31:06 -0800 | [diff] [blame] | 11 | /// See [`CFG.exported_header_prefixes`][CFG#cfgexported_header_prefixes]. |
| David Tolnay | bd54b6f | 2020-11-04 22:49:41 -0800 | [diff] [blame] | 12 | pub exported_header_prefixes: Vec<&'a str>, |
| David Tolnay | 0b1a6b3 | 2020-11-05 17:31:06 -0800 | [diff] [blame] | 13 | /// See [`CFG.exported_header_links`][CFG#cfgexported_header_links]. |
| David Tolnay | bd54b6f | 2020-11-04 22:49:41 -0800 | [diff] [blame] | 14 | pub exported_header_links: Vec<&'a str>, |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 15 | marker: PhantomData<*const ()>, // !Send + !Sync |
| 16 | } |
| 17 | |
| David Tolnay | 983ccf8 | 2020-10-08 17:03:35 -0700 | [diff] [blame] | 18 | /// Global configuration of the current build. |
| 19 | /// |
| 20 | /// <br> |
| 21 | /// |
| David Tolnay | cac5a83 | 2020-11-05 20:00:03 -0800 | [diff] [blame] | 22 | /// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>&str</strong></div> |
| 23 | /// |
| David Tolnay | 983ccf8 | 2020-10-08 17:03:35 -0700 | [diff] [blame] | 24 | /// ## **`CFG.include_prefix`** |
| 25 | /// |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 26 | /// The prefix at which C++ code from your crate as well as directly dependent |
| 27 | /// crates can access the code generated during this build. |
| David Tolnay | 983ccf8 | 2020-10-08 17:03:35 -0700 | [diff] [blame] | 28 | /// |
| 29 | /// By default, the `include_prefix` is equal to the name of the current crate. |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 30 | /// That means if your crate is called `demo` and has Rust source files in a |
| David Tolnay | 983ccf8 | 2020-10-08 17:03:35 -0700 | [diff] [blame] | 31 | /// *src/* directory and maybe some handwritten C++ header files in an |
| 32 | /// *include/* directory, then the current crate as well as downstream crates |
| 33 | /// might include them as follows: |
| 34 | /// |
| 35 | /// ``` |
| 36 | /// # const _: &str = stringify! { |
| 37 | /// // include one of the handwritten headers: |
| 38 | /// #include "demo/include/wow.h" |
| 39 | /// |
| 40 | /// // include a header generated from Rust cxx::bridge: |
| 41 | /// #include "demo/src/lib.rs.h" |
| 42 | /// # }; |
| 43 | /// ``` |
| 44 | /// |
| 45 | /// By modifying `CFG.include_prefix` we can substitute a prefix that is |
| 46 | /// different from the crate name if desired. Here we'll change it to |
| 47 | /// `"path/to"` which will make import paths take the form |
| 48 | /// `"path/to/include/wow.h"` and `"path/to/src/lib.rs.h"`. |
| 49 | /// |
| 50 | /// ```no_run |
| 51 | /// // build.rs |
| 52 | /// |
| 53 | /// use cxx_build::CFG; |
| 54 | /// |
| 55 | /// fn main() { |
| 56 | /// CFG.include_prefix = "path/to"; |
| 57 | /// |
| 58 | /// cxx_build::bridge("src/lib.rs") |
| 59 | /// .file("src/demo.cc") // probably contains `#include "path/to/src/lib.rs.h"` |
| 60 | /// /* ... */ |
| 61 | /// .compile("demo"); |
| 62 | /// } |
| 63 | /// ``` |
| 64 | /// |
| 65 | /// Note that cross-crate imports are only made available between **direct |
| 66 | /// dependencies**. Another crate must directly depend on your crate in order to |
| 67 | /// #include its headers; a transitive dependency is not sufficient. |
| 68 | /// Additionally, headers from a direct dependency are only importable if the |
| 69 | /// dependency's Cargo.toml manifest contains a `links` key. If not, its headers |
| 70 | /// will not be importable from outside of the same crate. |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 71 | /// |
| 72 | /// <br> |
| 73 | /// |
| David Tolnay | cac5a83 | 2020-11-05 20:00:03 -0800 | [diff] [blame] | 74 | /// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec<&Path></strong></div> |
| 75 | /// |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 76 | /// ## **`CFG.exported_header_dirs`** |
| 77 | /// |
| 78 | /// A vector of absolute paths. The current crate, directly dependent crates, |
| 79 | /// and further crates to which this crate's headers are exported (see below) |
| 80 | /// will be able to `#include` headers from these directories. |
| 81 | /// |
| 82 | /// Adding a directory to `exported_header_dirs` is similar to adding it to the |
| 83 | /// current build via the `cc` crate's [`Build::include`][cc::Build::include], |
| 84 | /// but *also* makes the directory available to downstream crates that want to |
| 85 | /// `#include` one of the headers from your crate. If the dir were added only |
| 86 | /// using `Build::include`, the downstream crate including your header would |
| 87 | /// need to manually add the same directory to their own build as well. |
| 88 | /// |
| 89 | /// When using `exported_header_dirs`, your crate must also set a `links` key |
| 90 | /// for itself in Cargo.toml. See [*the `links` manifest key*][links]. The |
| 91 | /// reason is that Cargo imposes no ordering on the execution of build scripts |
| 92 | /// without a `links` key, which means the downstream crate's build script might |
| 93 | /// execute before yours decides what to put into `exported_header_dirs`. |
| 94 | /// |
| 95 | /// [links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key |
| 96 | /// |
| 97 | /// ### Example |
| 98 | /// |
| 99 | /// One of your crate's headers wants to include a system library, such as |
| 100 | /// `#include "Python.h"`. |
| 101 | /// |
| 102 | /// ```no_run |
| 103 | /// // build.rs |
| 104 | /// |
| 105 | /// use cxx_build::CFG; |
| 106 | /// use std::path::PathBuf; |
| 107 | /// |
| 108 | /// fn main() { |
| 109 | /// let python3 = pkg_config::probe_library("python3").unwrap(); |
| 110 | /// let python_include_paths = python3.include_paths.iter().map(PathBuf::as_path); |
| 111 | /// CFG.exported_header_dirs.extend(python_include_paths); |
| 112 | /// |
| 113 | /// cxx_build::bridge("src/bridge.rs").compile("demo"); |
| 114 | /// } |
| 115 | /// ``` |
| 116 | /// |
| 117 | /// ### Example |
| 118 | /// |
| 119 | /// Your crate wants to rearrange the headers that it exports vs how they're |
| 120 | /// laid out locally inside the crate's source directory. |
| 121 | /// |
| 122 | /// Suppose the crate as published contains a file at `./include/myheader.h` but |
| 123 | /// wants it available to downstream crates as `#include "foo/v1/public.h"`. |
| 124 | /// |
| 125 | /// ```no_run |
| 126 | /// // build.rs |
| 127 | /// |
| 128 | /// use cxx_build::CFG; |
| 129 | /// use std::path::Path; |
| 130 | /// use std::{env, fs}; |
| 131 | /// |
| 132 | /// fn main() { |
| 133 | /// let out_dir = env::var_os("OUT_DIR").unwrap(); |
| 134 | /// let headers = Path::new(&out_dir).join("headers"); |
| 135 | /// CFG.exported_header_dirs.push(&headers); |
| 136 | /// |
| 137 | /// // We contain `include/myheader.h` locally, but |
| 138 | /// // downstream will use `#include "foo/v1/public.h"` |
| 139 | /// let foo = headers.join("foo").join("v1"); |
| 140 | /// fs::create_dir_all(&foo).unwrap(); |
| 141 | /// fs::copy("include/myheader.h", foo.join("public.h")).unwrap(); |
| 142 | /// |
| 143 | /// cxx_build::bridge("src/bridge.rs").compile("demo"); |
| 144 | /// } |
| 145 | /// ``` |
| 146 | /// |
| David Tolnay | cac5a83 | 2020-11-05 20:00:03 -0800 | [diff] [blame] | 147 | /// <p style="margin:0"><br><br></p> |
| 148 | /// |
| 149 | /// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec<&str></strong></div> |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 150 | /// |
| 151 | /// ## **`CFG.exported_header_prefixes`** |
| 152 | /// |
| 153 | /// Vector of strings. These each refer to the `include_prefix` of one of your |
| 154 | /// direct dependencies, or a prefix thereof. They describe which of your |
| 155 | /// dependencies participate in your crate's C++ public API, as opposed to |
| 156 | /// private use by your crate's implementation. |
| 157 | /// |
| 158 | /// As a general rule, if one of your headers `#include`s something from one of |
| 159 | /// your dependencies, you need to put that dependency's `include_prefix` into |
| 160 | /// `CFG.exported_header_prefixes` (*or* their `links` key into |
| 161 | /// `CFG.exported_header_links`; see below). On the other hand if only your C++ |
| 162 | /// implementation files and *not* your headers are importing from the |
| 163 | /// dependency, you do not export that dependency. |
| 164 | /// |
| 165 | /// The significance of exported headers is that if downstream code (crate 𝒜) |
| 166 | /// contains an `#include` of a header from your crate (ℬ) and your header |
| 167 | /// contains an `#include` of something from your dependency (𝒞), the exported |
| 168 | /// dependency 𝒞 becomes available during the downstream crate 𝒜's build. |
| 169 | /// Otherwise the downstream crate 𝒜 doesn't know about 𝒞 and wouldn't be able |
| 170 | /// to find what header your header is referring to, and would fail to build. |
| 171 | /// |
| 172 | /// When using `exported_header_prefixes`, your crate must also set a `links` |
| 173 | /// key for itself in Cargo.toml. |
| 174 | /// |
| 175 | /// ### Example |
| 176 | /// |
| 177 | /// Suppose you have a crate with 5 direct dependencies and the `include_prefix` |
| 178 | /// for each one are: |
| 179 | /// |
| 180 | /// - "crate0" |
| 181 | /// - "group/api/crate1" |
| 182 | /// - "group/api/crate2" |
| 183 | /// - "group/api/contrib/crate3" |
| 184 | /// - "detail/crate4" |
| 185 | /// |
| 186 | /// Your header involves types from the first four so we re-export those as part |
| 187 | /// of your public API, while crate4 is only used internally by your cc file not |
| 188 | /// your header, so we do not export: |
| 189 | /// |
| 190 | /// ```no_run |
| 191 | /// // build.rs |
| 192 | /// |
| 193 | /// use cxx_build::CFG; |
| 194 | /// |
| 195 | /// fn main() { |
| 196 | /// CFG.exported_header_prefixes = vec!["crate0", "group/api"]; |
| 197 | /// |
| 198 | /// cxx_build::bridge("src/bridge.rs") |
| 199 | /// .file("src/impl.cc") |
| 200 | /// .compile("demo"); |
| 201 | /// } |
| 202 | /// ``` |
| 203 | /// |
| David Tolnay | cac5a83 | 2020-11-05 20:00:03 -0800 | [diff] [blame] | 204 | /// <p style="margin:0"><br><br></p> |
| 205 | /// |
| 206 | /// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec<&str></strong></div> |
| David Tolnay | 8249c83 | 2020-11-05 16:37:04 -0800 | [diff] [blame] | 207 | /// |
| 208 | /// ## **`CFG.exported_header_links`** |
| 209 | /// |
| 210 | /// Vector of strings. These each refer to the `links` attribute ([*the `links` |
| 211 | /// manifest key*][links]) of one of your crate's direct dependencies. |
| 212 | /// |
| 213 | /// This achieves an equivalent result to `CFG.exported_header_prefixes` by |
| 214 | /// re-exporting a dependency as part of your crate's public API, except with |
| 215 | /// finer grained control for cases when multiple crates might be sharing the |
| 216 | /// same `include_prefix` and you'd like to export some but not others. Links |
| 217 | /// attributes are guaranteed to be unique identifiers by Cargo. |
| 218 | /// |
| 219 | /// When using `exported_header_links`, your crate must also set a `links` key |
| 220 | /// for itself in Cargo.toml. |
| 221 | /// |
| 222 | /// ### Example |
| 223 | /// |
| 224 | /// ```no_run |
| 225 | /// // build.rs |
| 226 | /// |
| 227 | /// use cxx_build::CFG; |
| 228 | /// |
| 229 | /// fn main() { |
| 230 | /// CFG.exported_header_links.push("git2"); |
| 231 | /// |
| 232 | /// cxx_build::bridge("src/bridge.rs").compile("demo"); |
| 233 | /// } |
| 234 | /// ``` |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 235 | #[cfg(doc)] |
| 236 | pub static mut CFG: Cfg = Cfg { |
| 237 | include_prefix: "", |
| David Tolnay | bd54b6f | 2020-11-04 22:49:41 -0800 | [diff] [blame] | 238 | exported_header_dirs: Vec::new(), |
| 239 | exported_header_prefixes: Vec::new(), |
| 240 | exported_header_links: Vec::new(), |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 241 | marker: PhantomData, |
| 242 | }; |
| 243 | |
| 244 | impl<'a> Debug for Cfg<'a> { |
| 245 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
| David Tolnay | 5346b21 | 2020-11-05 16:42:30 -0800 | [diff] [blame] | 246 | let Self { |
| 247 | include_prefix, |
| 248 | exported_header_dirs, |
| 249 | exported_header_prefixes, |
| 250 | exported_header_links, |
| 251 | marker: _, |
| 252 | } = self; |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 253 | formatter |
| 254 | .debug_struct("Cfg") |
| David Tolnay | 5346b21 | 2020-11-05 16:42:30 -0800 | [diff] [blame] | 255 | .field("include_prefix", include_prefix) |
| 256 | .field("exported_header_dirs", exported_header_dirs) |
| 257 | .field("exported_header_prefixes", exported_header_prefixes) |
| 258 | .field("exported_header_links", exported_header_links) |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 259 | .finish() |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | #[cfg(not(doc))] |
| 264 | pub use self::r#impl::Cfg::CFG; |
| 265 | |
| 266 | #[cfg(not(doc))] |
| 267 | mod r#impl { |
| David Tolnay | 676196b | 2020-11-04 13:23:08 -0800 | [diff] [blame] | 268 | use crate::intern::{intern, InternedString}; |
| David Tolnay | e352c1e | 2020-12-31 16:41:05 -0800 | [diff] [blame^] | 269 | use crate::syntax::map::UnorderedMap as Map; |
| David Tolnay | 9520821 | 2020-11-04 23:06:10 -0800 | [diff] [blame] | 270 | use crate::vec::{self, InternedVec as _}; |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 271 | use lazy_static::lazy_static; |
| 272 | use std::cell::RefCell; |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 273 | use std::fmt::{self, Debug}; |
| 274 | use std::marker::PhantomData; |
| 275 | use std::ops::{Deref, DerefMut}; |
| 276 | use std::sync::{PoisonError, RwLock}; |
| 277 | |
| David Tolnay | 39e9f91 | 2020-11-04 23:03:29 -0800 | [diff] [blame] | 278 | struct CurrentCfg { |
| 279 | include_prefix: InternedString, |
| 280 | exported_header_dirs: Vec<InternedString>, |
| 281 | exported_header_prefixes: Vec<InternedString>, |
| 282 | exported_header_links: Vec<InternedString>, |
| 283 | } |
| 284 | |
| 285 | impl CurrentCfg { |
| 286 | fn default() -> Self { |
| 287 | let include_prefix = crate::env_os("CARGO_PKG_NAME") |
| David Tolnay | 676196b | 2020-11-04 13:23:08 -0800 | [diff] [blame] | 288 | .map(|pkg| intern(&pkg.to_string_lossy())) |
| David Tolnay | 39e9f91 | 2020-11-04 23:03:29 -0800 | [diff] [blame] | 289 | .unwrap_or_default(); |
| 290 | let exported_header_dirs = Vec::new(); |
| 291 | let exported_header_prefixes = Vec::new(); |
| 292 | let exported_header_links = Vec::new(); |
| 293 | CurrentCfg { |
| 294 | include_prefix, |
| 295 | exported_header_dirs, |
| 296 | exported_header_prefixes, |
| 297 | exported_header_links, |
| 298 | } |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | lazy_static! { |
| 303 | static ref CURRENT: RwLock<CurrentCfg> = RwLock::new(CurrentCfg::default()); |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | thread_local! { |
| David Tolnay | 0393202 | 2020-10-08 19:24:53 -0700 | [diff] [blame] | 307 | // FIXME: If https://github.com/rust-lang/rust/issues/77425 is resolved, |
| 308 | // we can delete this thread local side table and instead make each CFG |
| 309 | // instance directly own the associated super::Cfg. |
| 310 | // |
| 311 | // #[allow(const_item_mutation)] |
| 312 | // pub const CFG: Cfg = Cfg { |
| 313 | // cfg: AtomicPtr::new(ptr::null_mut()), |
| 314 | // }; |
| 315 | // pub struct Cfg { |
| 316 | // cfg: AtomicPtr<super::Cfg>, |
| 317 | // } |
| 318 | // |
| David Tolnay | e352c1e | 2020-12-31 16:41:05 -0800 | [diff] [blame^] | 319 | static CONST_DEREFS: RefCell<Map<Handle, Box<super::Cfg<'static>>>> = RefCell::default(); |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | #[derive(Eq, PartialEq, Hash)] |
| 323 | struct Handle(*const Cfg<'static>); |
| 324 | |
| 325 | impl<'a> Cfg<'a> { |
| 326 | fn current() -> super::Cfg<'a> { |
| David Tolnay | 39e9f91 | 2020-11-04 23:03:29 -0800 | [diff] [blame] | 327 | let current = CURRENT.read().unwrap_or_else(PoisonError::into_inner); |
| 328 | let include_prefix = current.include_prefix.str(); |
| David Tolnay | 9520821 | 2020-11-04 23:06:10 -0800 | [diff] [blame] | 329 | let exported_header_dirs = current.exported_header_dirs.vec(); |
| 330 | let exported_header_prefixes = current.exported_header_prefixes.vec(); |
| 331 | let exported_header_links = current.exported_header_links.vec(); |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 332 | super::Cfg { |
| 333 | include_prefix, |
| David Tolnay | 306f126 | 2020-11-04 22:54:48 -0800 | [diff] [blame] | 334 | exported_header_dirs, |
| 335 | exported_header_prefixes, |
| 336 | exported_header_links, |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 337 | marker: PhantomData, |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | const fn handle(self: &Cfg<'a>) -> Handle { |
| 342 | Handle(<*const Cfg>::cast(self)) |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | // Since super::Cfg is !Send and !Sync, all Cfg are thread local and will |
| 347 | // drop on the same thread where they were created. |
| 348 | pub enum Cfg<'a> { |
| 349 | Mut(super::Cfg<'a>), |
| 350 | CFG, |
| 351 | } |
| 352 | |
| 353 | impl<'a> Debug for Cfg<'a> { |
| 354 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
| 355 | if let Cfg::Mut(cfg) = self { |
| 356 | Debug::fmt(cfg, formatter) |
| 357 | } else { |
| 358 | Debug::fmt(&Cfg::current(), formatter) |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | impl<'a> Deref for Cfg<'a> { |
| 364 | type Target = super::Cfg<'a>; |
| 365 | |
| 366 | fn deref(&self) -> &Self::Target { |
| 367 | if let Cfg::Mut(cfg) = self { |
| 368 | cfg |
| 369 | } else { |
| 370 | let cfg = CONST_DEREFS.with(|derefs| -> *mut super::Cfg { |
| 371 | &mut **derefs |
| 372 | .borrow_mut() |
| 373 | .entry(self.handle()) |
| 374 | .or_insert_with(|| Box::new(Cfg::current())) |
| 375 | }); |
| 376 | unsafe { &mut *cfg } |
| 377 | } |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | impl<'a> DerefMut for Cfg<'a> { |
| 382 | fn deref_mut(&mut self) -> &mut Self::Target { |
| 383 | if let Cfg::CFG = self { |
| 384 | CONST_DEREFS.with(|derefs| derefs.borrow_mut().remove(&self.handle())); |
| 385 | *self = Cfg::Mut(Cfg::current()); |
| 386 | } |
| 387 | match self { |
| 388 | Cfg::Mut(cfg) => cfg, |
| 389 | Cfg::CFG => unreachable!(), |
| 390 | } |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | impl<'a> Drop for Cfg<'a> { |
| 395 | fn drop(&mut self) { |
| 396 | if let Cfg::Mut(cfg) = self { |
| David Tolnay | 39e9f91 | 2020-11-04 23:03:29 -0800 | [diff] [blame] | 397 | let mut current = CURRENT.write().unwrap_or_else(PoisonError::into_inner); |
| 398 | current.include_prefix = intern(cfg.include_prefix); |
| David Tolnay | 9520821 | 2020-11-04 23:06:10 -0800 | [diff] [blame] | 399 | current.exported_header_dirs = vec::intern(&cfg.exported_header_dirs); |
| 400 | current.exported_header_prefixes = vec::intern(&cfg.exported_header_prefixes); |
| 401 | current.exported_header_links = vec::intern(&cfg.exported_header_links); |
| David Tolnay | e5098cb | 2020-10-07 16:04:48 -0700 | [diff] [blame] | 402 | } else { |
| 403 | CONST_DEREFS.with(|derefs| derefs.borrow_mut().remove(&self.handle())); |
| 404 | } |
| 405 | } |
| 406 | } |
| 407 | } |