1 // Copyright 2023 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /// The `chromium::import!{}` macro for importing crates from GN paths. 6 /// 7 /// This macro is used to access first-party crates in the Chromium project 8 /// (or other projects using Chromium's //build system) through the GN path 9 /// to the crate. All GN paths must be absolute paths. 10 /// 11 /// Third-party crates are accessed as usual by their name, which is available 12 /// whenever the Rust target depends on the third-party crate. The `import!` 13 /// macro does nothing, and will cause a compilation error if an attempt is 14 /// made to import a third-party crate with it. 15 /// 16 /// # Motivation 17 /// 18 /// Since first-party crates do not all have globally unique GN names, using 19 /// their GN target name as their crate name leads to ambiguity when multiple 20 /// crates with the same name are dependencies of the same crate. As such, we 21 /// produce mangled crate names that are unique, and depend on their full GN 22 /// path, but these names are not easy to spell. 23 /// 24 /// # Usage 25 /// 26 /// The `chromium` crate is automatically present in all first-party Rust 27 /// targets, which makes the `chromium::import!{}` macro available. The macro 28 /// should be given a list of GN paths (directory and target name) as quoted 29 /// strings to be imported into the current module, delineated with semicolons. 30 /// 31 /// When no target name is specified (e.g. `:name`) at the end of the GN path, 32 /// the target will be the same as the last directory name. This is the same 33 /// behaviour as within the GN `deps` list. 34 /// 35 /// The imported crates can be renamed by using the `as` keyword and reexported 36 /// using the `pub` keyword. These function in the same way as they do when 37 /// naming or reexporting with `use`, but the `import!` macro replaces the `use` 38 /// keyword for these purposes with first-party crates. 39 /// 40 /// # Examples 41 /// 42 /// ## Basic usage 43 /// Basic usage, importing a few targets. The name given to the imported crates 44 /// is their GN target name by default. In this example, there would be two 45 /// crates available in the Rust module below: `example` which is the 46 /// `example` GN target in `rust/example/BUILD.gn` and `other` which is the 47 /// `other` GN target in `rust/example/BUILD.gn`. 48 /// ``` 49 /// chromium::import! { 50 /// "//rust/example"; 51 /// "//rust/example:other"; 52 /// } 53 /// 54 /// use example::Goat; 55 /// 56 /// example::foo(Goat::new()); 57 /// other::foo(Goat::with_age(3)); 58 /// ``` 59 /// 60 /// ## Renaming an import 61 /// Since multiple GN targets may have the same local name, they can be given 62 /// a different name when imported by using `as`: 63 /// ``` 64 /// chromium::import! { 65 /// "//rust/example" as renamed; 66 /// "//rust/example:other" as very_renamed; 67 /// } 68 /// 69 /// use renamed::Goat; 70 /// 71 /// renamed::foo(Goat::new()); 72 /// very_renamed::foo(Goat::with_age(3)); 73 /// ``` 74 /// 75 /// ## Re-exporting 76 /// When importing and re-exporting a dependency, the usual syntax would be 77 /// `pub use my_dependency;`. For first-party crates, this must be done through 78 /// the `import!` macro by prepending the `pub` keyword where the crate is 79 /// imported. The exported name can be specified with `as`: 80 /// ``` 81 /// mod module { 82 /// 83 /// chromium::import! { 84 /// pub "//rust/example"; 85 /// pub "//rust/example:other" as exported_other; 86 /// } 87 /// 88 /// } 89 /// 90 /// use module::example::Goat; 91 /// 92 /// module::example::foo(Goat::new()) 93 /// module::exported_other::foo(Goat::with_age(3)); 94 /// ``` 95 pub use import_attribute::import; 96