├── .buckconfig ├── .buckroot ├── .cargo └── config.toml ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .ignore ├── .taplo.toml ├── BUCK ├── BUCK_TREE ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── allocator ├── BUCK ├── allocator.rs └── std_alloc.rs ├── constraints ├── BUCK └── defs.bzl ├── crates.io ├── BUCK ├── crate_download.bzl └── rule.bzl ├── defs.bzl ├── fixups ├── ahash │ └── fixups.toml ├── basic-toml │ └── fixups.toml ├── blake3 │ └── fixups.toml ├── camino │ └── fixups.toml ├── clippy │ └── fixups.toml ├── clippy_config │ └── fixups.toml ├── clippy_lints │ └── fixups.toml ├── clippy_utils │ └── fixups.toml ├── compiler_builtins │ └── fixups.toml ├── core │ └── fixups.toml ├── crossbeam-utils │ └── fixups.toml ├── generic-array │ └── fixups.toml ├── getrandom │ └── fixups.toml ├── hashbrown │ └── fixups.toml ├── icu_list_data │ └── fixups.toml ├── icu_locid_transform_data │ └── fixups.toml ├── icu_normalizer_data │ └── fixups.toml ├── icu_properties_data │ └── fixups.toml ├── libc │ └── fixups.toml ├── lock_api │ └── fixups.toml ├── mime_guess │ └── fixups.toml ├── nix │ └── fixups.toml ├── object │ └── fixups.toml ├── panic_abort │ └── fixups.toml ├── parking_lot_core │ └── fixups.toml ├── proc-macro-hack │ └── fixups.toml ├── proc-macro2 │ └── fixups.toml ├── profiler_builtins │ └── fixups.toml ├── psm │ └── fixups.toml ├── pulldown-cmark │ └── fixups.toml ├── rustc-main │ └── fixups.toml ├── rustc_apfloat │ └── fixups.toml ├── rustc_codegen_llvm │ └── fixups.toml ├── rustc_errors │ └── fixups.toml ├── rustc_interface │ └── fixups.toml ├── rustc_llvm │ ├── BUCK │ ├── defs.bzl │ └── fixups.toml ├── rustc_log │ ├── fixups.toml │ └── overlay │ │ └── src │ │ └── lib.rs ├── rustc_macros │ └── fixups.toml ├── rustc_target │ └── fixups.toml ├── rustdoc-tool │ └── fixups.toml ├── rustdoc │ ├── fixups.toml │ └── overlay │ │ └── lib.rs ├── rustix │ └── fixups.toml ├── semver │ └── fixups.toml ├── serde │ └── fixups.toml ├── serde_json │ └── fixups.toml ├── stacker │ └── fixups.toml ├── std │ └── fixups.toml ├── thiserror │ └── fixups.toml ├── tracing │ └── fixups.toml ├── typenum │ └── fixups.toml ├── wasmparser │ └── fixups.toml ├── winapi-x86_64-pc-windows-gnu │ └── fixups.toml ├── winapi │ └── fixups.toml ├── windows_x86_64_gnu │ └── fixups.toml ├── windows_x86_64_msvc │ └── fixups.toml └── zerocopy │ └── fixups.toml ├── platforms ├── BUCK ├── cross │ └── BUCK ├── defs.bzl ├── exec │ └── BUCK ├── stage1 │ └── BUCK ├── stage2 │ └── BUCK └── windows │ └── BUCK ├── reindeer.toml ├── scripts ├── check.bxl └── download.bxl ├── stage0 ├── BUCK ├── defs.bzl ├── stage0_executable.py ├── stage0_overlay.py └── stage0_sysroot.py ├── stage1 ├── BUCK └── defs.bzl ├── stage2 └── BUCK ├── submodule_init.sh └── toolchains ├── BUCK ├── cxx.bzl ├── cxx └── BUCK ├── rust.bzl ├── rust ├── BUCK └── defs.bzl └── target ├── BUCK └── target_triple.bzl /.buckconfig: -------------------------------------------------------------------------------- 1 | [cells] 2 | rust = . 3 | prelude = prelude 4 | toolchains = toolchains 5 | none = none 6 | 7 | [external_cells] 8 | prelude = bundled 9 | 10 | [cell_aliases] 11 | config = prelude 12 | fbcode = none 13 | fbsource = none 14 | 15 | [project] 16 | ignore = .git, rust/build, rust/node_modules, rust/target 17 | 18 | [build] 19 | execution_platforms = rust//platforms:execution 20 | -------------------------------------------------------------------------------- /.buckroot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dtolnay/buck2-rustc-bootstrap/f86e674f3ce8c55e22328302fef1c1ee7c198d19/.buckroot -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [unstable] 2 | bindeps = true 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Buck2 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | schedule: [cron: "40 14 * * *"] 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | buck2: 13 | name: Buck2 on ${{matrix.os == 'ubuntu' && 'Linux' || matrix.os == 'macos' && 'macOS' || matrix.os == 'windows' && 'Windows' || '???'}} 14 | runs-on: ${{matrix.os}}-latest 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: 19 | - ubuntu 20 | - macos 21 | #- windows 22 | timeout-minutes: 90 23 | steps: 24 | - uses: actions/checkout@v4 25 | - uses: dtolnay/install-buck2@latest 26 | - run: git submodule update --init prelude 27 | - run: git submodule update --init rust 28 | - run: git submodule update --init library/backtrace 29 | working-directory: rust 30 | - run: git submodule update --init library/stdarch 31 | working-directory: rust 32 | - run: buck2 run stage2:rustc -- --version --verbose 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /buck-out/ 2 | /rustc-ice-* 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rust"] 2 | path = rust 3 | url = https://github.com/rust-lang/rust.git 4 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | /prelude/ 2 | /rust/ 3 | -------------------------------------------------------------------------------- /.taplo.toml: -------------------------------------------------------------------------------- 1 | exclude = [ 2 | "buck-out/**", 3 | "prelude/**", 4 | "rust/**", 5 | ] 6 | 7 | [formatting] 8 | align_comments = false 9 | array_auto_collapse = false 10 | array_auto_expand = false 11 | indent_string = " " 12 | 13 | [[rule]] 14 | include = ["**/Cargo.toml"] 15 | keys = [ 16 | "dependencies", 17 | "patch.crates-io", 18 | "target.*.dependencies", 19 | "workspace", 20 | ] 21 | [rule.formatting] 22 | reorder_arrays = true 23 | reorder_keys = true 24 | -------------------------------------------------------------------------------- /BUCK_TREE: -------------------------------------------------------------------------------- 1 | load("@prelude//cfg/modifier:cfg_constructor.bzl", "cfg_constructor_post_constraint_analysis", "cfg_constructor_pre_constraint_analysis") 2 | load("@prelude//cfg/modifier:common.bzl", "MODIFIER_METADATA_KEY") 3 | load("@prelude//cfg/modifier/set_cfg_modifiers.bzl", "set_cfg_modifiers") 4 | 5 | set_cfg_modifiers([]) 6 | 7 | set_cfg_constructor( 8 | aliases = struct( 9 | # Reindeer universe (//constraints:reindeer-universe) 10 | compiler = "//constraints:compiler", 11 | library = "//constraints:library", 12 | # Bootstrap stage (//constraints:bootstrap-stage) 13 | stage1 = "//constraints:stage1", 14 | stage2 = "//constraints:stage2", 15 | # Architecture (prelude//cpu/constraints:cpu) 16 | aarch64 = "prelude//cpu/constraints:arm64", 17 | x86_64 = "prelude//cpu/constraints:x86_64", 18 | # Operating system (prelude//os/constraints:os) 19 | linux = "prelude//os/constraints:linux", 20 | macos = "prelude//os/constraints:macos", 21 | windows = "prelude//os/constraints:windows", 22 | ), 23 | extra_data = struct(), 24 | key = MODIFIER_METADATA_KEY, 25 | stage0 = cfg_constructor_pre_constraint_analysis, 26 | stage1 = cfg_constructor_post_constraint_analysis, 27 | ) 28 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "buck2-rust" 3 | version = "0.0.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [[bin]] 8 | name = "reindeer" 9 | path = "reindeer.toml" 10 | 11 | [dependencies] 12 | # Standard library 13 | alloc = { path = "rust/library/alloc" } 14 | compiler_builtins = "0.1" 15 | core = { path = "rust/library/core" } 16 | panic_abort = { path = "rust/library/panic_abort" } 17 | panic_unwind = { path = "rust/library/panic_unwind" } 18 | proc_macro = { path = "rust/library/proc_macro" } 19 | std = { path = "rust/library/std", features = ["backtrace", "std_detect_dlsym_getauxval", "std_detect_file_io"] } 20 | test = { path = "rust/library/test" } 21 | 22 | # Compiler 23 | allocator-api2 = { version = "0.2", default-features = false } 24 | clippy = { path = "rust/src/tools/clippy", artifact = ["bin"] } 25 | rustc-main = { path = "rust/compiler/rustc", artifact = ["bin"], features = ["llvm"] } 26 | rustdoc-tool = { path = "rust/src/tools/rustdoc", artifact = ["bin"] } 27 | 28 | [patch.crates-io] 29 | rustc-std-workspace-alloc = { path = "rust/library/rustc-std-workspace-alloc" } 30 | rustc-std-workspace-core = { path = "rust/library/rustc-std-workspace-core" } 31 | rustc-std-workspace-std = { path = "rust/library/rustc-std-workspace-std" } 32 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | https://github.com/user-attachments/assets/78b9050a-dd2a-406b-9c5f-748d41f66ef4 2 | 3 | ## Example commands 4 | 5 | These do not need to be run in any particular order. 6 | 7 | ```console 8 | # Download crates.io dependencies 9 | $ buck2 uquery 'kind(crate_download, ...)' | xargs buck2 build 10 | 11 | # Check standard library and rustc using bootstrap compiler in #[cfg(bootstrap)] 12 | $ buck2 build stage1:std[check] 13 | $ buck2 build stage1:rustc[check] 14 | 15 | # Build and run stage1 compiler 16 | $ buck2 build stage1:rustc 17 | $ buck2 run stage1:rustc -- --version --verbose 18 | 19 | # Build and run stage2 compiler in #[cfg(not(bootstrap))] using stage1 compiler 20 | $ buck2 build stage2:rustc 21 | $ buck2 run stage2:rustc -- --version --verbose 22 | 23 | # Build various intermediate crates (stage1 by default) 24 | $ buck2 build :rustc_ast 25 | $ buck2 build :rustc_ast -m=stage2 26 | $ buck2 build :syn-2.0.101 --target-platforms //platforms/stage1:compiler 27 | 28 | # Document a crate using stage0 or stage1 rustdoc 29 | $ buck2 build :rustc_ast[doc] --show-simple-output 30 | $ buck2 build :rustc_ast[doc] -m=stage2 --show-simple-output 31 | 32 | # Print rustc warnings in rendered or JSON format 33 | $ buck2 build :rustc_ast[diag.txt] --out=- 34 | $ buck2 build :rustc_ast[diag.json] --out=- 35 | 36 | # Run clippy on a crate using stage0 or stage1 clippy 37 | $ buck2 build :rustc_ast[clippy.txt] --out=- 38 | $ buck2 build :rustc_ast[clippy.txt] -m=stage2 --out=- 39 | 40 | # Expand macros 41 | $ buck2 build :rustc_ast[expand] --out=- 42 | 43 | # Report documentation coverage (percentage of public APIs documented) 44 | $ buck2 build :rustc_ast[doc-coverage] --out=- | jq 45 | 46 | # Produce rustc and LLVM profiling data 47 | $ buck2 build :rustc_ast[profile][rustc_stages][raw] --show-output 48 | $ buck2 build :rustc_ast[profile][llvm_passes] --show-output 49 | ``` 50 | 51 | ## Configurations 52 | 53 | The following execution platforms are available for use with `--target-platforms`: 54 | 55 | - `//platforms/stage1:library` 56 | - `//platforms/stage1:library-build-script` 57 | - `//platforms/stage1:compiler` 58 | - `//platforms/stage1:compiler-build-script` 59 | - `//platforms/stage2:library` 60 | - `//platforms/stage2:library-build-script` 61 | - `//platforms/stage2:compiler` 62 | - `//platforms/stage2:compiler-build-script` 63 | 64 | The "stage1" platforms compile Rust code using stage0 downloaded rustc and 65 | rustdoc and clippy. The "stage2" platforms use the stage1 built-from-source 66 | tools. 67 | 68 | The "build-script" platforms compile without optimization. These are used for 69 | procedural macros and build.rs. The non-build-script platforms compile with a 70 | high level of optimization. 71 | 72 | The "build-script" and "compiler" platforms provide implicit sysroot 73 | dependencies so that `extern crate std` is available without declaring an 74 | explicit dependency on a crate called `std`. The non-build-script "library" 75 | platforms require explicit specification of dependencies. 76 | 77 | Most targets have a `default_target_platform` set so `--target-platforms` should 78 | usually not need to be specified. Use the modifier `-m=stage2` to replace the 79 | default stage1 target platform with the corresponding stage2 one. 80 | 81 | ## Cross-compilation 82 | 83 | This project is set up with a bare-bones C++ toolchain that relies on a system 84 | linker, which usually does not support linking for a different platform. But we 85 | do support type-checking, rustdoc, and clippy for different platforms, including 86 | both stage1 and stage2. 87 | 88 | Use the modifiers `aarch64`, `x86_64`, `linux`, `macos`, `windows`, or use 89 | target platforms like `//platforms/cross:aarch64-unknown-linux-gnu`. 90 | 91 | ```console 92 | # Typecheck rustc in stage1 for aarch64 linux (two equivalent ways) 93 | $ buck2 build stage1:rustc[check] --target-platforms //platforms/cross:aarch64-unknown-linux-gnu 94 | $ buck2 build stage1:rustc[check] -m=aarch64 -m=linux 95 | 96 | # Typecheck rustc in stage2 using stage1 rustc built for the host 97 | $ buck2 build stage2:rustc[check] -m=aarch64 -m=linux 98 | 99 | # Build documentation for a different platform 100 | $ buck2 build :rustc_ast[doc] -m=aarch64 -m=linux 101 | 102 | # Perform clippy checks for a different platform 103 | $ buck2 build :rustc_ast[clippy.txt] -m=aarch64 -m=linux --out=- 104 | ``` 105 | 106 | ## Whole-repo checks 107 | 108 | The commands above like `buck2 build :rustc_ast[clippy.txt]` report rustc 109 | warnings and clippy lints from just a single crate, not its transitive 110 | dependency graph like Cargo usually does. There is a [BXL] script for producing 111 | warnings for a whole dependency graph of a set of targets: 112 | 113 | [BXL]: https://buck2.build/docs/bxl 114 | 115 | ```console 116 | # Report warnings from every dependency of rustc: 117 | $ buck2 bxl scripts/check.bxl:main -- --target stage1:rustc | xargs cat 118 | 119 | # Run clippy on every dependency of rustc: 120 | $ buck2 bxl scripts/check.bxl:main -- --target stage1:rustc --output clippy.txt | xargs cat 121 | 122 | # Run clippy on every dependency of rustc and report lints in JSON: 123 | $ buck2 bxl scripts/check.bxl:main -- --target stage1:rustc --output clippy.json | xargs cat 124 | ``` 125 | 126 | ## Build speed 127 | 128 | Several factors add to make Buck-based bootstrap consistently faster than the 129 | Rust repo's custom x.py Cargo-based bootstrap system. 130 | 131 | On my machine, building stage2 rustc takes about 6.5 minutes with `buck2 clean; 132 | time buck2 build stage2:rustc` and about 8 minutes with `x.py clean && time x.py 133 | build compiler --stage=2`. The Buck build is **20%** faster. 134 | 135 | The difference widens when building multiple tools, not only rustc. Buck will 136 | build an arbitrary dependency graph concurrently while x.py is limited to 137 | building each different tool serially. `buck2 build stage2:rustc stage2:rustdoc 138 | stage2:clippy-driver` takes +46 seconds longer than building rustc alone, because 139 | Clippy is the long pole and takes exactly that much longer to build than 140 | rustc\_driver, which it depends on. But the equivalent `x.py build compiler 141 | src/tools/rustdoc src/tools/clippy --stage=2` takes +153 seconds longer than 142 | building rustc alone, because rustdoc takes +69 seconds and clippy takes +84 143 | seconds, and all three tools build serially. Altogether Buck is **32%** faster 144 | at building this group of tools. 145 | 146 | Some less significant factors that also make the Buck build faster: 147 | 148 | - x.py builds multiple copies of many crates. For example the `tracing` crate 149 | and its nontrivial dependency graph are built separately when rustc depends on 150 | tracing versus when rustdoc depends on tracing. In the Buck build, there is 151 | just one build of `tracing` that both rustc and rustdoc use. 152 | 153 | - In x.py, C++ dependencies (like the `llvm-wrapper` built by rustc\_llvm's 154 | build.rs) build pretty late in the build process, after a stage1 standard 155 | library is finished compiling, after rustc\_llvm's build-dependencies and 156 | build script are finished compiling. In Buck the llvm-wrapper build is one of 157 | the first things to build because it does not depend on any Rust code or 158 | anything else other than the unpack of downloaded LLVM headers. 159 | 160 | - The previous item is exacerbated by the fact that x.py builds llvm-wrapper 161 | multiple times, separately for stage1 and stage2, because there is no facility 162 | for the stage2 compiler build's build scripts to share such artifacts with the 163 | stage1 build. Buck builds llvm-wrapper once because the sources are all the 164 | same, the same C++ compiler is used by stage1 and stage2, and the flags to the 165 | C++ compiler are the same, so we are really talking about one build action. 166 | Stage1 and stage2 differ only in what Rust compiler is used and whether 167 | `--cfg=bootstrap` is passed to Rust compilations, neither of which is relevant 168 | to a C++ compilation. 169 | 170 | Incremental builds are faster in Buck too. After already having built it, 171 | rebuilding rustc\_ast with a small change in its lib.rs takes 1.625 seconds with 172 | `buck2 build :rustc_ast[check]` and 2.6 seconds with `x.py check 173 | compiler/rustc_ast`. The actual underlying rustc command to typecheck rustc\_ast 174 | used by both build systems takes 1.575 seconds, so Buck's overhead for this is 175 | 50 milliseconds (0.05 seconds) while x.py's and Cargo's is about 1 second, an 176 | order of magnitude larger. 177 | 178 | At least 2 factors contribute to x.py's overhead: 179 | 180 | - x.py does not have a granular view of the dependency graph. At a high level it 181 | knows that building the compiler requires building the standard library first, 182 | but within the standard library or compiler it does not manage what crate 183 | depends on which others, and which source files go into which crate. Even when 184 | local changes definitely do not require rebuilding the standard library, x.py 185 | must still delegate to a sequence of slow serial Cargo invocations whereby 186 | Cargo could choose to rebuild the standard library if it were necessary (which 187 | it isn't), adding latency. In contrast, a single Buck process coordinates the 188 | entire dependency graph from top-level targets to build actions to input files 189 | which those actions operate on. If is quick to map from a file change to 190 | exactly which build actions need to be kicked off right away. 191 | 192 | - The state of the Buck build graph is preserved in memory across CLI commands. 193 | Like how IDEs rely on a long-running language server (LSP) that preserves 194 | facts about the user's program in complex data structures in memory to serve 195 | IDE features with low latency, Buck does this for build graphs. In contrast, 196 | Cargo reloads the world each time it runs, including parsing Cargo.toml files 197 | and lockfiles and Cargo config files. And as mentioned, x.py will do multiple 198 | of these Cargo invocations serially. 199 | -------------------------------------------------------------------------------- /allocator/BUCK: -------------------------------------------------------------------------------- 1 | rust_library( 2 | name = "rust_allocator", 3 | srcs = [ 4 | "allocator.rs", 5 | "std_alloc.rs", 6 | ], 7 | crate = "rust_allocator", 8 | crate_root = "allocator.rs", 9 | edition = "2024", 10 | features = [ 11 | "std", 12 | ], 13 | preferred_linkage = "static", 14 | rustc_flags = [ 15 | "-Clink-arg=-fvisibility=hidden", 16 | "-Ainternal_features", 17 | ], 18 | target_compatible_with = [ 19 | "//constraints:library", 20 | "//constraints:sysroot-deps=explicit", 21 | ], 22 | visibility = ["PUBLIC"], 23 | deps = [ 24 | "//:alloc", 25 | "//:std", 26 | ], 27 | ) 28 | 29 | alias( 30 | name = "allocator-api2", 31 | actual = select({ 32 | "//constraints:library": None, 33 | "//constraints:compiler": "//:allocator-api2", 34 | }), 35 | default_target_platform = "//platforms/stage1:library", 36 | visibility = ["//:"], 37 | ) 38 | -------------------------------------------------------------------------------- /allocator/allocator.rs: -------------------------------------------------------------------------------- 1 | // Allocations in Rust code invoke `__rust_alloc` and its kin under the hood. 2 | // These functions arren't actually implemented anywhere - instead, the compiler 3 | // will in certain cases inject an "allocator shim" implementation for them 4 | // which calls the corresponding *actual* implementation: 5 | // - `__rdl_*` by default 6 | // - `__rg_*` if `#[global_allocator]` is set 7 | // 8 | // The cases in which an allocator shim is generated are: 9 | // - when building a `bin` crate 10 | // - when building a `staticlib` crate 11 | // - when building a `cdylib` crate 12 | // - when building *the first* `dylib` crate in a dependency graph 13 | // 14 | // There are use cases where none of those criteria are satisfied yet we still 15 | // need an allocator. For example, in a diamon dependency scenario: 16 | // 17 | // foo.cpp <- top-level target 18 | // / \ 19 | // / \ 20 | // left.rs right.rs 21 | // \ / 22 | // \ / 23 | // shared.rs 24 | // 25 | // Officially `left.rs` and `right.rs` are supposed to be built as `staticlib` 26 | // or `cdylib` crates which both bundle `shared.rs` and the standard library in 27 | // their output. This has several downsides (bloat, symbol collisions, singleton 28 | // conflicts...) so we want to build them as `rlib` crates instead. If all of 29 | // our Rust crates are `rlib`s, we won't get an allocator shim. 30 | // 31 | // We can't get the compiler to generate an allocator shim for us, but we can 32 | // effectively provide our own by defining `__rust_alloc` and friends ourselves 33 | // to point to the default allocator. 34 | // 35 | // In case it comes up, on Android we have to use a custom malloc because 36 | // Clang+LLVM assume allocations are 16-byte-aligned which is not guaranteed to 37 | // be true on Android 6 and earlier. This can result in a SIGBUS. 38 | 39 | #![feature(alloc_internals)] 40 | #![feature(linkage)] 41 | #![cfg_attr(not(feature = "std"), no_std)] 42 | 43 | #[cfg(feature = "std")] 44 | pub mod std_alloc; 45 | 46 | extern crate alloc; 47 | 48 | use alloc::alloc::__alloc_error_handler; 49 | 50 | #[unsafe(no_mangle)] 51 | #[linkage = "weak"] 52 | pub static __rust_alloc_error_handler_should_panic: u8 = 1; 53 | 54 | #[unsafe(no_mangle)] 55 | #[linkage = "weak"] 56 | pub static __rust_no_alloc_shim_is_unstable: u8 = 1; 57 | 58 | #[unsafe(no_mangle)] 59 | #[cfg_attr(not(target_os = "ios"), linkage = "weak")] 60 | pub unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! { 61 | unsafe { __alloc_error_handler::__rdl_oom(size, align) } 62 | } 63 | 64 | #[unsafe(no_mangle)] 65 | #[linkage = "weak"] 66 | pub unsafe fn __rg_oom(size: usize, align: usize) -> ! { 67 | unsafe { __alloc_error_handler::__rdl_oom(size, align) } 68 | } 69 | -------------------------------------------------------------------------------- /allocator/std_alloc.rs: -------------------------------------------------------------------------------- 1 | use std::alloc::{GlobalAlloc, Layout, System, __default_lib_allocator}; 2 | 3 | #[unsafe(no_mangle)] 4 | #[linkage = "weak"] 5 | pub unsafe fn __rust_alloc(size: usize, align: usize) -> *mut u8 { 6 | unsafe { __default_lib_allocator::__rdl_alloc(size, align) } 7 | } 8 | 9 | #[unsafe(no_mangle)] 10 | #[linkage = "weak"] 11 | pub unsafe fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { 12 | unsafe { 13 | let layout = Layout::from_size_align_unchecked(size, align); 14 | System.alloc(layout) 15 | } 16 | } 17 | 18 | #[unsafe(no_mangle)] 19 | #[linkage = "weak"] 20 | pub unsafe fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { 21 | unsafe { __default_lib_allocator::__rdl_alloc_zeroed(size, align) } 22 | } 23 | 24 | #[unsafe(no_mangle)] 25 | #[linkage = "weak"] 26 | pub unsafe fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { 27 | unsafe { 28 | let layout = Layout::from_size_align_unchecked(size, align); 29 | System.alloc_zeroed(layout) 30 | } 31 | } 32 | 33 | #[unsafe(no_mangle)] 34 | #[linkage = "weak"] 35 | pub unsafe fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) { 36 | unsafe { 37 | __default_lib_allocator::__rdl_dealloc(ptr, size, align); 38 | } 39 | } 40 | 41 | #[unsafe(no_mangle)] 42 | #[linkage = "weak"] 43 | pub unsafe fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { 44 | unsafe { 45 | let layout = Layout::from_size_align_unchecked(size, align); 46 | System.dealloc(ptr, layout); 47 | } 48 | } 49 | 50 | #[unsafe(no_mangle)] 51 | #[linkage = "weak"] 52 | pub unsafe fn __rust_realloc( 53 | ptr: *mut u8, 54 | old_size: usize, 55 | align: usize, 56 | new_size: usize, 57 | ) -> *mut u8 { 58 | unsafe { __default_lib_allocator::__rdl_realloc(ptr, old_size, align, new_size) } 59 | } 60 | 61 | #[unsafe(no_mangle)] 62 | #[linkage = "weak"] 63 | pub unsafe fn __rdl_realloc( 64 | ptr: *mut u8, 65 | old_size: usize, 66 | align: usize, 67 | new_size: usize, 68 | ) -> *mut u8 { 69 | unsafe { 70 | let old_layout = Layout::from_size_align_unchecked(old_size, align); 71 | System.realloc(ptr, old_layout, new_size) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /constraints/BUCK: -------------------------------------------------------------------------------- 1 | load(":defs.bzl", "constraint") 2 | 3 | constraint( 4 | setting = "false", 5 | ) 6 | 7 | constraint( 8 | setting = "sysroot-deps", 9 | values = [ 10 | # Crate must declare explicit dependencies on standard library. This is 11 | # enabled within standard library code. 12 | "sysroot-deps=explicit", 13 | # Crate implicitly receives access to standard library crates, such as 14 | # within compiler code and standard library build scripts. 15 | "sysroot-deps=implicit", 16 | ], 17 | ) 18 | 19 | constraint( 20 | setting = "reindeer-universe", 21 | values = [ 22 | # Transitive dependencies of rust/library/. 23 | "library", 24 | # Transitive dependencies of rust/compiler/. 25 | "compiler", 26 | ], 27 | ) 28 | 29 | constraint( 30 | setting = "bootstrap-stage", 31 | values = [ 32 | # Use stage0 (download) to build stage1 standard library and compiler. 33 | "stage1", 34 | # Use stage1 to build stage2 standard library and compiler. 35 | "stage2", 36 | ], 37 | ) 38 | 39 | constraint( 40 | setting = "opt-level", 41 | values = [ 42 | "opt-level=0", 43 | "opt-level=3", 44 | ], 45 | ) 46 | -------------------------------------------------------------------------------- /constraints/defs.bzl: -------------------------------------------------------------------------------- 1 | def _unified_constraint_impl(ctx: AnalysisContext) -> list[Provider]: 2 | label = ctx.label.raw_target() 3 | setting = ConstraintSettingInfo(label = label) 4 | value = ConstraintValueInfo(setting = setting, label = label) 5 | 6 | return [ 7 | DefaultInfo(), 8 | setting, 9 | value, 10 | ConfigurationInfo( 11 | constraints = {label: value}, 12 | values = {}, 13 | ), 14 | ] 15 | 16 | unified_constraint = rule( 17 | impl = _unified_constraint_impl, 18 | attrs = {}, 19 | is_configuration_rule = True, 20 | ) 21 | 22 | def constraint(setting, values = []): 23 | if values: 24 | native.constraint_setting( 25 | name = setting, 26 | visibility = ["PUBLIC"], 27 | ) 28 | for value in values: 29 | native.constraint_value( 30 | name = value, 31 | constraint_setting = ":{}".format(setting), 32 | visibility = ["PUBLIC"], 33 | ) 34 | else: 35 | unified_constraint( 36 | name = setting, 37 | visibility = ["PUBLIC"], 38 | ) 39 | 40 | def _configuration_transition_impl(ctx: AnalysisContext) -> list[Provider]: 41 | label = ctx.attrs.label or ctx.label.name 42 | 43 | if ctx.attrs.add_fallback_settings: 44 | fallback_constraints = ctx.attrs.add_fallback_settings[PlatformInfo].configuration.constraints 45 | else: 46 | fallback_constraints = {} 47 | 48 | keep = set() 49 | for setting in ctx.attrs.keep_settings or []: 50 | keep.add(setting[ConstraintSettingInfo].label) 51 | 52 | discard = set() 53 | for setting in ctx.attrs.discard_settings or []: 54 | discard.add(setting[ConstraintSettingInfo].label) 55 | 56 | def transition_impl(platform: PlatformInfo) -> PlatformInfo: 57 | constraints = dict(fallback_constraints) 58 | for setting, value in platform.configuration.constraints.items(): 59 | if setting in keep or (discard and setting not in discard): 60 | constraints[setting] = value 61 | 62 | return PlatformInfo( 63 | label = label, 64 | configuration = ConfigurationInfo( 65 | constraints = constraints, 66 | values = platform.configuration.values, 67 | ), 68 | ) 69 | 70 | return [ 71 | DefaultInfo(), 72 | TransitionInfo(impl = transition_impl), 73 | ] 74 | 75 | configuration_transition = rule( 76 | impl = _configuration_transition_impl, 77 | attrs = { 78 | "add_fallback_settings": attrs.option(attrs.dep(providers = [PlatformInfo]), default = None), 79 | "discard_settings": attrs.option(attrs.list(attrs.dep(providers = [ConstraintSettingInfo])), default = None), 80 | "keep_settings": attrs.option(attrs.list(attrs.dep(providers = [ConstraintSettingInfo])), default = None), 81 | "label": attrs.option(attrs.string(), default = None), 82 | }, 83 | is_configuration_rule = True, 84 | ) 85 | 86 | transition_alias = rule( 87 | impl = lambda ctx: ctx.attrs.actual.providers, 88 | attrs = {"actual": attrs.dep()}, 89 | supports_incoming_transition = True, 90 | ) 91 | -------------------------------------------------------------------------------- /crates.io/BUCK: -------------------------------------------------------------------------------- 1 | load("//constraints:defs.bzl", "configuration_transition") 2 | 3 | configuration_transition( 4 | name = "download", 5 | visibility = ["PUBLIC"], 6 | ) 7 | -------------------------------------------------------------------------------- /crates.io/crate_download.bzl: -------------------------------------------------------------------------------- 1 | load(":rule.bzl", _crate_download = "crate_download") 2 | 3 | def crate_download(**kwargs): 4 | _crate_download( 5 | incoming_transition = "//crates.io:download", 6 | **kwargs 7 | ) 8 | -------------------------------------------------------------------------------- /crates.io/rule.bzl: -------------------------------------------------------------------------------- 1 | load("@prelude//http_archive:exec_deps.bzl", "HttpArchiveExecDeps") 2 | load("@prelude//http_archive:unarchive.bzl", "unarchive") 3 | 4 | def _crate_download_impl(ctx: AnalysisContext) -> list[Provider]: 5 | filename = ctx.label.name.removesuffix(".crate") + ".tar.gz" 6 | archive = ctx.actions.declare_output(filename) 7 | ctx.actions.download_file( 8 | archive.as_output(), 9 | ctx.attrs.urls[0], 10 | sha256 = ctx.attrs.sha256, 11 | is_deferrable = True, 12 | ) 13 | 14 | output, sub_targets = unarchive( 15 | ctx = ctx, 16 | archive = archive, 17 | output_name = ctx.label.name, 18 | ext_type = "tar.gz", 19 | excludes = [], 20 | strip_prefix = ctx.attrs.strip_prefix, 21 | exec_deps = ctx.attrs._exec_deps[HttpArchiveExecDeps], 22 | prefer_local = False, 23 | sub_targets = ctx.attrs.sub_targets, 24 | ) 25 | 26 | return [DefaultInfo( 27 | default_output = output, 28 | sub_targets = sub_targets, 29 | )] 30 | 31 | crate_download = rule( 32 | impl = _crate_download_impl, 33 | attrs = { 34 | "_exec_deps": attrs.default_only(attrs.exec_dep(providers = [HttpArchiveExecDeps], default = "//platforms/exec:http_archive")), 35 | "sha256": attrs.string(), 36 | "strip_prefix": attrs.string(), 37 | "sub_targets": attrs.list(attrs.string(), default = []), 38 | "urls": attrs.list(attrs.string()), 39 | }, 40 | supports_incoming_transition = True, 41 | ) 42 | -------------------------------------------------------------------------------- /defs.bzl: -------------------------------------------------------------------------------- 1 | load("@prelude//:rules.bzl", "rust_library") 2 | load("@prelude//rust:cargo_buildscript.bzl", "buildscript_run") 3 | load("@prelude//rust:cargo_package.bzl", "apply_platform_attrs") 4 | load("@prelude//rust:proc_macro_alias.bzl", "rust_proc_macro_alias") 5 | load("@prelude//utils:type_defs.bzl", "is_select") 6 | load("//constraints:defs.bzl", "transition_alias") 7 | 8 | def rust_bootstrap_alias(actual, **kwargs): 9 | if not actual.endswith("-0.0.0"): 10 | native.alias( 11 | actual = actual, 12 | target_compatible_with = _target_constraints(None), 13 | **kwargs 14 | ) 15 | 16 | def rust_bootstrap_binary( 17 | name, 18 | crate, 19 | crate_root, 20 | platform = {}, 21 | rustc_flags = [], 22 | **kwargs): 23 | extra_rustc_flags = [] 24 | 25 | if crate_root.startswith("rust/library/"): 26 | default_target_platform = "//platforms/stage1:library-build-script" 27 | elif crate_root.startswith("rust/compiler/") or crate_root.startswith("rust/src/"): 28 | default_target_platform = "//platforms/stage1:compiler" 29 | else: 30 | default_target_platform = "//platforms/stage1:compiler" 31 | extra_rustc_flags.append("--cap-lints=allow") 32 | 33 | native.rust_binary( 34 | name = name, 35 | crate = crate, 36 | crate_root = crate_root, 37 | default_target_platform = default_target_platform, 38 | rustc_flags = rustc_flags + extra_rustc_flags, 39 | target_compatible_with = _target_constraints(crate_root), 40 | **apply_platform_attrs(platform, kwargs) 41 | ) 42 | 43 | def rust_bootstrap_library( 44 | name, 45 | crate, 46 | crate_root, 47 | deps = [], 48 | env = {}, 49 | platform = {}, 50 | preferred_linkage = None, 51 | proc_macro = False, 52 | rustc_flags = [], 53 | srcs = [], 54 | visibility = None, 55 | **kwargs): 56 | target_compatible_with = _target_constraints(crate_root) 57 | 58 | if name.endswith("-0.0.0"): 59 | versioned_name = name 60 | name = name.removesuffix("-0.0.0") 61 | native.alias( 62 | name = versioned_name, 63 | actual = ":{}".format(name), 64 | target_compatible_with = target_compatible_with, 65 | ) 66 | visibility = ["PUBLIC"] 67 | 68 | extra_deps = [] 69 | extra_env = {} 70 | extra_rustc_flags = [] 71 | extra_srcs = [] 72 | 73 | if crate_root.startswith("rust/library/"): 74 | default_target_platform = "//platforms/stage1:library" 75 | elif crate_root.startswith("rust/compiler/") or crate_root.startswith("rust/src/"): 76 | default_target_platform = "//platforms/stage1:compiler" 77 | messages_ftl = glob(["rust/compiler/{}/messages.ftl".format(crate)]) 78 | if messages_ftl: 79 | extra_env["CARGO_PKG_NAME"] = crate 80 | extra_srcs += messages_ftl 81 | extra_srcs.append("rust/src/version") 82 | extra_env["CFG_RELEASE"] = "\\$(cat rust/src/version)" 83 | extra_env["CFG_RELEASE_CHANNEL"] = "dev" 84 | extra_env["CFG_VERSION"] = "\\$(cat rust/src/version) " + select({ 85 | "//constraints:stage1": "(buckified stage1)", 86 | "//constraints:stage2": "(buckified stage2)", 87 | }) 88 | extra_env["CFG_COMPILER_HOST_TRIPLE"] = "$(target_triple)" 89 | extra_deps.append("toolchains//target:target_triple") 90 | else: 91 | default_target_platform = None 92 | extra_rustc_flags.append("--cap-lints=allow") 93 | 94 | if proc_macro: 95 | rust_proc_macro_alias( 96 | name = name, 97 | actual_exec = ":_{}".format(name), 98 | actual_plugin = ":_{}".format(name), 99 | default_target_platform = default_target_platform, 100 | target_compatible_with = target_compatible_with, 101 | visibility = visibility, 102 | ) 103 | name = "_{}".format(name) 104 | visibility = [] 105 | 106 | rust_library( 107 | name = name, 108 | crate = crate, 109 | crate_root = crate_root, 110 | default_target_platform = default_target_platform, 111 | preferred_linkage = preferred_linkage or "static", 112 | proc_macro = proc_macro, 113 | srcs = srcs + extra_srcs, 114 | target_compatible_with = target_compatible_with, 115 | visibility = visibility, 116 | **apply_platform_attrs(platform, kwargs | dict( 117 | deps = deps + extra_deps, 118 | env = env + extra_env if is_select(env) else env | extra_env, 119 | rustc_flags = rustc_flags + extra_rustc_flags, 120 | )) 121 | ) 122 | 123 | def rust_bootstrap_buildscript_run(**kwargs): 124 | buildscript_run( 125 | target_compatible_with = _target_constraints(None), 126 | **kwargs 127 | ) 128 | 129 | def cxx_bootstrap_library( 130 | name, 131 | compatible_with = None, 132 | deps = [], 133 | visibility = None, 134 | **kwargs): 135 | extra_deps = ["toolchains//cxx:stdlib"] 136 | 137 | native.cxx_library( 138 | name = "{}-compile".format(name), 139 | compatible_with = compatible_with, 140 | deps = deps + extra_deps, 141 | **kwargs 142 | ) 143 | 144 | transition_alias( 145 | name = name, 146 | actual = ":{}-compile".format(name), 147 | compatible_with = compatible_with, 148 | incoming_transition = "toolchains//cxx:prune_cxx_configuration", 149 | visibility = visibility, 150 | ) 151 | 152 | def _target_constraints(crate_root): 153 | if crate_root and crate_root.startswith("rust/library/"): 154 | target_compatible_with = [ 155 | "//constraints:library", 156 | "//constraints:sysroot-deps=explicit", 157 | ] 158 | elif crate_root and (crate_root.startswith("rust/compiler/") or crate_root.startswith("rust/src/")): 159 | target_compatible_with = [ 160 | "//constraints:compiler", 161 | "//constraints:sysroot-deps=implicit", 162 | ] 163 | else: 164 | target_compatible_with = select({ 165 | "DEFAULT": ["//constraints:false"], 166 | "//constraints:compiler": [], 167 | "//constraints:library": [], 168 | }) 169 | 170 | return target_compatible_with 171 | -------------------------------------------------------------------------------- /fixups/ahash/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/basic-toml/fixups.toml: -------------------------------------------------------------------------------- 1 | cargo_env = [ 2 | "CARGO_PKG_VERSION_MAJOR", 3 | "CARGO_PKG_VERSION_MINOR", 4 | "CARGO_PKG_VERSION_PATCH", 5 | ] 6 | -------------------------------------------------------------------------------- /fixups/blake3/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | 3 | ['cfg(target_arch = "x86_64")'] 4 | cfgs = ["blake3_sse2_ffi", "blake3_sse41_ffi", "blake3_avx2_ffi", "blake3_avx512_ffi"] 5 | 6 | [['cfg(all(target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))'.cxx_library]] 7 | name = "simd_x86_unix" 8 | srcs = [ 9 | "c/blake3.c", 10 | "c/blake3_dispatch.c", 11 | "c/blake3_portable.c", 12 | "c/blake3_sse2_x86-64_unix.S", 13 | "c/blake3_sse41_x86-64_unix.S", 14 | "c/blake3_avx2_x86-64_unix.S", 15 | "c/blake3_avx512_x86-64_unix.S", 16 | ] 17 | compiler_flags = ["-mavx512f", "-mavx512vl"] 18 | headers = ["c/*.h"] 19 | compatible_with = [ 20 | "prelude//os/constraints:linux", 21 | "prelude//os/constraints:macos", 22 | ] 23 | 24 | [['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "gnu"))'.cxx_library]] 25 | name = "simd_x86_windows_gnu" 26 | srcs = [ 27 | "c/blake3.c", 28 | "c/blake3_dispatch.c", 29 | "c/blake3_portable.c", 30 | "c/blake3_sse2_x86-64_windows_gnu.S", 31 | "c/blake3_sse41_x86-64_windows_gnu.S", 32 | "c/blake3_avx2_x86-64_windows_gnu.S", 33 | "c/blake3_avx512_x86-64_windows_gnu.S", 34 | ] 35 | compiler_flags = ["-mavx512f", "-mavx512vl"] 36 | headers = ["c/*.h"] 37 | compatible_with = ["prelude//os/constraints:windows"] 38 | 39 | [['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "msvc"))'.cxx_library]] 40 | name = "simd_x86_windows_msvc" 41 | srcs = [ 42 | "c/blake3.c", 43 | "c/blake3_dispatch.c", 44 | "c/blake3_portable.c", 45 | "c/blake3_sse2_x86-64_windows_msvc.asm", 46 | "c/blake3_sse41_x86-64_windows_msvc.asm", 47 | "c/blake3_avx2_x86-64_windows_msvc.asm", 48 | "c/blake3_avx512_x86-64_windows_msvc.asm", 49 | ] 50 | headers = ["c/*.h"] 51 | compatible_with = ["prelude//os/constraints:windows"] 52 | 53 | ['cfg(any(target_arch = "aarch64", target_arch = "arm"))'] 54 | cfgs = ["blake3_neon"] 55 | 56 | [['cfg(target_arch = "aarch64")'.cxx_library]] 57 | name = "simd_neon-aarch64" 58 | srcs = ["c/blake3_neon.c"] 59 | headers = ["c/*.h"] 60 | -------------------------------------------------------------------------------- /fixups/camino/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/clippy/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | cargo_env = [ 3 | "CARGO_PKG_NAME", 4 | "CARGO_PKG_VERSION_MAJOR", 5 | "CARGO_PKG_VERSION_MINOR", 6 | "CARGO_PKG_VERSION_PATCH", 7 | ] 8 | extra_deps = [ 9 | ":rustc_driver-0.0.0", 10 | ":rustc_interface-0.0.0", 11 | ":rustc_session-0.0.0", 12 | ":rustc_span-0.0.0", 13 | ] 14 | linker_flags = ["-Wl,-rpath,$ORIGIN/../lib"] 15 | -------------------------------------------------------------------------------- /fixups/clippy_config/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_deps = [ 2 | ":rustc_errors-0.0.0", 3 | ":rustc_hir-0.0.0", 4 | ":rustc_middle-0.0.0", 5 | ":rustc_session-0.0.0", 6 | ":rustc_span-0.0.0", 7 | ] 8 | -------------------------------------------------------------------------------- /fixups/clippy_lints/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_deps = [ 2 | ":pulldown-cmark-0.11.3", 3 | ":rustc_abi-0.0.0", 4 | ":rustc_arena-0.0.0", 5 | ":rustc_ast-0.0.0", 6 | ":rustc_ast_pretty-0.0.0", 7 | ":rustc_attr_parsing-0.0.0", 8 | ":rustc_data_structures-0.0.0", 9 | ":rustc_driver-0.0.0", 10 | ":rustc_errors-0.0.0", 11 | ":rustc_hir-0.0.0", 12 | ":rustc_hir_analysis-0.0.0", 13 | ":rustc_hir_pretty-0.0.0", 14 | ":rustc_hir_typeck-0.0.0", 15 | ":rustc_index-0.0.0", 16 | ":rustc_infer-0.0.0", 17 | ":rustc_lexer-0.0.0", 18 | ":rustc_lint-0.0.0", 19 | ":rustc_middle-0.0.0", 20 | ":rustc_parse-0.0.0", 21 | ":rustc_parse_format-0.0.0", 22 | ":rustc_resolve-0.0.0", 23 | ":rustc_session-0.0.0", 24 | ":rustc_span-0.0.0", 25 | ":rustc_target-0.0.0", 26 | ":rustc_trait_selection-0.0.0", 27 | ":thin-vec-0.2.14", 28 | ] 29 | -------------------------------------------------------------------------------- /fixups/clippy_utils/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_deps = [ 2 | ":rustc_abi-0.0.0", 3 | ":rustc_ast-0.0.0", 4 | ":rustc_ast_pretty-0.0.0", 5 | ":rustc_attr_parsing-0.0.0", 6 | ":rustc_const_eval-0.0.0", 7 | ":rustc_data_structures-0.0.0", 8 | ":rustc_driver-0.0.0", 9 | ":rustc_errors-0.0.0", 10 | ":rustc_hir-0.0.0", 11 | ":rustc_hir_typeck-0.0.0", 12 | ":rustc_index-0.0.0", 13 | ":rustc_infer-0.0.0", 14 | ":rustc_lexer-0.0.0", 15 | ":rustc_lint-0.0.0", 16 | ":rustc_middle-0.0.0", 17 | ":rustc_mir_dataflow-0.0.0", 18 | ":rustc_session-0.0.0", 19 | ":rustc_span-0.0.0", 20 | ":rustc_trait_selection-0.0.0", 21 | ":smallvec-1.15.0", 22 | ] 23 | -------------------------------------------------------------------------------- /fixups/compiler_builtins/fixups.toml: -------------------------------------------------------------------------------- 1 | rustc_flags = [ 2 | # Port of Cargo change: https://github.com/rust-lang/rust/pull/73136/files 3 | # 4 | # Set this to a large value in order to allow compiler-builtins to generate 5 | # 1 symbol per object file. This is needed in order to allow the linker to 6 | # avoid duplicate symbols. 7 | "-Ccodegen-units=10000", 8 | ] 9 | 10 | [buildscript.run.env] 11 | # Read by the build script, but only relevant to libm tests. 12 | OPT_LEVEL = "3" 13 | -------------------------------------------------------------------------------- /fixups/core/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_srcs = [ 2 | "src/**/*.md", 3 | "../portable-simd/crates/core_simd/src/core_simd_docs.md", 4 | "../portable-simd/crates/core_simd/**/*.rs", 5 | "../stdarch/crates/core_arch/src/core_arch_docs.md", 6 | "../stdarch/crates/core_arch/**/*.rs", 7 | ] 8 | -------------------------------------------------------------------------------- /fixups/crossbeam-utils/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/generic-array/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/getrandom/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/hashbrown/fixups.toml: -------------------------------------------------------------------------------- 1 | # Hashbrown does not really depend on allocator-api2 but `cargo metadata` is 2 | # claiming that it is, likely because of https://github.com/rust-lang/cargo/issues/10801 3 | omit_deps = ["allocator_api2"] 4 | extra_deps = ["//allocator:allocator-api2"] 5 | 6 | # Undo https://github.com/rust-lang/rust/pull/138425 for hashbrown >=0.15.3 and rustc <1.87.0 7 | features = ["raw-entry"] 8 | 9 | [rustc_flags_select] 10 | "//constraints:compiler" = [] 11 | "//constraints:library" = ["-Zforce-unstable-if-unmarked"] 12 | -------------------------------------------------------------------------------- /fixups/icu_list_data/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/icu_locid_transform_data/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/icu_normalizer_data/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | extra_srcs = ["data/**"] 3 | -------------------------------------------------------------------------------- /fixups/icu_properties_data/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | extra_srcs = ["data/**"] 3 | -------------------------------------------------------------------------------- /fixups/libc/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/lock_api/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/mime_guess/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | 3 | [env] 4 | MIME_TYPES_GENERATED_PATH = "$(location :mime_guess-2.0.5-build-script-run[out_dir])/mime_types_generated.rs" 5 | -------------------------------------------------------------------------------- /fixups/nix/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/object/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/panic_abort/fixups.toml: -------------------------------------------------------------------------------- 1 | rustc_flags = ["-Cpanic=abort"] 2 | -------------------------------------------------------------------------------- /fixups/parking_lot_core/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/proc-macro-hack/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/proc-macro2/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/profiler_builtins/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/psm/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | 3 | ['cfg(all(target_arch = "x86_64", target_os = "linux"))'] 4 | cfgs = ["asm", "switchable_stack"] 5 | [['cfg(all(target_arch = "x86_64", target_os = "linux"))'.cxx_library]] 6 | name = "psm_s-linux-x86_64" 7 | srcs = ["src/arch/x86_64.s"] 8 | compiler_flags = ["-xassembler-with-cpp"] 9 | headers = ["src/arch/psm.h"] 10 | 11 | ['cfg(all(target_arch = "aarch64", target_os = "linux"))'] 12 | cfgs = ["asm", "switchable_stack"] 13 | [['cfg(all(target_arch = "aarch64", target_os = "linux"))'.cxx_library]] 14 | name = "psm_s-linux-aarch64" 15 | srcs = ["src/arch/aarch_aapcs64.s"] 16 | compiler_flags = ["-xassembler-with-cpp"] 17 | headers = ["src/arch/psm.h"] 18 | 19 | ['cfg(all(target_arch = "x86_64", target_os = "macos"))'] 20 | cfgs = ["asm", "switchable_stack"] 21 | [['cfg(all(target_arch = "x86_64", target_os = "macos"))'.cxx_library]] 22 | name = "psm_s-macos-x86_64" 23 | srcs = ["src/arch/x86_64.s"] 24 | compiler_flags = ["-xassembler-with-cpp"] 25 | preprocessor_flags = ["-DCFG_TARGET_OS_macos"] 26 | headers = ["src/arch/psm.h"] 27 | 28 | ['cfg(all(target_arch = "aarch64", target_os = "macos"))'] 29 | cfgs = ["asm", "switchable_stack"] 30 | [['cfg(all(target_arch = "aarch64", target_os = "macos"))'.cxx_library]] 31 | name = "psm_s-macos-aarch64" 32 | srcs = ["src/arch/aarch_aapcs64.s"] 33 | compiler_flags = ["-xassembler-with-cpp"] 34 | preprocessor_flags = ["-DCFG_TARGET_OS_macos"] 35 | headers = ["src/arch/psm.h"] 36 | 37 | ['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "msvc"))'] 38 | cfgs = ["asm"] 39 | [['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "msvc"))'.cxx_library]] 40 | name = "psm_s-windows-x86_64-msvc" 41 | srcs = ["src/arch/x86_64_msvc.asm"] 42 | headers = ["src/arch/psm.h"] 43 | 44 | ['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "gnu"))'] 45 | cfgs = ["asm"] 46 | [['cfg(all(target_arch = "x86_64", target_os = "windows", target_env = "gnu"))'.cxx_library]] 47 | name = "psm_s-windows-x86_64-gnu" 48 | srcs = ["src/arch/x86_64_windows_gnu.s"] 49 | compiler_flags = ["-xassembler-with-cpp"] 50 | headers = ["src/arch/psm.h"] 51 | -------------------------------------------------------------------------------- /fixups/pulldown-cmark/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/rustc-main/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | linker_flags = ["-Wl,-rpath,$ORIGIN/../lib"] 3 | -------------------------------------------------------------------------------- /fixups/rustc_apfloat/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/rustc_codegen_llvm/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_srcs = ["src/debuginfo/doc.md"] 2 | rustc_flags = ["-Zlink-directives=no"] 3 | -------------------------------------------------------------------------------- /fixups/rustc_errors/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_srcs = ["../rustc_error_codes/src/error_codes/**"] 2 | -------------------------------------------------------------------------------- /fixups/rustc_interface/fixups.toml: -------------------------------------------------------------------------------- 1 | [env] 2 | RUSTC_INSTALL_BINDIR = "bin" 3 | -------------------------------------------------------------------------------- /fixups/rustc_llvm/BUCK: -------------------------------------------------------------------------------- 1 | load( 2 | ":defs.bzl", 3 | "llvm_config", 4 | "llvm_cxx_flags", 5 | "llvm_linker_flags", 6 | "llvm_preprocessor_flags", 7 | "llvm_rustc_flags", 8 | ) 9 | 10 | llvm_config( 11 | name = "llvm-config", 12 | llvm = "//stage0:ci_llvm", 13 | ) 14 | 15 | configured_alias( 16 | name = "host-llvm-config", 17 | actual = ":llvm-config", 18 | platform = "//platforms:host", 19 | ) 20 | 21 | llvm_rustc_flags( 22 | name = "rustc-flags", 23 | llvm_config = ":host-llvm-config", 24 | visibility = ["//:rustc_llvm"], 25 | ) 26 | 27 | llvm_cxx_flags( 28 | name = "cxx-flags", 29 | llvm_config = ":host-llvm-config", 30 | visibility = ["//:rustc_llvm-0.0.0-llvm-wrapper-compile"], 31 | ) 32 | 33 | llvm_preprocessor_flags( 34 | name = "preprocessor-flags", 35 | llvm_config = ":host-llvm-config", 36 | visibility = ["//:rustc_llvm-0.0.0-llvm-wrapper-compile"], 37 | ) 38 | 39 | llvm_linker_flags( 40 | name = "linker-flags", 41 | llvm_config = ":host-llvm-config", 42 | ) 43 | 44 | prebuilt_cxx_library( 45 | name = "llvm", 46 | exported_linker_flags = [ 47 | "-L$(location //stage0:ci_llvm)/lib", 48 | "-lz", 49 | "@$(location :linker-flags)", 50 | ], 51 | visibility = ["//:rustc_llvm-0.0.0-llvm-wrapper-compile"], 52 | ) 53 | -------------------------------------------------------------------------------- /fixups/rustc_llvm/defs.bzl: -------------------------------------------------------------------------------- 1 | def _llvm_config_impl(ctx: AnalysisContext) -> list[Provider]: 2 | llvm = ctx.attrs.llvm[DefaultInfo].default_outputs[0] 3 | llvm_config = llvm.project("bin/llvm-config") 4 | return [ 5 | DefaultInfo(default_output = llvm_config), 6 | RunInfo(llvm_config), 7 | ] 8 | 9 | llvm_config = rule( 10 | impl = _llvm_config_impl, 11 | attrs = {"llvm": attrs.dep()}, 12 | ) 13 | 14 | def _rustc_cfg_llvm_component_impl( 15 | actions: AnalysisActions, 16 | llvm_config_components: ArtifactValue, 17 | output: OutputArtifact) -> list[Provider]: 18 | discard = set(["csky"]) # broken? 19 | 20 | cfg = [] 21 | for component in llvm_config_components.read_string().split(): 22 | if component not in discard: 23 | cfg.append("--cfg=llvm_component=\"{}\"\n".format(component)) 24 | 25 | actions.write(output, "".join(cfg)) 26 | return [] 27 | 28 | _rustc_cfg_llvm_component = dynamic_actions( 29 | impl = _rustc_cfg_llvm_component_impl, 30 | attrs = { 31 | "llvm_config_components": dynattrs.artifact_value(), 32 | "output": dynattrs.output(), 33 | }, 34 | ) 35 | 36 | def _llvm_rustc_flags_impl(ctx: AnalysisContext) -> list[Provider]: 37 | llvm_config_components = ctx.actions.declare_output("components") 38 | ctx.actions.run( 39 | [ 40 | ctx.attrs._redirect_stdout[RunInfo], 41 | llvm_config_components.as_output(), 42 | ctx.attrs.llvm_config[RunInfo], 43 | "--components", 44 | ], 45 | category = "llvm_config", 46 | ) 47 | 48 | rustc_flags = ctx.actions.declare_output("rustc-flags") 49 | ctx.actions.dynamic_output_new( 50 | _rustc_cfg_llvm_component( 51 | llvm_config_components = llvm_config_components, 52 | output = rustc_flags.as_output(), 53 | ), 54 | ) 55 | 56 | return [DefaultInfo(default_output = rustc_flags)] 57 | 58 | llvm_rustc_flags = rule( 59 | impl = _llvm_rustc_flags_impl, 60 | attrs = { 61 | "llvm_config": attrs.dep(providers = [RunInfo]), 62 | "_redirect_stdout": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "prelude//rust/tools:redirect_stdout")), 63 | }, 64 | ) 65 | 66 | def _cxx_flags_impl( 67 | actions: AnalysisActions, 68 | llvm_config_cxxflags: ArtifactValue, 69 | output: OutputArtifact) -> list[Provider]: 70 | flags = [] 71 | for flag in llvm_config_cxxflags.read_string().split(): 72 | if flag.startswith("-std=") or flag.startswith("-stdlib=") or flag.startswith("-f"): 73 | flags.append(flag + "\n") 74 | elif not (flag.startswith("-I") or flag.startswith("-D")): 75 | fail("unrecognized llvm flag:", repr(flag)) 76 | actions.write(output, "".join(flags)) 77 | return [] 78 | 79 | _cxx_flags = dynamic_actions( 80 | impl = _cxx_flags_impl, 81 | attrs = { 82 | "llvm_config_cxxflags": dynattrs.artifact_value(), 83 | "output": dynattrs.output(), 84 | }, 85 | ) 86 | 87 | def _llvm_cxx_flags_impl(ctx: AnalysisContext) -> list[Provider]: 88 | llvm_config_cxxflags = ctx.actions.declare_output("cxxflags") 89 | ctx.actions.run( 90 | [ 91 | ctx.attrs._redirect_stdout[RunInfo], 92 | llvm_config_cxxflags.as_output(), 93 | ctx.attrs.llvm_config[RunInfo], 94 | "--cxxflags", 95 | ], 96 | category = "llvm_config", 97 | ) 98 | 99 | cxx_flags = ctx.actions.declare_output("cxx-flags") 100 | ctx.actions.dynamic_output_new( 101 | _cxx_flags( 102 | llvm_config_cxxflags = llvm_config_cxxflags, 103 | output = cxx_flags.as_output(), 104 | ), 105 | ) 106 | 107 | return [DefaultInfo(default_output = cxx_flags)] 108 | 109 | llvm_cxx_flags = rule( 110 | impl = _llvm_cxx_flags_impl, 111 | attrs = { 112 | "llvm_config": attrs.dep(providers = [RunInfo]), 113 | "_redirect_stdout": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "prelude//rust/tools:redirect_stdout")), 114 | }, 115 | ) 116 | 117 | def _preprocessor_flags_impl( 118 | actions: AnalysisActions, 119 | llvm_config_cxxflags: ArtifactValue, 120 | output: OutputArtifact) -> list[Provider]: 121 | flags = [] 122 | for flag in llvm_config_cxxflags.read_string().split(): 123 | if flag.startswith("-D"): 124 | flags.append(flag + "\n") 125 | actions.write(output, "".join(flags)) 126 | return [] 127 | 128 | _preprocessor_flags = dynamic_actions( 129 | impl = _preprocessor_flags_impl, 130 | attrs = { 131 | "llvm_config_cxxflags": dynattrs.artifact_value(), 132 | "output": dynattrs.output(), 133 | }, 134 | ) 135 | 136 | def _llvm_preprocessor_flags_impl(ctx: AnalysisContext) -> list[Provider]: 137 | llvm_config_cxxflags = ctx.actions.declare_output("cxxflags") 138 | ctx.actions.run( 139 | [ 140 | ctx.attrs._redirect_stdout[RunInfo], 141 | llvm_config_cxxflags.as_output(), 142 | ctx.attrs.llvm_config[RunInfo], 143 | "--cxxflags", 144 | ], 145 | category = "llvm_config", 146 | ) 147 | 148 | preprocessor_flags = ctx.actions.declare_output("preprocessor-flags") 149 | ctx.actions.dynamic_output_new( 150 | _preprocessor_flags( 151 | llvm_config_cxxflags = llvm_config_cxxflags, 152 | output = preprocessor_flags.as_output(), 153 | ), 154 | ) 155 | 156 | return [DefaultInfo(default_output = preprocessor_flags)] 157 | 158 | llvm_preprocessor_flags = rule( 159 | impl = _llvm_preprocessor_flags_impl, 160 | attrs = { 161 | "llvm_config": attrs.dep(providers = [RunInfo]), 162 | "_redirect_stdout": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "prelude//rust/tools:redirect_stdout")), 163 | }, 164 | ) 165 | 166 | def _linker_flags_impl( 167 | actions: AnalysisActions, 168 | llvm_config_libs: ArtifactValue, 169 | output: OutputArtifact) -> list[Provider]: 170 | flags = [] 171 | for flag in llvm_config_libs.read_string().split(): 172 | flags.append(flag + "\n") 173 | actions.write(output, "".join(flags)) 174 | return [] 175 | 176 | _linker_flags = dynamic_actions( 177 | impl = _linker_flags_impl, 178 | attrs = { 179 | "llvm_config_libs": dynattrs.artifact_value(), 180 | "output": dynattrs.output(), 181 | }, 182 | ) 183 | 184 | def _llvm_linker_flags_impl(ctx: AnalysisContext) -> list[Provider]: 185 | llvm_config_libs = ctx.actions.declare_output("libs") 186 | ctx.actions.run( 187 | [ 188 | ctx.attrs._redirect_stdout[RunInfo], 189 | llvm_config_libs.as_output(), 190 | ctx.attrs.llvm_config[RunInfo], 191 | "--libs", 192 | ], 193 | category = "llvm_config", 194 | ) 195 | 196 | linker_flags = ctx.actions.declare_output("linker-flags") 197 | ctx.actions.dynamic_output_new( 198 | _linker_flags( 199 | llvm_config_libs = llvm_config_libs, 200 | output = linker_flags.as_output(), 201 | ), 202 | ) 203 | 204 | return [DefaultInfo(default_output = linker_flags)] 205 | 206 | llvm_linker_flags = rule( 207 | impl = _llvm_linker_flags_impl, 208 | attrs = { 209 | "llvm_config": attrs.dep(providers = [RunInfo]), 210 | "_redirect_stdout": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "prelude//rust/tools:redirect_stdout")), 211 | }, 212 | ) 213 | -------------------------------------------------------------------------------- /fixups/rustc_llvm/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | rustc_flags = ["@$(location //fixups/rustc_llvm:rustc-flags)"] 3 | 4 | [[cxx_library]] 5 | name = "llvm-wrapper" 6 | srcs = ["llvm-wrapper/*.cpp"] 7 | headers = ["llvm-wrapper/*.h"] 8 | compiler_flags = [ 9 | "--config=$(location //fixups/rustc_llvm:cxx-flags)", 10 | ] 11 | preprocessor_flags = [ 12 | "-I$(location //stage0:ci_llvm)/include", 13 | "--config=$(location //fixups/rustc_llvm:preprocessor-flags)", 14 | ] 15 | deps = ["//fixups/rustc_llvm:llvm"] 16 | preferred_linkage = "static" 17 | -------------------------------------------------------------------------------- /fixups/rustc_log/fixups.toml: -------------------------------------------------------------------------------- 1 | overlay = "overlay" # https://github.com/rust-lang/rust/pull/140627 2 | -------------------------------------------------------------------------------- /fixups/rustc_log/overlay/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate allows tools to enable rust logging without having to magically 2 | //! match rustc's tracing crate version. 3 | //! 4 | //! For example if someone is working on rustc_ast and wants to write some 5 | //! minimal code against it to run in a debugger, with access to the `debug!` 6 | //! logs emitted by rustc_ast, that can be done by writing: 7 | //! 8 | //! ```toml 9 | //! [dependencies] 10 | //! rustc_ast = { path = "../rust/compiler/rustc_ast" } 11 | //! rustc_log = { path = "../rust/compiler/rustc_log" } 12 | //! rustc_span = { path = "../rust/compiler/rustc_span" } 13 | //! ``` 14 | //! 15 | //! ``` 16 | //! fn main() { 17 | //! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap(); 18 | //! 19 | //! let edition = rustc_span::edition::Edition::Edition2021; 20 | //! rustc_span::create_session_globals_then(edition, None, || { 21 | //! /* ... */ 22 | //! }); 23 | //! } 24 | //! ``` 25 | //! 26 | //! Now `LOG=debug cargo +nightly run` will run your minimal main.rs and show 27 | //! rustc's debug logging. In a workflow like this, one might also add 28 | //! `std::env::set_var("LOG", "debug")` to the top of main so that `cargo 29 | //! +nightly run` by itself is sufficient to get logs. 30 | //! 31 | //! The reason rustc_log is a tiny separate crate, as opposed to exposing the 32 | //! same things in rustc_driver only, is to enable the above workflow. If you 33 | //! had to depend on rustc_driver in order to turn on rustc's debug logs, that's 34 | //! an enormously bigger dependency tree; every change you make to rustc_ast (or 35 | //! whichever piece of the compiler you are interested in) would involve 36 | //! rebuilding all the rest of rustc up to rustc_driver in order to run your 37 | //! main.rs. Whereas by depending only on rustc_log and the few crates you are 38 | //! debugging, you can make changes inside those crates and quickly run main.rs 39 | //! to read the debug logs. 40 | 41 | use std::env::{self, VarError}; 42 | use std::fmt::{self, Display}; 43 | use std::io::{self, IsTerminal}; 44 | 45 | use tracing::dispatcher::SetGlobalDefaultError; 46 | use tracing_core::{Event, Subscriber}; 47 | use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter}; 48 | use tracing_subscriber::fmt::FmtContext; 49 | use tracing_subscriber::fmt::format::{self, FormatEvent, FormatFields}; 50 | use tracing_subscriber::layer::SubscriberExt; 51 | 52 | /// The values of all the environment variables that matter for configuring a logger. 53 | /// Errors are explicitly preserved so that we can share error handling. 54 | pub struct LoggerConfig { 55 | pub filter: Result, 56 | pub color_logs: Result, 57 | pub verbose_entry_exit: Result, 58 | pub verbose_thread_ids: Result, 59 | pub backtrace: Result, 60 | pub wraptree: Result, 61 | pub lines: Result, 62 | } 63 | 64 | impl LoggerConfig { 65 | pub fn from_env(env: &str) -> Self { 66 | LoggerConfig { 67 | filter: env::var(env), 68 | color_logs: env::var(format!("{env}_COLOR")), 69 | verbose_entry_exit: env::var(format!("{env}_ENTRY_EXIT")), 70 | verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")), 71 | backtrace: env::var(format!("{env}_BACKTRACE")), 72 | wraptree: env::var(format!("{env}_WRAPTREE")), 73 | lines: env::var(format!("{env}_LINES")), 74 | } 75 | } 76 | } 77 | 78 | /// Initialize the logger with the given values for the filter, coloring, and other options env variables. 79 | pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { 80 | let filter = match cfg.filter { 81 | Ok(env) => EnvFilter::new(env), 82 | _ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)), 83 | }; 84 | 85 | let color_logs = match cfg.color_logs { 86 | Ok(value) => match value.as_ref() { 87 | "always" => true, 88 | "never" => false, 89 | "auto" => stderr_isatty(), 90 | _ => return Err(Error::InvalidColorValue(value)), 91 | }, 92 | Err(VarError::NotPresent) => stderr_isatty(), 93 | Err(VarError::NotUnicode(_value)) => return Err(Error::NonUnicodeColorValue), 94 | }; 95 | 96 | let verbose_entry_exit = match cfg.verbose_entry_exit { 97 | Ok(v) => &v != "0", 98 | Err(_) => false, 99 | }; 100 | 101 | let verbose_thread_ids = match cfg.verbose_thread_ids { 102 | Ok(v) => &v == "1", 103 | Err(_) => false, 104 | }; 105 | 106 | let lines = match cfg.lines { 107 | Ok(v) => &v == "1", 108 | Err(_) => false, 109 | }; 110 | 111 | let mut layer = tracing_tree::HierarchicalLayer::default() 112 | .with_writer(io::stderr) 113 | .with_ansi(color_logs) 114 | .with_targets(true) 115 | .with_verbose_exit(verbose_entry_exit) 116 | .with_verbose_entry(verbose_entry_exit) 117 | .with_indent_amount(2) 118 | .with_indent_lines(lines) 119 | .with_thread_ids(verbose_thread_ids) 120 | .with_thread_names(verbose_thread_ids); 121 | 122 | match cfg.wraptree { 123 | Ok(v) => match v.parse::() { 124 | Ok(v) => { 125 | layer = layer.with_wraparound(v); 126 | } 127 | Err(_) => return Err(Error::InvalidWraptree(v)), 128 | }, 129 | Err(_) => {} // no wraptree 130 | } 131 | 132 | let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); 133 | match cfg.backtrace { 134 | Ok(backtrace_target) => { 135 | let fmt_layer = tracing_subscriber::fmt::layer() 136 | .with_writer(io::stderr) 137 | .without_time() 138 | .event_format(BacktraceFormatter { backtrace_target }); 139 | let subscriber = subscriber.with(fmt_layer); 140 | tracing::subscriber::set_global_default(subscriber)?; 141 | } 142 | Err(_) => { 143 | tracing::subscriber::set_global_default(subscriber)?; 144 | } 145 | }; 146 | 147 | Ok(()) 148 | } 149 | 150 | struct BacktraceFormatter { 151 | backtrace_target: String, 152 | } 153 | 154 | impl FormatEvent for BacktraceFormatter 155 | where 156 | S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>, 157 | N: for<'a> FormatFields<'a> + 'static, 158 | { 159 | fn format_event( 160 | &self, 161 | _ctx: &FmtContext<'_, S, N>, 162 | mut writer: format::Writer<'_>, 163 | event: &Event<'_>, 164 | ) -> fmt::Result { 165 | let target = event.metadata().target(); 166 | if !target.contains(&self.backtrace_target) { 167 | return Ok(()); 168 | } 169 | // Use Backtrace::force_capture because we don't want to depend on the 170 | // RUST_BACKTRACE environment variable being set. 171 | let backtrace = std::backtrace::Backtrace::force_capture(); 172 | writeln!(writer, "stack backtrace: \n{backtrace:?}") 173 | } 174 | } 175 | 176 | pub fn stdout_isatty() -> bool { 177 | io::stdout().is_terminal() 178 | } 179 | 180 | pub fn stderr_isatty() -> bool { 181 | io::stderr().is_terminal() 182 | } 183 | 184 | #[derive(Debug)] 185 | pub enum Error { 186 | InvalidColorValue(String), 187 | NonUnicodeColorValue, 188 | InvalidWraptree(String), 189 | AlreadyInit(SetGlobalDefaultError), 190 | } 191 | 192 | impl std::error::Error for Error {} 193 | 194 | impl Display for Error { 195 | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 196 | match self { 197 | Error::InvalidColorValue(value) => write!( 198 | formatter, 199 | "invalid log color value '{value}': expected one of always, never, or auto", 200 | ), 201 | Error::NonUnicodeColorValue => write!( 202 | formatter, 203 | "non-Unicode log color value: expected one of always, never, or auto", 204 | ), 205 | Error::InvalidWraptree(value) => write!( 206 | formatter, 207 | "invalid log WRAPTREE value '{value}': expected a non-negative integer", 208 | ), 209 | Error::AlreadyInit(tracing_error) => Display::fmt(tracing_error, formatter), 210 | } 211 | } 212 | } 213 | 214 | impl From for Error { 215 | fn from(tracing_error: SetGlobalDefaultError) -> Self { 216 | Error::AlreadyInit(tracing_error) 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /fixups/rustc_macros/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/rustc_target/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_srcs = ["src/spec/targets/*.ld"] 2 | -------------------------------------------------------------------------------- /fixups/rustdoc-tool/fixups.toml: -------------------------------------------------------------------------------- 1 | linker_flags = ["-Wl,-rpath,$ORIGIN/../lib"] 2 | -------------------------------------------------------------------------------- /fixups/rustdoc/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | cargo_env = ["CARGO_MANIFEST_DIR"] 3 | extra_deps = [ 4 | "toolchains//rust:sysroot[test]", 5 | ":pulldown-cmark-0.11.3", 6 | ":rustc_abi-0.0.0", 7 | ":rustc_ast-0.0.0", 8 | ":rustc_ast_pretty-0.0.0", 9 | ":rustc_attr_parsing-0.0.0", 10 | ":rustc_data_structures-0.0.0", 11 | ":rustc_driver-0.0.0", 12 | ":rustc_errors-0.0.0", 13 | ":rustc_expand-0.0.0", 14 | ":rustc_feature-0.0.0", 15 | ":rustc_hir-0.0.0", 16 | ":rustc_hir_analysis-0.0.0", 17 | ":rustc_hir_pretty-0.0.0", 18 | ":rustc_index-0.0.0", 19 | ":rustc_infer-0.0.0", 20 | ":rustc_interface-0.0.0", 21 | ":rustc_lexer-0.0.0", 22 | ":rustc_lint-0.0.0", 23 | ":rustc_lint_defs-0.0.0", 24 | ":rustc_log-0.0.0", 25 | ":rustc_macros-0.0.0", 26 | ":rustc_metadata-0.0.0", 27 | ":rustc_middle-0.0.0", 28 | ":rustc_parse-0.0.0", 29 | ":rustc_passes-0.0.0", 30 | ":rustc_resolve-0.0.0", 31 | ":rustc_serialize-0.0.0", 32 | ":rustc_session-0.0.0", 33 | ":rustc_span-0.0.0", 34 | ":rustc_target-0.0.0", 35 | ":rustc_trait_selection-0.0.0", 36 | ":thin-vec-0.2.14", 37 | ] 38 | extra_srcs = [ 39 | "html/static/**", 40 | "html/templates/**/*.html", 41 | "rinja.toml", 42 | ] 43 | overlay = "overlay" # https://github.com/rust-lang/rust/pull/140627 44 | 45 | [env] 46 | DOC_RUST_LANG_ORG_CHANNEL = "https://doc.rust-lang.org/stable" 47 | -------------------------------------------------------------------------------- /fixups/rustdoc/overlay/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc( 2 | html_root_url = "https://doc.rust-lang.org/nightly/", 3 | html_playground_url = "https://play.rust-lang.org/" 4 | )] 5 | #![feature(rustc_private)] 6 | #![feature(assert_matches)] 7 | #![feature(box_patterns)] 8 | #![feature(debug_closure_helpers)] 9 | #![feature(file_buffered)] 10 | #![feature(format_args_nl)] 11 | #![feature(if_let_guard)] 12 | #![feature(impl_trait_in_assoc_type)] 13 | #![feature(iter_intersperse)] 14 | #![feature(let_chains)] 15 | #![feature(never_type)] 16 | #![feature(os_str_display)] 17 | #![feature(round_char_boundary)] 18 | #![feature(test)] 19 | #![feature(type_alias_impl_trait)] 20 | #![feature(type_ascription)] 21 | #![recursion_limit = "256"] 22 | #![warn(rustc::internal)] 23 | #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] 24 | #![allow(rustc::diagnostic_outside_of_impl)] 25 | #![allow(rustc::untranslatable_diagnostic)] 26 | 27 | extern crate thin_vec; 28 | 29 | // N.B. these need `extern crate` even in 2018 edition 30 | // because they're loaded implicitly from the sysroot. 31 | // The reason they're loaded from the sysroot is because 32 | // the rustdoc artifacts aren't stored in rustc's cargo target directory. 33 | // So if `rustc` was specified in Cargo.toml, this would spuriously rebuild crates. 34 | // 35 | // Dependencies listed in Cargo.toml do not need `extern crate`. 36 | 37 | extern crate pulldown_cmark; 38 | extern crate rustc_abi; 39 | extern crate rustc_ast; 40 | extern crate rustc_ast_pretty; 41 | extern crate rustc_attr_parsing; 42 | extern crate rustc_data_structures; 43 | extern crate rustc_driver; 44 | extern crate rustc_errors; 45 | extern crate rustc_expand; 46 | extern crate rustc_feature; 47 | extern crate rustc_hir; 48 | extern crate rustc_hir_analysis; 49 | extern crate rustc_hir_pretty; 50 | extern crate rustc_index; 51 | extern crate rustc_infer; 52 | extern crate rustc_interface; 53 | extern crate rustc_lexer; 54 | extern crate rustc_lint; 55 | extern crate rustc_lint_defs; 56 | extern crate rustc_log; 57 | extern crate rustc_macros; 58 | extern crate rustc_metadata; 59 | extern crate rustc_middle; 60 | extern crate rustc_parse; 61 | extern crate rustc_passes; 62 | extern crate rustc_resolve; 63 | extern crate rustc_serialize; 64 | extern crate rustc_session; 65 | extern crate rustc_span; 66 | extern crate rustc_target; 67 | extern crate rustc_trait_selection; 68 | extern crate test; 69 | 70 | // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs 71 | // about jemalloc. 72 | #[cfg(feature = "jemalloc")] 73 | extern crate tikv_jemalloc_sys as jemalloc_sys; 74 | 75 | use std::env::{self, VarError}; 76 | use std::io::{self, IsTerminal}; 77 | use std::process; 78 | 79 | use rustc_errors::DiagCtxtHandle; 80 | use rustc_interface::interface; 81 | use rustc_middle::ty::TyCtxt; 82 | use rustc_session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option}; 83 | use rustc_session::{EarlyDiagCtxt, getopts}; 84 | use tracing::info; 85 | 86 | use crate::clean::utils::DOC_RUST_LANG_ORG_VERSION; 87 | 88 | /// A macro to create a FxHashMap. 89 | /// 90 | /// Example: 91 | /// 92 | /// ```ignore(cannot-test-this-because-non-exported-macro) 93 | /// let letters = map!{"a" => "b", "c" => "d"}; 94 | /// ``` 95 | /// 96 | /// Trailing commas are allowed. 97 | /// Commas between elements are required (even if the expression is a block). 98 | macro_rules! map { 99 | ($( $key: expr => $val: expr ),* $(,)*) => {{ 100 | let mut map = ::rustc_data_structures::fx::FxIndexMap::default(); 101 | $( map.insert($key, $val); )* 102 | map 103 | }} 104 | } 105 | 106 | mod clean; 107 | mod config; 108 | mod core; 109 | mod display; 110 | mod docfs; 111 | mod doctest; 112 | mod error; 113 | mod externalfiles; 114 | mod fold; 115 | mod formats; 116 | // used by the error-index generator, so it needs to be public 117 | pub mod html; 118 | mod json; 119 | pub(crate) mod lint; 120 | mod markdown; 121 | mod passes; 122 | mod scrape_examples; 123 | mod theme; 124 | mod visit; 125 | mod visit_ast; 126 | mod visit_lib; 127 | 128 | pub fn main() { 129 | // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs 130 | // about jemalloc. 131 | #[cfg(feature = "jemalloc")] 132 | { 133 | use std::os::raw::{c_int, c_void}; 134 | 135 | #[used] 136 | static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; 137 | #[used] 138 | static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = 139 | jemalloc_sys::posix_memalign; 140 | #[used] 141 | static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; 142 | #[used] 143 | static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; 144 | #[used] 145 | static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; 146 | #[used] 147 | static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; 148 | 149 | #[cfg(target_os = "macos")] 150 | { 151 | extern "C" { 152 | fn _rjem_je_zone_register(); 153 | } 154 | 155 | #[used] 156 | static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; 157 | } 158 | } 159 | 160 | let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); 161 | 162 | rustc_driver::install_ice_hook( 163 | "https://github.com/rust-lang/rust/issues/new\ 164 | ?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md", 165 | |_| (), 166 | ); 167 | 168 | // When using CI artifacts with `download-rustc`, tracing is unconditionally built 169 | // with `--features=static_max_level_info`, which disables almost all rustdoc logging. To avoid 170 | // this, compile our own version of `tracing` that logs all levels. 171 | // NOTE: this compiles both versions of tracing unconditionally, because 172 | // - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and 173 | // - Otherwise, there's no warning that logging is being ignored when `download-rustc` is enabled 174 | // NOTE: The reason this doesn't show double logging when `download-rustc = false` and 175 | // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one 176 | // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml). 177 | 178 | init_logging(&early_dcx); 179 | match rustc_log::init_logger(rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")) { 180 | Ok(()) => {} 181 | Err(rustc_log::Error::AlreadyInit(_)) => {} 182 | Err(error) => early_dcx.early_fatal(error.to_string()), 183 | } 184 | 185 | let exit_code = rustc_driver::catch_with_exit_code(|| { 186 | let at_args = rustc_driver::args::raw_args(&early_dcx); 187 | main_args(&mut early_dcx, &at_args); 188 | }); 189 | process::exit(exit_code); 190 | } 191 | 192 | fn init_logging(early_dcx: &EarlyDiagCtxt) { 193 | let color_logs = match env::var("RUSTDOC_LOG_COLOR").as_deref() { 194 | Ok("always") => true, 195 | Ok("never") => false, 196 | Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(), 197 | Ok(value) => early_dcx.early_fatal(format!( 198 | "invalid log color value '{value}': expected one of always, never, or auto", 199 | )), 200 | Err(VarError::NotUnicode(value)) => early_dcx.early_fatal(format!( 201 | "invalid log color value '{}': expected one of always, never, or auto", 202 | value.to_string_lossy() 203 | )), 204 | }; 205 | let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG"); 206 | let layer = tracing_tree::HierarchicalLayer::default() 207 | .with_writer(io::stderr) 208 | .with_ansi(color_logs) 209 | .with_targets(true) 210 | .with_wraparound(10) 211 | .with_verbose_exit(true) 212 | .with_verbose_entry(true) 213 | .with_indent_amount(2); 214 | #[cfg(debug_assertions)] 215 | let layer = layer.with_thread_ids(true).with_thread_names(true); 216 | 217 | use tracing_subscriber::layer::SubscriberExt; 218 | let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); 219 | tracing::subscriber::set_global_default(subscriber).unwrap(); 220 | } 221 | 222 | fn opts() -> Vec { 223 | use rustc_session::config::OptionKind::{Flag, FlagMulti, Multi, Opt}; 224 | use rustc_session::config::OptionStability::{Stable, Unstable}; 225 | use rustc_session::config::make_opt as opt; 226 | 227 | vec![ 228 | opt(Stable, FlagMulti, "h", "help", "show this help message", ""), 229 | opt(Stable, FlagMulti, "V", "version", "print rustdoc's version", ""), 230 | opt(Stable, FlagMulti, "v", "verbose", "use verbose output", ""), 231 | opt(Stable, Opt, "w", "output-format", "the output type to write", "[html]"), 232 | opt( 233 | Stable, 234 | Opt, 235 | "", 236 | "output", 237 | "Which directory to place the output. This option is deprecated, use --out-dir instead.", 238 | "PATH", 239 | ), 240 | opt(Stable, Opt, "o", "out-dir", "which directory to place the output", "PATH"), 241 | opt(Stable, Opt, "", "crate-name", "specify the name of this crate", "NAME"), 242 | make_crate_type_option(), 243 | opt(Stable, Multi, "L", "library-path", "directory to add to crate search path", "DIR"), 244 | opt(Stable, Multi, "", "cfg", "pass a --cfg to rustc", ""), 245 | opt(Stable, Multi, "", "check-cfg", "pass a --check-cfg to rustc", ""), 246 | opt(Stable, Multi, "", "extern", "pass an --extern to rustc", "NAME[=PATH]"), 247 | opt( 248 | Unstable, 249 | Multi, 250 | "", 251 | "extern-html-root-url", 252 | "base URL to use for dependencies; for example, \ 253 | \"std=/doc\" links std::vec::Vec to /doc/std/vec/struct.Vec.html", 254 | "NAME=URL", 255 | ), 256 | opt( 257 | Unstable, 258 | FlagMulti, 259 | "", 260 | "extern-html-root-takes-precedence", 261 | "give precedence to `--extern-html-root-url`, not `html_root_url`", 262 | "", 263 | ), 264 | opt(Stable, Multi, "C", "codegen", "pass a codegen option to rustc", "OPT[=VALUE]"), 265 | opt(Stable, FlagMulti, "", "document-private-items", "document private items", ""), 266 | opt( 267 | Unstable, 268 | FlagMulti, 269 | "", 270 | "document-hidden-items", 271 | "document items that have doc(hidden)", 272 | "", 273 | ), 274 | opt(Stable, FlagMulti, "", "test", "run code examples as tests", ""), 275 | opt(Stable, Multi, "", "test-args", "arguments to pass to the test runner", "ARGS"), 276 | opt( 277 | Stable, 278 | Opt, 279 | "", 280 | "test-run-directory", 281 | "The working directory in which to run tests", 282 | "PATH", 283 | ), 284 | opt(Stable, Opt, "", "target", "target triple to document", "TRIPLE"), 285 | opt( 286 | Stable, 287 | Multi, 288 | "", 289 | "markdown-css", 290 | "CSS files to include via in a rendered Markdown file", 291 | "FILES", 292 | ), 293 | opt( 294 | Stable, 295 | Multi, 296 | "", 297 | "html-in-header", 298 | "files to include inline in the section of a rendered Markdown file \ 299 | or generated documentation", 300 | "FILES", 301 | ), 302 | opt( 303 | Stable, 304 | Multi, 305 | "", 306 | "html-before-content", 307 | "files to include inline between and the content of a rendered \ 308 | Markdown file or generated documentation", 309 | "FILES", 310 | ), 311 | opt( 312 | Stable, 313 | Multi, 314 | "", 315 | "html-after-content", 316 | "files to include inline between the content and of a rendered \ 317 | Markdown file or generated documentation", 318 | "FILES", 319 | ), 320 | opt( 321 | Unstable, 322 | Multi, 323 | "", 324 | "markdown-before-content", 325 | "files to include inline between and the content of a rendered \ 326 | Markdown file or generated documentation", 327 | "FILES", 328 | ), 329 | opt( 330 | Unstable, 331 | Multi, 332 | "", 333 | "markdown-after-content", 334 | "files to include inline between the content and of a rendered \ 335 | Markdown file or generated documentation", 336 | "FILES", 337 | ), 338 | opt(Stable, Opt, "", "markdown-playground-url", "URL to send code snippets to", "URL"), 339 | opt(Stable, FlagMulti, "", "markdown-no-toc", "don't include table of contents", ""), 340 | opt( 341 | Stable, 342 | Opt, 343 | "e", 344 | "extend-css", 345 | "To add some CSS rules with a given file to generate doc with your own theme. \ 346 | However, your theme might break if the rustdoc's generated HTML changes, so be careful!", 347 | "PATH", 348 | ), 349 | opt( 350 | Unstable, 351 | Multi, 352 | "Z", 353 | "", 354 | "unstable / perma-unstable options (only on nightly build)", 355 | "FLAG", 356 | ), 357 | opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"), 358 | opt( 359 | Unstable, 360 | Opt, 361 | "", 362 | "playground-url", 363 | "URL to send code snippets to, may be reset by --markdown-playground-url \ 364 | or `#![doc(html_playground_url=...)]`", 365 | "URL", 366 | ), 367 | opt( 368 | Unstable, 369 | FlagMulti, 370 | "", 371 | "display-doctest-warnings", 372 | "show warnings that originate in doctests", 373 | "", 374 | ), 375 | opt( 376 | Stable, 377 | Opt, 378 | "", 379 | "crate-version", 380 | "crate version to print into documentation", 381 | "VERSION", 382 | ), 383 | opt( 384 | Unstable, 385 | FlagMulti, 386 | "", 387 | "sort-modules-by-appearance", 388 | "sort modules by where they appear in the program, rather than alphabetically", 389 | "", 390 | ), 391 | opt( 392 | Stable, 393 | Opt, 394 | "", 395 | "default-theme", 396 | "Set the default theme. THEME should be the theme name, generally lowercase. \ 397 | If an unknown default theme is specified, the builtin default is used. \ 398 | The set of themes, and the rustdoc built-in default, are not stable.", 399 | "THEME", 400 | ), 401 | opt( 402 | Unstable, 403 | Multi, 404 | "", 405 | "default-setting", 406 | "Default value for a rustdoc setting (used when \"rustdoc-SETTING\" is absent \ 407 | from web browser Local Storage). If VALUE is not supplied, \"true\" is used. \ 408 | Supported SETTINGs and VALUEs are not documented and not stable.", 409 | "SETTING[=VALUE]", 410 | ), 411 | opt( 412 | Stable, 413 | Multi, 414 | "", 415 | "theme", 416 | "additional themes which will be added to the generated docs", 417 | "FILES", 418 | ), 419 | opt(Stable, Multi, "", "check-theme", "check if given theme is valid", "FILES"), 420 | opt( 421 | Unstable, 422 | Opt, 423 | "", 424 | "resource-suffix", 425 | "suffix to add to CSS and JavaScript files, \ 426 | e.g., \"search-index.js\" will become \"search-index-suffix.js\"", 427 | "PATH", 428 | ), 429 | opt( 430 | Stable, 431 | Opt, 432 | "", 433 | "edition", 434 | "edition to use when compiling rust code (default: 2015)", 435 | "EDITION", 436 | ), 437 | opt( 438 | Stable, 439 | Opt, 440 | "", 441 | "color", 442 | "Configure coloring of output: 443 | auto = colorize, if output goes to a tty (default); 444 | always = always colorize output; 445 | never = never colorize output", 446 | "auto|always|never", 447 | ), 448 | opt( 449 | Stable, 450 | Opt, 451 | "", 452 | "error-format", 453 | "How errors and other messages are produced", 454 | "human|json|short", 455 | ), 456 | opt( 457 | Stable, 458 | Opt, 459 | "", 460 | "diagnostic-width", 461 | "Provide width of the output for truncated error messages", 462 | "WIDTH", 463 | ), 464 | opt(Stable, Opt, "", "json", "Configure the structure of JSON diagnostics", "CONFIG"), 465 | opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"), 466 | opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"), 467 | opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"), 468 | opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"), 469 | opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"), 470 | opt( 471 | Stable, 472 | Multi, 473 | "", 474 | "cap-lints", 475 | "Set the most restrictive lint level. \ 476 | More restrictive lints are capped at this level. \ 477 | By default, it is at `forbid` level.", 478 | "LEVEL", 479 | ), 480 | opt(Unstable, Opt, "", "index-page", "Markdown file to be used as index page", "PATH"), 481 | opt( 482 | Unstable, 483 | FlagMulti, 484 | "", 485 | "enable-index-page", 486 | "To enable generation of the index page", 487 | "", 488 | ), 489 | opt( 490 | Unstable, 491 | Opt, 492 | "", 493 | "static-root-path", 494 | "Path string to force loading static files from in output pages. \ 495 | If not set, uses combinations of '../' to reach the documentation root.", 496 | "PATH", 497 | ), 498 | opt( 499 | Unstable, 500 | Opt, 501 | "", 502 | "persist-doctests", 503 | "Directory to persist doctest executables into", 504 | "PATH", 505 | ), 506 | opt( 507 | Unstable, 508 | FlagMulti, 509 | "", 510 | "show-coverage", 511 | "calculate percentage of public items with documentation", 512 | "", 513 | ), 514 | opt( 515 | Unstable, 516 | FlagMulti, 517 | "", 518 | "enable-per-target-ignores", 519 | "parse ignore-foo for ignoring doctests on a per-target basis", 520 | "", 521 | ), 522 | opt( 523 | Unstable, 524 | Opt, 525 | "", 526 | "runtool", 527 | "", 528 | "The tool to run tests with when building for a different target than host", 529 | ), 530 | opt( 531 | Unstable, 532 | Multi, 533 | "", 534 | "runtool-arg", 535 | "", 536 | "One (of possibly many) arguments to pass to the runtool", 537 | ), 538 | opt( 539 | Unstable, 540 | Opt, 541 | "", 542 | "test-builder", 543 | "The rustc-like binary to use as the test builder", 544 | "PATH", 545 | ), 546 | opt( 547 | Unstable, 548 | Multi, 549 | "", 550 | "test-builder-wrapper", 551 | "Wrapper program to pass test-builder and arguments", 552 | "PATH", 553 | ), 554 | opt(Unstable, FlagMulti, "", "check", "Run rustdoc checks", ""), 555 | opt( 556 | Unstable, 557 | FlagMulti, 558 | "", 559 | "generate-redirect-map", 560 | "Generate JSON file at the top level instead of generating HTML redirection files", 561 | "", 562 | ), 563 | opt( 564 | Unstable, 565 | Multi, 566 | "", 567 | "emit", 568 | "Comma separated list of types of output for rustdoc to emit", 569 | "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]", 570 | ), 571 | opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""), 572 | opt( 573 | Unstable, 574 | Multi, 575 | "", 576 | "remap-path-prefix", 577 | "Remap source names in compiler messages", 578 | "FROM=TO", 579 | ), 580 | opt( 581 | Unstable, 582 | FlagMulti, 583 | "", 584 | "show-type-layout", 585 | "Include the memory layout of types in the docs", 586 | "", 587 | ), 588 | opt(Unstable, Flag, "", "nocapture", "Don't capture stdout and stderr of tests", ""), 589 | opt( 590 | Unstable, 591 | Flag, 592 | "", 593 | "generate-link-to-definition", 594 | "Make the identifiers in the HTML source code pages navigable", 595 | "", 596 | ), 597 | opt( 598 | Unstable, 599 | Opt, 600 | "", 601 | "scrape-examples-output-path", 602 | "", 603 | "collect function call information and output at the given path", 604 | ), 605 | opt( 606 | Unstable, 607 | Multi, 608 | "", 609 | "scrape-examples-target-crate", 610 | "", 611 | "collect function call information for functions from the target crate", 612 | ), 613 | opt(Unstable, Flag, "", "scrape-tests", "Include test code when scraping examples", ""), 614 | opt( 615 | Unstable, 616 | Multi, 617 | "", 618 | "with-examples", 619 | "", 620 | "path to function call information (for displaying examples in the documentation)", 621 | ), 622 | opt( 623 | Unstable, 624 | Opt, 625 | "", 626 | "merge", 627 | "Controls how rustdoc handles files from previously documented crates in the doc root\n\ 628 | none = Do not write cross-crate information to the --out-dir\n\ 629 | shared = Append current crate's info to files found in the --out-dir\n\ 630 | finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files", 631 | "none|shared|finalize", 632 | ), 633 | opt( 634 | Unstable, 635 | Opt, 636 | "", 637 | "parts-out-dir", 638 | "Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none", 639 | "path/to/doc.parts/", 640 | ), 641 | opt( 642 | Unstable, 643 | Multi, 644 | "", 645 | "include-parts-dir", 646 | "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize", 647 | "path/to/doc.parts/", 648 | ), 649 | opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), 650 | opt( 651 | Unstable, 652 | Multi, 653 | "", 654 | "doctest-compilation-args", 655 | "", 656 | "add arguments to be used when compiling doctests", 657 | ), 658 | opt( 659 | Unstable, 660 | FlagMulti, 661 | "", 662 | "disable-minification", 663 | "disable the minification of CSS/JS files (perma-unstable, do not use with cached files)", 664 | "", 665 | ), 666 | // deprecated / removed options 667 | opt( 668 | Stable, 669 | Multi, 670 | "", 671 | "plugin-path", 672 | "removed, see issue #44136 for more information", 673 | "DIR", 674 | ), 675 | opt( 676 | Stable, 677 | Multi, 678 | "", 679 | "passes", 680 | "removed, see issue #44136 for more information", 681 | "PASSES", 682 | ), 683 | opt( 684 | Stable, 685 | Multi, 686 | "", 687 | "plugins", 688 | "removed, see issue #44136 for more information", 689 | "PLUGINS", 690 | ), 691 | opt( 692 | Stable, 693 | FlagMulti, 694 | "", 695 | "no-defaults", 696 | "removed, see issue #44136 for more information", 697 | "", 698 | ), 699 | opt( 700 | Stable, 701 | Opt, 702 | "r", 703 | "input-format", 704 | "removed, see issue #44136 for more information", 705 | "[rust]", 706 | ), 707 | ] 708 | } 709 | 710 | fn usage(argv0: &str) { 711 | let mut options = getopts::Options::new(); 712 | for option in opts() { 713 | option.apply(&mut options); 714 | } 715 | println!("{}", options.usage(&format!("{argv0} [options] "))); 716 | println!(" @path Read newline separated options from `path`\n"); 717 | println!( 718 | "More information available at {DOC_RUST_LANG_ORG_VERSION}/rustdoc/what-is-rustdoc.html", 719 | ); 720 | } 721 | 722 | pub(crate) fn wrap_return(dcx: DiagCtxtHandle<'_>, res: Result<(), String>) { 723 | match res { 724 | Ok(()) => dcx.abort_if_errors(), 725 | Err(err) => dcx.fatal(err), 726 | } 727 | } 728 | 729 | fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( 730 | krate: clean::Crate, 731 | renderopts: config::RenderOptions, 732 | cache: formats::cache::Cache, 733 | tcx: TyCtxt<'tcx>, 734 | ) { 735 | match formats::run_format::(krate, renderopts, cache, tcx) { 736 | Ok(_) => tcx.dcx().abort_if_errors(), 737 | Err(e) => { 738 | let mut msg = 739 | tcx.dcx().struct_fatal(format!("couldn't generate documentation: {}", e.error)); 740 | let file = e.file.display().to_string(); 741 | if !file.is_empty() { 742 | msg.note(format!("failed to create or modify \"{file}\"")); 743 | } 744 | msg.emit(); 745 | } 746 | } 747 | } 748 | 749 | /// Renders and writes cross-crate info files, like the search index. This function exists so that 750 | /// we can run rustdoc without a crate root in the `--merge=finalize` mode. Cross-crate info files 751 | /// discovered via `--include-parts-dir` are combined and written to the doc root. 752 | fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> { 753 | assert!( 754 | opt.should_merge.write_rendered_cci, 755 | "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize" 756 | ); 757 | assert!( 758 | !opt.should_merge.read_rendered_cci, 759 | "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize" 760 | ); 761 | let crates = html::render::CrateInfo::read_many(&opt.include_parts_dir)?; 762 | let include_sources = !opt.html_no_source; 763 | html::render::write_not_crate_specific( 764 | &crates, 765 | &opt.output, 766 | &opt, 767 | &opt.themes, 768 | opt.extension_css.as_deref(), 769 | &opt.resource_suffix, 770 | include_sources, 771 | )?; 772 | Ok(()) 773 | } 774 | 775 | fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { 776 | // Throw away the first argument, the name of the binary. 777 | // In case of at_args being empty, as might be the case by 778 | // passing empty argument array to execve under some platforms, 779 | // just use an empty slice. 780 | // 781 | // This situation was possible before due to arg_expand_all being 782 | // called before removing the argument, enabling a crash by calling 783 | // the compiler with @empty_file as argv[0] and no more arguments. 784 | let at_args = at_args.get(1..).unwrap_or_default(); 785 | 786 | let args = rustc_driver::args::arg_expand_all(early_dcx, at_args); 787 | 788 | let mut options = getopts::Options::new(); 789 | for option in opts() { 790 | option.apply(&mut options); 791 | } 792 | let matches = match options.parse(&args) { 793 | Ok(m) => m, 794 | Err(err) => { 795 | early_dcx.early_fatal(err.to_string()); 796 | } 797 | }; 798 | 799 | // Note that we discard any distinction between different non-zero exit 800 | // codes from `from_matches` here. 801 | let (input, options, render_options) = 802 | match config::Options::from_matches(early_dcx, &matches, args) { 803 | Some(opts) => opts, 804 | None => return, 805 | }; 806 | 807 | let dcx = 808 | core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts); 809 | let dcx = dcx.handle(); 810 | 811 | let input = match input { 812 | config::InputMode::HasFile(input) => input, 813 | config::InputMode::NoInputMergeFinalize => { 814 | return wrap_return( 815 | dcx, 816 | run_merge_finalize(render_options) 817 | .map_err(|e| format!("could not write merged cross-crate info: {e}")), 818 | ); 819 | } 820 | }; 821 | 822 | let output_format = options.output_format; 823 | 824 | match ( 825 | options.should_test || output_format == config::OutputFormat::Doctest, 826 | config::markdown_input(&input), 827 | ) { 828 | (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), 829 | (true, None) => return doctest::run(dcx, input, options), 830 | (false, Some(md_input)) => { 831 | let md_input = md_input.to_owned(); 832 | let edition = options.edition; 833 | let config = core::create_config(input, options, &render_options); 834 | 835 | // `markdown::render` can invoke `doctest::make_test`, which 836 | // requires session globals and a thread pool, so we use 837 | // `run_compiler`. 838 | return wrap_return( 839 | dcx, 840 | interface::run_compiler(config, |_compiler| { 841 | markdown::render_and_write(&md_input, render_options, edition) 842 | }), 843 | ); 844 | } 845 | (false, None) => {} 846 | } 847 | 848 | // need to move these items separately because we lose them by the time the closure is called, 849 | // but we can't create the dcx ahead of time because it's not Send 850 | let show_coverage = options.show_coverage; 851 | let run_check = options.run_check; 852 | 853 | // First, parse the crate and extract all relevant information. 854 | info!("starting to run rustc"); 855 | 856 | // Interpret the input file as a rust source file, passing it through the 857 | // compiler all the way through the analysis passes. The rustdoc output is 858 | // then generated from the cleaned AST of the crate. This runs all the 859 | // plug/cleaning passes. 860 | let crate_version = options.crate_version.clone(); 861 | 862 | let scrape_examples_options = options.scrape_examples_options.clone(); 863 | let bin_crate = options.bin_crate; 864 | 865 | let config = core::create_config(input, options, &render_options); 866 | 867 | let registered_lints = config.register_lints.is_some(); 868 | 869 | interface::run_compiler(config, |compiler| { 870 | let sess = &compiler.sess; 871 | 872 | if sess.opts.describe_lints { 873 | rustc_driver::describe_lints(sess, registered_lints); 874 | return; 875 | } 876 | 877 | let krate = rustc_interface::passes::parse(sess); 878 | rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { 879 | if sess.dcx().has_errors().is_some() { 880 | sess.dcx().fatal("Compilation failed, aborting rustdoc"); 881 | } 882 | 883 | let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { 884 | core::run_global_ctxt(tcx, show_coverage, render_options, output_format) 885 | }); 886 | info!("finished with rustc"); 887 | 888 | if let Some(options) = scrape_examples_options { 889 | return scrape_examples::run(krate, render_opts, cache, tcx, options, bin_crate); 890 | } 891 | 892 | cache.crate_version = crate_version; 893 | 894 | if show_coverage { 895 | // if we ran coverage, bail early, we don't need to also generate docs at this point 896 | // (also we didn't load in any of the useful passes) 897 | return; 898 | } else if run_check { 899 | // Since we're in "check" mode, no need to generate anything beyond this point. 900 | return; 901 | } 902 | 903 | info!("going to format"); 904 | match output_format { 905 | config::OutputFormat::Html => sess.time("render_html", || { 906 | run_renderer::>(krate, render_opts, cache, tcx) 907 | }), 908 | config::OutputFormat::Json => sess.time("render_json", || { 909 | run_renderer::>(krate, render_opts, cache, tcx) 910 | }), 911 | // Already handled above with doctest runners. 912 | config::OutputFormat::Doctest => unreachable!(), 913 | } 914 | }) 915 | }) 916 | } 917 | -------------------------------------------------------------------------------- /fixups/rustix/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/semver/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/serde/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/serde_json/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/stacker/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | 3 | [['cfg(target_os = "windows")'.cxx_library]] 4 | name = "windows" 5 | srcs = ["src/arch/windows.c"] 6 | compiler_flags = ["-DWINDOWS"] 7 | -------------------------------------------------------------------------------- /fixups/std/fixups.toml: -------------------------------------------------------------------------------- 1 | extra_srcs = [ 2 | "../backtrace/src/**/*.rs", 3 | "../core/src/error.md", 4 | "../core/src/ffi/*.md", 5 | "../core/src/primitive_docs.rs", 6 | "../core/src/macros/panic.md", 7 | "../portable-simd/crates/core_simd/src/core_simd_docs.md", 8 | "../portable-simd/crates/std_float/**/*.rs", 9 | "../stdarch/crates/core_arch/src/core_arch_docs.md", 10 | ] 11 | 12 | buildscript.run = false 13 | cfgs = ["backtrace_in_libstd"] 14 | rustc_flags = ["-Zforce-unstable-if-unmarked"] 15 | preferred_linkage = "any" 16 | 17 | ['cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "x86_64"))'] 18 | env = { "STD_ENV_ARCH" = "x86_64" } 19 | omit_deps = ["panic_abort"] 20 | extra_deps = [":panic_unwind-0.0.0"] 21 | 22 | ['cfg(all(any(target_os = "linux", target_os = "macos"), target_arch = "aarch64"))'] 23 | env = { "STD_ENV_ARCH" = "aarch64" } 24 | omit_deps = ["panic_abort"] 25 | extra_deps = [":panic_unwind-0.0.0"] 26 | 27 | ['cfg(windows)'] 28 | env = { "STD_ENV_ARCH" = "x86_64" } 29 | omit_deps = ["panic_abort"] 30 | extra_deps = [":panic_unwind-0.0.0"] 31 | -------------------------------------------------------------------------------- /fixups/thiserror/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/tracing/fixups.toml: -------------------------------------------------------------------------------- 1 | features = [ 2 | "max_level_off", 3 | "release_max_level_off", 4 | ] 5 | -------------------------------------------------------------------------------- /fixups/typenum/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/wasmparser/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = true 2 | -------------------------------------------------------------------------------- /fixups/winapi-x86_64-pc-windows-gnu/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | 3 | [['cfg(target_os = "windows")'.prebuilt_cxx_library]] 4 | name = "extra_libraries" 5 | static_libs = ["lib/libwinapi_ole32.a", "lib/libwinapi_shell32.a"] 6 | -------------------------------------------------------------------------------- /fixups/winapi/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | 3 | ['cfg(target_os = "windows")'] 4 | buildscript.run = true 5 | extra_deps = [ 6 | "//platforms/windows:advapi32.lib", 7 | "//platforms/windows:avrt.lib", 8 | "//platforms/windows:bcrypt.lib", 9 | "//platforms/windows:bluetoothapis.lib", 10 | "//platforms/windows:bthprops.lib", 11 | "//platforms/windows:cfgmgr32.lib", 12 | "//platforms/windows:comctl32.lib", 13 | "//platforms/windows:comdlg32.lib", 14 | "//platforms/windows:credui.lib", 15 | "//platforms/windows:crypt32.lib", 16 | "//platforms/windows:cryptnet.lib", 17 | "//platforms/windows:d2d1.lib", 18 | "//platforms/windows:d3d11.lib", 19 | "//platforms/windows:d3d12.lib", 20 | "//platforms/windows:d3d9.lib", 21 | "//platforms/windows:d3dcompiler.lib", 22 | "//platforms/windows:dbghelp.lib", 23 | "//platforms/windows:dcomp.lib", 24 | "//platforms/windows:dsound.lib", 25 | "//platforms/windows:dwmapi.lib", 26 | "//platforms/windows:dwrite.lib", 27 | "//platforms/windows:dxgi.lib", 28 | "//platforms/windows:dxva2.lib", 29 | "//platforms/windows:fwpuclnt.lib", 30 | "//platforms/windows:gdi32.lib", 31 | "//platforms/windows:hid.lib", 32 | "//platforms/windows:httpapi.lib", 33 | "//platforms/windows:imm32.lib", 34 | "//platforms/windows:iphlpapi.lib", 35 | "//platforms/windows:kernel32.lib", 36 | "//platforms/windows:ktmw32.lib", 37 | "//platforms/windows:mmdevapi.lib", 38 | "//platforms/windows:mpr.lib", 39 | "//platforms/windows:msimg32.lib", 40 | "//platforms/windows:mswsock.lib", 41 | "//platforms/windows:ncrypt.lib", 42 | "//platforms/windows:netapi32.lib", 43 | "//platforms/windows:ntdll.lib", 44 | "//platforms/windows:odbc32.lib", 45 | "//platforms/windows:ole32.lib", 46 | "//platforms/windows:oleaut32.lib", 47 | "//platforms/windows:opengl32.lib", 48 | "//platforms/windows:pdh.lib", 49 | "//platforms/windows:powrprof.lib", 50 | "//platforms/windows:psapi.lib", 51 | "//platforms/windows:rstrtmgr.lib", 52 | "//platforms/windows:runtimeobject.lib", 53 | "//platforms/windows:secur32.lib", 54 | "//platforms/windows:setupapi.lib", 55 | "//platforms/windows:shcore.lib", 56 | "//platforms/windows:shell32.lib", 57 | "//platforms/windows:shlwapi.lib", 58 | "//platforms/windows:sporder.lib", 59 | "//platforms/windows:synchronization.lib", 60 | "//platforms/windows:user32.lib", 61 | "//platforms/windows:userenv.lib", 62 | "//platforms/windows:usp10.lib", 63 | "//platforms/windows:uxtheme.lib", 64 | "//platforms/windows:version.lib", 65 | "//platforms/windows:vssapi.lib", 66 | "//platforms/windows:wer.lib", 67 | "//platforms/windows:wevtapi.lib", 68 | "//platforms/windows:windowscodecs.lib", 69 | "//platforms/windows:winhttp.lib", 70 | "//platforms/windows:wininet.lib", 71 | "//platforms/windows:winmm.lib", 72 | "//platforms/windows:winscard.lib", 73 | "//platforms/windows:winspool.lib", 74 | "//platforms/windows:wintrust.lib", 75 | "//platforms/windows:winusb.lib", 76 | "//platforms/windows:wlanapi.lib", 77 | "//platforms/windows:ws2_32.lib", 78 | "//platforms/windows:wtsapi32.lib", 79 | "//platforms/windows:xinput.lib", 80 | ] 81 | -------------------------------------------------------------------------------- /fixups/windows_x86_64_gnu/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/windows_x86_64_msvc/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | -------------------------------------------------------------------------------- /fixups/zerocopy/fixups.toml: -------------------------------------------------------------------------------- 1 | buildscript.run = false 2 | cargo_env = ["CARGO_PKG_VERSION"] 3 | -------------------------------------------------------------------------------- /platforms/BUCK: -------------------------------------------------------------------------------- 1 | load("@prelude//platforms:defs.bzl", "host_configuration") 2 | load(":defs.bzl", "execution_platforms", "platform") 3 | 4 | platform( 5 | name = "host", 6 | constraint_values = [ 7 | host_configuration.cpu, 8 | host_configuration.os, 9 | ], 10 | visibility = ["PUBLIC"], 11 | ) 12 | 13 | execution_platforms( 14 | name = "execution", 15 | platforms = [ 16 | ":host", 17 | "//platforms/stage1:library", 18 | "//platforms/stage1:library-build-script", 19 | "//platforms/stage1:compiler", 20 | "//platforms/stage1:compiler-build-script", 21 | "//platforms/stage2:library", 22 | "//platforms/stage2:library-build-script", 23 | "//platforms/stage2:compiler", 24 | "//platforms/stage2:compiler-build-script", 25 | ], 26 | ) 27 | -------------------------------------------------------------------------------- /platforms/cross/BUCK: -------------------------------------------------------------------------------- 1 | [ 2 | platform( 3 | name = name, 4 | constraint_values = [ 5 | "prelude//cpu/constraints:{}".format(cpu), 6 | "prelude//os/constraints:{}".format(os), 7 | ], 8 | visibility = ["PUBLIC"], 9 | ) 10 | for name, cpu, os in [ 11 | ("aarch64-apple-darwin", "arm64", "macos"), 12 | ("aarch64-pc-windows-msvc", "arm64", "windows"), 13 | ("aarch64-unknown-linux-gnu", "arm64", "linux"), 14 | ("x86_64-apple-darwin", "x86_64", "macos"), 15 | ("x86_64-pc-windows-msvc", "x86_64", "windows"), 16 | ("x86_64-unknown-linux-gnu", "x86_64", "linux"), 17 | ] 18 | ] 19 | -------------------------------------------------------------------------------- /platforms/defs.bzl: -------------------------------------------------------------------------------- 1 | def _platform_impl(ctx: AnalysisContext) -> list[Provider]: 2 | platform_label = ctx.label.raw_target() 3 | constraints = {} 4 | 5 | if ctx.attrs.base: 6 | for label, value in ctx.attrs.base[PlatformInfo].configuration.constraints.items(): 7 | constraints[label] = value 8 | 9 | for dep in ctx.attrs.constraint_values: 10 | for label, value in dep[ConfigurationInfo].constraints.items(): 11 | constraints[label] = value 12 | 13 | use_windows_path_separators = False 14 | for value in constraints.values(): 15 | if str(value.label) == "prelude//os/constraints:windows": 16 | use_windows_path_separators = True 17 | 18 | configuration = ConfigurationInfo( 19 | constraints = constraints, 20 | values = {}, 21 | ) 22 | 23 | transition = set() 24 | for dep in ctx.attrs.transition: 25 | transition.add(dep[ConstraintSettingInfo].label) 26 | 27 | def transition_impl(platform: PlatformInfo) -> PlatformInfo: 28 | constraints = dict(configuration.constraints) 29 | for setting, value in platform.configuration.constraints.items(): 30 | if setting not in transition: 31 | constraints[setting] = value 32 | 33 | return PlatformInfo( 34 | label = str(platform_label), 35 | configuration = ConfigurationInfo( 36 | constraints = constraints, 37 | values = platform.configuration.values, 38 | ), 39 | ) 40 | 41 | return [ 42 | DefaultInfo(), 43 | PlatformInfo( 44 | label = str(platform_label), 45 | configuration = configuration, 46 | ), 47 | ExecutionPlatformInfo( 48 | label = platform_label, 49 | configuration = configuration, 50 | executor_config = CommandExecutorConfig( 51 | local_enabled = True, 52 | remote_enabled = False, 53 | use_windows_path_separators = use_windows_path_separators, 54 | ), 55 | ), 56 | TransitionInfo(impl = transition_impl), 57 | ] 58 | 59 | platform = rule( 60 | impl = _platform_impl, 61 | attrs = { 62 | "base": attrs.option(attrs.dep(providers = [PlatformInfo]), default = None), 63 | "constraint_values": attrs.list(attrs.configuration_label(), default = []), 64 | # Configuration settings in this list are overwritten during a 65 | # transition to this platform, whereas configuration settings not in 66 | # this list are preserved. 67 | "transition": attrs.list(attrs.configuration_label(), default = [ 68 | "//constraints:bootstrap-stage", 69 | "//constraints:opt-level", 70 | "//constraints:reindeer-universe", 71 | "//constraints:sysroot-deps", 72 | ]), 73 | }, 74 | is_configuration_rule = True, 75 | ) 76 | 77 | def _execution_platforms_impl(ctx: AnalysisContext) -> list[Provider]: 78 | platforms = [ 79 | platform[ExecutionPlatformInfo] 80 | for platform in ctx.attrs.platforms 81 | ] 82 | 83 | return [ 84 | DefaultInfo(), 85 | ExecutionPlatformRegistrationInfo(platforms = platforms), 86 | ] 87 | 88 | execution_platforms = rule( 89 | impl = _execution_platforms_impl, 90 | attrs = { 91 | "platforms": attrs.list(attrs.dep(providers = [ExecutionPlatformInfo])), 92 | }, 93 | is_configuration_rule = True, 94 | ) 95 | -------------------------------------------------------------------------------- /platforms/exec/BUCK: -------------------------------------------------------------------------------- 1 | alias( 2 | name = "os_lookup", 3 | actual = "prelude//os_lookup/targets:os_lookup", 4 | target_compatible_with = select({ 5 | "DEFAULT": ["//constraints:false"], 6 | "prelude//os:linux": [], 7 | "prelude//os:macos": [], 8 | "prelude//os:windows": [], 9 | }), 10 | visibility = ["PUBLIC"], 11 | ) 12 | 13 | alias( 14 | name = "http_archive", 15 | actual = "prelude//http_archive/tools:exec_deps", 16 | target_compatible_with = select({ 17 | "DEFAULT": ["//constraints:false"], 18 | "prelude//os:linux": [], 19 | "prelude//os:macos": [], 20 | "prelude//os:windows": [], 21 | }), 22 | visibility = ["PUBLIC"], 23 | ) 24 | -------------------------------------------------------------------------------- /platforms/stage1/BUCK: -------------------------------------------------------------------------------- 1 | load("//platforms:defs.bzl", "platform") 2 | 3 | platform( 4 | name = "library", 5 | base = "//platforms:host", 6 | constraint_values = [ 7 | "//constraints:library", 8 | "//constraints:opt-level=3", 9 | "//constraints:stage1", 10 | "//constraints:sysroot-deps=explicit", 11 | ], 12 | visibility = ["PUBLIC"], 13 | ) 14 | 15 | platform( 16 | name = "library-build-script", 17 | base = ":library", 18 | constraint_values = [ 19 | "//constraints:opt-level=0", 20 | "//constraints:sysroot-deps=implicit", 21 | ], 22 | visibility = ["PUBLIC"], 23 | ) 24 | 25 | platform( 26 | name = "compiler", 27 | base = "//platforms:host", 28 | constraint_values = [ 29 | "//constraints:compiler", 30 | "//constraints:opt-level=3", 31 | "//constraints:stage1", 32 | "//constraints:sysroot-deps=implicit", 33 | ], 34 | visibility = ["PUBLIC"], 35 | ) 36 | 37 | platform( 38 | name = "compiler-build-script", 39 | base = ":compiler", 40 | constraint_values = [ 41 | "//constraints:opt-level=0", 42 | ], 43 | visibility = ["PUBLIC"], 44 | ) 45 | -------------------------------------------------------------------------------- /platforms/stage2/BUCK: -------------------------------------------------------------------------------- 1 | load("//platforms:defs.bzl", "platform") 2 | 3 | platform( 4 | name = "library", 5 | base = "//platforms:host", 6 | constraint_values = [ 7 | "//constraints:library", 8 | "//constraints:opt-level=3", 9 | "//constraints:stage2", 10 | "//constraints:sysroot-deps=explicit", 11 | ], 12 | visibility = ["PUBLIC"], 13 | ) 14 | 15 | platform( 16 | name = "library-build-script", 17 | base = ":library", 18 | constraint_values = [ 19 | "//constraints:opt-level=0", 20 | "//constraints:sysroot-deps=implicit", 21 | ], 22 | visibility = ["PUBLIC"], 23 | ) 24 | 25 | platform( 26 | name = "compiler", 27 | base = "//platforms:host", 28 | constraint_values = [ 29 | "//constraints:compiler", 30 | "//constraints:opt-level=3", 31 | "//constraints:stage2", 32 | "//constraints:sysroot-deps=implicit", 33 | ], 34 | visibility = ["PUBLIC"], 35 | ) 36 | 37 | platform( 38 | name = "compiler-build-script", 39 | base = ":compiler", 40 | constraint_values = [ 41 | "//constraints:opt-level=0", 42 | ], 43 | visibility = ["PUBLIC"], 44 | ) 45 | -------------------------------------------------------------------------------- /platforms/windows/BUCK: -------------------------------------------------------------------------------- 1 | LIBS = [ 2 | "advapi32.lib", 3 | "avrt.lib", 4 | "bcrypt.lib", 5 | "bluetoothapis.lib", 6 | "bthprops.lib", 7 | "cfgmgr32.lib", 8 | "comctl32.lib", 9 | "comdlg32.lib", 10 | "credui.lib", 11 | "crypt32.lib", 12 | "cryptnet.lib", 13 | "d2d1.lib", 14 | "d3d11.lib", 15 | "d3d12.lib", 16 | "d3d9.lib", 17 | "d3dcompiler.lib", 18 | "dbghelp.lib", 19 | "dcomp.lib", 20 | "dsound.lib", 21 | "dwmapi.lib", 22 | "dwrite.lib", 23 | "dxgi.lib", 24 | "dxva2.lib", 25 | "fwpuclnt.lib", 26 | "gdi32.lib", 27 | "hid.lib", 28 | "httpapi.lib", 29 | "imm32.lib", 30 | "iphlpapi.lib", 31 | "kernel32.lib", 32 | "ktmw32.lib", 33 | "mmdevapi.lib", 34 | "mpr.lib", 35 | "msimg32.lib", 36 | "mswsock.lib", 37 | "ncrypt.lib", 38 | "netapi32.lib", 39 | "ntdll.lib", 40 | "odbc32.lib", 41 | "ole32.lib", 42 | "oleaut32.lib", 43 | "opengl32.lib", 44 | "pdh.lib", 45 | "powrprof.lib", 46 | "psapi.lib", 47 | "rstrtmgr.lib", 48 | "runtimeobject.lib", 49 | "secur32.lib", 50 | "setupapi.lib", 51 | "shcore.lib", 52 | "shell32.lib", 53 | "shlwapi.lib", 54 | "sporder.lib", 55 | "synchronization.lib", 56 | "user32.lib", 57 | "userenv.lib", 58 | "usp10.lib", 59 | "uxtheme.lib", 60 | "version.lib", 61 | "vssapi.lib", 62 | "wer.lib", 63 | "wevtapi.lib", 64 | "windowscodecs.lib", 65 | "winhttp.lib", 66 | "wininet.lib", 67 | "winmm.lib", 68 | "winscard.lib", 69 | "winspool.lib", 70 | "wintrust.lib", 71 | "winusb.lib", 72 | "wlanapi.lib", 73 | "ws2_32.lib", 74 | "wtsapi32.lib", 75 | "xinput.lib", 76 | ] 77 | 78 | [ 79 | prebuilt_cxx_library( 80 | name = lib, 81 | exported_linker_flags = [lib], 82 | header_only = True, 83 | target_compatible_with = ["prelude//os:windows"], 84 | visibility = ["PUBLIC"], 85 | ) 86 | for lib in LIBS 87 | ] 88 | -------------------------------------------------------------------------------- /reindeer.toml: -------------------------------------------------------------------------------- 1 | strict_globs = true 2 | unresolved_fixup_error = true 3 | 4 | [cargo] 5 | bindeps = true 6 | 7 | [buck] 8 | buckfile_imports = """ 9 | load("//crates.io:crate_download.bzl", "crate_download") 10 | load( 11 | ":defs.bzl", 12 | "cxx_bootstrap_library", 13 | "rust_bootstrap_alias", 14 | "rust_bootstrap_binary", 15 | "rust_bootstrap_buildscript_run", 16 | "rust_bootstrap_library", 17 | ) 18 | 19 | export_file( 20 | name = "stage0_manifest", 21 | src = "rust/src/stage0", 22 | visibility = ["//stage0:"], 23 | ) 24 | 25 | rust_bootstrap_library( 26 | name = "rustc_driver-0.0.0", 27 | srcs = ["rust/compiler/rustc_driver/src/lib.rs"], 28 | crate = "rustc_driver", 29 | crate_root = "rust/compiler/rustc_driver/src/lib.rs", 30 | edition = "2021", 31 | visibility = [], 32 | deps = [":rustc_driver_impl-0.0.0"], 33 | ) 34 | """ 35 | 36 | alias = "rust_bootstrap_alias" 37 | buildscript_genrule = "rust_bootstrap_buildscript_run" 38 | cxx_library = "cxx_bootstrap_library" 39 | http_archive = "crate_download" 40 | rust_binary = "rust_bootstrap_binary" 41 | rust_library = "rust_bootstrap_library" 42 | 43 | [universe.library] 44 | constraint = "//constraints:library" 45 | include_crates = [ 46 | "alloc", 47 | "compiler_builtins", 48 | "core", 49 | "panic_abort", 50 | "panic_unwind", 51 | "proc_macro", 52 | "std", 53 | "test", 54 | ] 55 | 56 | [universe.compiler] 57 | constraint = "//constraints:compiler" 58 | include_crates = [ 59 | "allocator-api2", 60 | "clippy", 61 | "rustc-main", 62 | "rustdoc-tool", 63 | ] 64 | -------------------------------------------------------------------------------- /scripts/check.bxl: -------------------------------------------------------------------------------- 1 | # Report warnings from every dependency of rustc: 2 | # buck2 bxl scripts/check.bxl:main -- --target stage1:rustc | xargs cat 3 | # 4 | # Run clippy on every dependency of rustc: 5 | # buck2 bxl scripts/check.bxl:main -- --target stage1:rustc --output clippy.txt | xargs cat 6 | # 7 | # Run clippy on every dependency of rustc and report lints in JSON: 8 | # buck2 bxl scripts/check.bxl:main -- --target stage1:rustc --output clippy.json | xargs cat 9 | 10 | def main_impl(bxl_ctx: bxl.Context) -> None: 11 | # Build unconfigured targets set 12 | utargets = utarget_set() 13 | utargets += bxl_ctx.uquery().owner(bxl_ctx.cli_args.path) 14 | for target in bxl_ctx.cli_args.target: 15 | utargets += bxl_ctx.unconfigured_targets(target) 16 | 17 | # Apply default target platform to every target in the set 18 | ctargets = bxl_ctx.configured_targets(utargets, modifiers = bxl_ctx.cli_args.modifier) 19 | 20 | # Compute transitive closure of dependencies 21 | transitive_ctargets = bxl_ctx.cquery().deps(ctargets) 22 | 23 | # Filter to just Rust targets 24 | rust_ctargets = bxl_ctx.cquery().kind("^(rust_library|rust_binary)$", transitive_ctargets) 25 | 26 | # Build the requested sub-target of each of those Rust targets 27 | build_result = bxl_ctx.build([ 28 | target.label.with_sub_target(bxl_ctx.cli_args.output) 29 | for target in rust_ctargets 30 | ]) 31 | 32 | # Report results 33 | failed_targets = [] 34 | for target, value in build_result.items(): 35 | raw_target = target.raw_target() 36 | if len(value.failures()) > 0: 37 | failed_targets.append(raw_target) 38 | else: 39 | artifacts = bxl_ctx.output.ensure_multiple(value.artifacts()) 40 | bxl_ctx.output.stream(sep = "\n", wait_on = artifacts, *artifacts) 41 | 42 | if len(failed_targets) != 0: 43 | bxl_ctx.output.stream_json({"failed_targets": failed_targets}) 44 | fail("{} targets failed to build".format(len(failed_targets))) 45 | 46 | main = bxl.main( 47 | impl = main_impl, 48 | cli_args = { 49 | "modifier": cli_args.list(cli_args.string(), short = "m", default = []), 50 | "output": cli_args.enum(["diag.txt", "diag.json", "clippy.txt", "clippy.json"], default = "diag.txt"), 51 | "path": cli_args.list(cli_args.string(), default = []), 52 | "target": cli_args.list(cli_args.target_expr(), default = []), 53 | }, 54 | ) 55 | -------------------------------------------------------------------------------- /scripts/download.bxl: -------------------------------------------------------------------------------- 1 | # Download stage0 and crates.io dependencies. 2 | # buck2 bxl scripts/download.bxl:main 3 | 4 | def main_impl(bxl_ctx: bxl.Context) -> None: 5 | # crates.io downloads 6 | utargets = bxl_ctx.uquery().kind("crate_download", "//:") 7 | ctargets = bxl_ctx.configured_targets(utargets) 8 | analysis = bxl_ctx.analysis(ctargets) 9 | bxl_ctx.output.ensure_multiple([ 10 | crate.providers()[DefaultInfo].default_outputs[0] 11 | for crate in analysis.values() 12 | ]) 13 | 14 | # stage0 compiler component downloads 15 | ctarget = bxl_ctx.configured_targets("//stage0:dist") 16 | analysis = bxl_ctx.analysis(ctarget) 17 | bxl_ctx.output.ensure_multiple([ 18 | component[DefaultInfo].default_outputs[0] 19 | for component in analysis.providers()[DefaultInfo].sub_targets.values() 20 | ]) 21 | 22 | # stage0 llvm download 23 | ctarget = bxl_ctx.configured_targets("//stage0:rust_dev") 24 | analysis = bxl_ctx.analysis(ctarget) 25 | bxl_ctx.output.ensure(analysis.providers()[DefaultInfo].default_outputs[0]) 26 | 27 | main = bxl.main( 28 | impl = main_impl, 29 | cli_args = {}, 30 | ) 31 | -------------------------------------------------------------------------------- /stage0/BUCK: -------------------------------------------------------------------------------- 1 | load("//constraints:defs.bzl", "configuration_transition") 2 | load( 3 | ":defs.bzl", 4 | "ci_artifact", 5 | "ci_llvm", 6 | "stage0_download", 7 | "stage0_executable", 8 | "stage0_extract", 9 | "stage0_sysroot", 10 | ) 11 | 12 | configuration_transition( 13 | name = "stage0_configuration", 14 | add_fallback_settings = "//platforms:host", 15 | keep_settings = [ 16 | "prelude//cpu/constraints:cpu", 17 | "prelude//os/constraints:os", 18 | ], 19 | label = "stage0", 20 | ) 21 | 22 | stage0_download( 23 | name = "dist", 24 | components = [ 25 | "cargo", 26 | "clippy", 27 | "rust-std", 28 | "rustc", 29 | ], 30 | incoming_transition = ":stage0_configuration", 31 | manifest = "//:stage0_manifest", 32 | ) 33 | 34 | stage0_extract( 35 | name = "extract", 36 | dist = ":dist", 37 | incoming_transition = ":stage0_configuration", 38 | ) 39 | 40 | stage0_executable( 41 | name = "rustc", 42 | dist = ":extract[rustc]", 43 | incoming_transition = ":stage0_configuration", 44 | visibility = ["PUBLIC"], 45 | ) 46 | 47 | stage0_executable( 48 | name = "rustdoc", 49 | dist = ":extract[rustc]", 50 | env = {"RUSTC_BOOTSTRAP": "1"}, 51 | incoming_transition = ":stage0_configuration", 52 | visibility = ["PUBLIC"], 53 | ) 54 | 55 | stage0_executable( 56 | name = "clippy-driver", 57 | dist = ":extract[clippy]", 58 | incoming_transition = ":stage0_configuration", 59 | libdir = ":extract[rustc]", 60 | visibility = ["PUBLIC"], 61 | ) 62 | 63 | stage0_sysroot( 64 | name = "sysroot", 65 | dist = ":dist[rust-std]", 66 | incoming_transition = ":stage0_configuration", 67 | visibility = ["PUBLIC"], 68 | ) 69 | 70 | ci_artifact( 71 | name = "rust_dev", 72 | commit = "c03c38d5c2368cd2aa0e056dba060b94fc747f4e", 73 | component = "rust-dev-nightly", 74 | incoming_transition = ":stage0_configuration", 75 | manifest = "//:stage0_manifest", 76 | sha256 = { 77 | "aarch64-apple-darwin": "bb3654066eb816527697aa6e4d16793493517e2535a230c7f5dda5a8ecbaf5cb", 78 | "aarch64-pc-windows-msvc": "7680387e1818e2d0ca842de9d22d243d424ad6e9232af32d1925c09b5cca07c1", 79 | "aarch64-unknown-linux-gnu": "e6b7ef705621477cf4ef051e92acb5fb79275208a47064e03a3a67b31a607180", 80 | "x86_64-apple-darwin": "c0efa84a546087f4817060e07f8c712a3c586f3846fd6c93651f0e16417273fe", 81 | "x86_64-pc-windows-msvc": "f762480a89c9b83e2cce839c87f5aa7136b2aaab246900a4bae52cee0d31bb71", 82 | "x86_64-unknown-linux-gnu": "7cae16ba2ab8a4eb805a007688da4ff7aac337a5211401ae2f30901c0fd07a44", 83 | }, 84 | ) 85 | 86 | ci_llvm( 87 | name = "ci_llvm", 88 | incoming_transition = ":stage0_configuration", 89 | rust_dev = ":rust_dev", 90 | visibility = ["PUBLIC"], 91 | ) 92 | 93 | python_bootstrap_binary( 94 | name = "stage0_executable", 95 | main = "stage0_executable.py", 96 | ) 97 | 98 | python_bootstrap_binary( 99 | name = "stage0_overlay", 100 | main = "stage0_overlay.py", 101 | ) 102 | 103 | python_bootstrap_binary( 104 | name = "stage0_sysroot", 105 | main = "stage0_sysroot.py", 106 | ) 107 | -------------------------------------------------------------------------------- /stage0/defs.bzl: -------------------------------------------------------------------------------- 1 | load("@prelude//http_archive:exec_deps.bzl", "HttpArchiveExecDeps") 2 | load("@prelude//http_archive:unarchive.bzl", "unarchive") 3 | load("@prelude//os_lookup:defs.bzl", "OsLookup") 4 | load("@prelude//rust:targets.bzl", "targets") 5 | 6 | Stage0Info = provider( 7 | fields = { 8 | "artifacts_server": str, 9 | "compiler_date": str, 10 | "compiler_version": str, 11 | "dist_server": str, 12 | "entries": dict[str, str], 13 | }, 14 | ) 15 | 16 | def _stage0_parse_impl( 17 | actions: AnalysisActions, 18 | stage0_artifact: ArtifactValue) -> list[Provider]: 19 | _ = actions 20 | 21 | artifacts_server = None 22 | compiler_date = None 23 | compiler_version = None 24 | dist_server = None 25 | entries = {} 26 | 27 | for line in stage0_artifact.read_string().splitlines(): 28 | if line.startswith("#") or "=" not in line: 29 | continue 30 | 31 | key, value = line.split("=", 1) 32 | if key == "artifacts_server": 33 | artifacts_server = value 34 | elif key == "compiler_date": 35 | compiler_date = value 36 | elif key == "compiler_version": 37 | compiler_version = value 38 | elif key == "dist_server": 39 | dist_server = value 40 | else: 41 | entries[key] = value 42 | 43 | return [Stage0Info( 44 | artifacts_server = artifacts_server, 45 | compiler_date = compiler_date, 46 | compiler_version = compiler_version, 47 | dist_server = dist_server, 48 | entries = entries, 49 | )] 50 | 51 | _stage0_parse = dynamic_actions( 52 | impl = _stage0_parse_impl, 53 | attrs = { 54 | "stage0_artifact": dynattrs.artifact_value(), 55 | }, 56 | ) 57 | 58 | def _stage0_component_impl( 59 | actions: AnalysisActions, 60 | component: str, 61 | output: OutputArtifact, 62 | stage0_info: ResolvedDynamicValue, 63 | target_triple: str) -> list[Provider]: 64 | stage0_info = stage0_info.providers[Stage0Info] 65 | 66 | path = "dist/{}/{}-{}-{}.tar.xz".format( 67 | stage0_info.compiler_date, 68 | component, 69 | stage0_info.compiler_version, 70 | target_triple, 71 | ) 72 | 73 | sha256 = stage0_info.entries.get(path) 74 | if not sha256: 75 | fail("no checksum found in stage0 for {}".format(path)) 76 | 77 | actions.download_file( 78 | output, 79 | "{}/{}".format(stage0_info.dist_server, path), 80 | sha256 = sha256, 81 | ) 82 | return [] 83 | 84 | _stage0_component = dynamic_actions( 85 | impl = _stage0_component_impl, 86 | attrs = { 87 | "component": dynattrs.value(str), 88 | "output": dynattrs.output(), 89 | "stage0_info": dynattrs.dynamic_value(), 90 | "target_triple": dynattrs.value(str), 91 | }, 92 | ) 93 | 94 | def _stage0_download_impl(ctx: AnalysisContext) -> list[Provider]: 95 | target_triple = targets.exec_triple(ctx) 96 | 97 | stage0_artifact = ctx.attrs.manifest[DefaultInfo].default_outputs[0] 98 | stage0_info = ctx.actions.dynamic_output_new( 99 | _stage0_parse( 100 | stage0_artifact = stage0_artifact, 101 | ), 102 | ) 103 | 104 | sub_targets = {} 105 | for component in ctx.attrs.components: 106 | download = ctx.actions.declare_output("{}.tar.xz".format(component)) 107 | ctx.actions.dynamic_output_new( 108 | _stage0_component( 109 | component = component, 110 | output = download.as_output(), 111 | stage0_info = stage0_info, 112 | target_triple = target_triple, 113 | ), 114 | ) 115 | sub_targets[component] = [DefaultInfo(default_output = download)] 116 | 117 | return [DefaultInfo(sub_targets = sub_targets)] 118 | 119 | stage0_download = rule( 120 | impl = _stage0_download_impl, 121 | attrs = { 122 | "components": attrs.list(attrs.string()), 123 | "manifest": attrs.dep(), 124 | "_exec_os_type": attrs.default_only(attrs.dep(providers = [OsLookup], default = "//platforms/exec:os_lookup")), 125 | }, 126 | supports_incoming_transition = True, 127 | ) 128 | 129 | def _stage0_extract_impl(ctx: AnalysisContext) -> list[Provider]: 130 | sub_targets = {} 131 | for name, dist in ctx.attrs.dist[DefaultInfo].sub_targets.items(): 132 | contents, _ = unarchive( 133 | ctx = ctx, 134 | archive = dist[DefaultInfo].default_outputs[0], 135 | output_name = name, 136 | ext_type = "tar.xz", 137 | excludes = [], 138 | strip_prefix = None, 139 | exec_deps = ctx.attrs._exec_deps[HttpArchiveExecDeps], 140 | prefer_local = False, 141 | sub_targets = {}, 142 | ) 143 | sub_targets[name] = [DefaultInfo(default_output = contents)] 144 | 145 | return [DefaultInfo(sub_targets = sub_targets)] 146 | 147 | stage0_extract = rule( 148 | impl = _stage0_extract_impl, 149 | attrs = { 150 | "dist": attrs.dep(), 151 | "_exec_deps": attrs.default_only(attrs.exec_dep(providers = [HttpArchiveExecDeps], default = "//platforms/exec:http_archive")), 152 | }, 153 | supports_incoming_transition = True, 154 | ) 155 | 156 | def _stage0_executable_impl(ctx: AnalysisContext) -> list[Provider]: 157 | dist = ctx.attrs.dist[DefaultInfo].default_outputs[0] 158 | 159 | if ctx.attrs.libdir: 160 | libdir = ctx.attrs.libdir[DefaultInfo].default_outputs[0] 161 | overlay = ctx.actions.declare_output("overlay", dir = True) 162 | ctx.actions.run( 163 | [ 164 | ctx.attrs._overlay[RunInfo], 165 | cmd_args(dist, format = "--dist={}"), 166 | "--exe={}".format(ctx.label.name), 167 | cmd_args(libdir, format = "--libdir={}", relative_to = overlay), 168 | cmd_args(overlay.as_output(), format = "--overlay={}"), 169 | ], 170 | category = "overlay", 171 | ) 172 | command = overlay.project("bin").project(ctx.label.name) 173 | else: 174 | command = cmd_args( 175 | ctx.attrs._wrapper[RunInfo], 176 | cmd_args(dist, format = "--dist={}"), 177 | "--exe={}".format(ctx.label.name), 178 | ["--env={}={}".format(k, v) for k, v in ctx.attrs.env.items()], 179 | "--", 180 | ) 181 | 182 | return [ 183 | DefaultInfo(), 184 | RunInfo(command), 185 | ] 186 | 187 | stage0_executable = rule( 188 | impl = _stage0_executable_impl, 189 | attrs = { 190 | "dist": attrs.dep(), 191 | "env": attrs.dict(key = attrs.string(), value = attrs.string(), default = {}), 192 | "libdir": attrs.option(attrs.dep(), default = None), 193 | "_overlay": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "//stage0:stage0_overlay")), 194 | "_wrapper": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "//stage0:stage0_executable")), 195 | }, 196 | supports_incoming_transition = True, 197 | ) 198 | 199 | def _stage0_sysroot_impl(ctx: AnalysisContext) -> list[Provider]: 200 | dist = ctx.attrs.dist[DefaultInfo].default_outputs[0] 201 | 202 | contents, _ = unarchive( 203 | ctx = ctx, 204 | archive = dist, 205 | output_name = "dist", 206 | ext_type = "tar.xz", 207 | excludes = [], 208 | strip_prefix = None, 209 | exec_deps = ctx.attrs._exec_deps[HttpArchiveExecDeps], 210 | prefer_local = False, 211 | sub_targets = {}, 212 | ) 213 | 214 | sysroot = ctx.actions.declare_output("sysroot") 215 | ctx.actions.run( 216 | [ 217 | ctx.attrs._wrapper[RunInfo], 218 | cmd_args(contents, format = "--dist={}"), 219 | cmd_args(contents, format = "--relative={}").relative_to(sysroot, parent = 1), 220 | cmd_args(sysroot.as_output(), format = "--symlink={}"), 221 | ], 222 | category = "sysroot", 223 | ) 224 | 225 | return [DefaultInfo(default_output = sysroot)] 226 | 227 | stage0_sysroot = rule( 228 | impl = _stage0_sysroot_impl, 229 | attrs = { 230 | "dist": attrs.dep(), 231 | "_exec_deps": attrs.default_only(attrs.exec_dep(providers = [HttpArchiveExecDeps], default = "//platforms/exec:http_archive")), 232 | "_wrapper": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "//stage0:stage0_sysroot")), 233 | }, 234 | supports_incoming_transition = True, 235 | ) 236 | 237 | def _download_ci_artifact_impl( 238 | actions: AnalysisActions, 239 | commit: str, 240 | component: str, 241 | output: OutputArtifact, 242 | sha256: str, 243 | stage0_info: ResolvedDynamicValue, 244 | target_triple: str) -> list[Provider]: 245 | artifacts_server = stage0_info.providers[Stage0Info].artifacts_server 246 | actions.download_file( 247 | output, 248 | "{}/{}/{}-{}.tar.xz".format(artifacts_server, commit, component, target_triple), 249 | sha256 = sha256, 250 | ) 251 | return [] 252 | 253 | _download_ci_artifact = dynamic_actions( 254 | impl = _download_ci_artifact_impl, 255 | attrs = { 256 | "commit": dynattrs.value(str), 257 | "component": dynattrs.value(str), 258 | "output": dynattrs.output(), 259 | "sha256": dynattrs.value(str), 260 | "stage0_info": dynattrs.dynamic_value(), 261 | "target_triple": dynattrs.value(str), 262 | }, 263 | ) 264 | 265 | def _ci_artifact_impl(ctx: AnalysisContext) -> list[Provider]: 266 | target_triple = targets.exec_triple(ctx) 267 | 268 | stage0_artifact = ctx.attrs.manifest[DefaultInfo].default_outputs[0] 269 | stage0_info = ctx.actions.dynamic_output_new( 270 | _stage0_parse( 271 | stage0_artifact = stage0_artifact, 272 | ), 273 | ) 274 | 275 | download = ctx.actions.declare_output("{}.tar.xz".format(ctx.attrs.component)) 276 | ctx.actions.dynamic_output_new( 277 | _download_ci_artifact( 278 | commit = ctx.attrs.commit, 279 | component = ctx.attrs.component, 280 | output = download.as_output(), 281 | sha256 = ctx.attrs.sha256.get(target_triple, "0" * 64), 282 | stage0_info = stage0_info, 283 | target_triple = target_triple, 284 | ), 285 | ) 286 | 287 | return [DefaultInfo(default_output = download)] 288 | 289 | ci_artifact = rule( 290 | impl = _ci_artifact_impl, 291 | attrs = { 292 | "commit": attrs.string(), 293 | "component": attrs.string(), 294 | "manifest": attrs.dep(), 295 | "sha256": attrs.dict(key = attrs.string(), value = attrs.string()), 296 | "_exec_os_type": attrs.default_only(attrs.dep(providers = [OsLookup], default = "//platforms/exec:os_lookup")), 297 | }, 298 | supports_incoming_transition = True, 299 | ) 300 | 301 | def _ci_llvm_impl(ctx: AnalysisContext) -> list[Provider]: 302 | rust_dev = ctx.attrs.rust_dev[DefaultInfo].default_outputs[0] 303 | 304 | contents, _ = unarchive( 305 | ctx = ctx, 306 | archive = rust_dev, 307 | output_name = "ci-llvm", 308 | ext_type = "tar.xz", 309 | excludes = [], 310 | strip_prefix = "rust-dev-nightly-{}/rust-dev".format(targets.exec_triple(ctx)), 311 | exec_deps = ctx.attrs._exec_deps[HttpArchiveExecDeps], 312 | prefer_local = False, 313 | sub_targets = {}, 314 | ) 315 | 316 | return [DefaultInfo(default_output = contents)] 317 | 318 | ci_llvm = rule( 319 | impl = _ci_llvm_impl, 320 | attrs = { 321 | "rust_dev": attrs.dep(), 322 | "_exec_deps": attrs.default_only(attrs.exec_dep(providers = [HttpArchiveExecDeps], default = "//platforms/exec:http_archive")), 323 | "_exec_os_type": attrs.default_only(attrs.dep(providers = [OsLookup], default = "//platforms/exec:os_lookup")), 324 | }, 325 | supports_incoming_transition = True, 326 | ) 327 | -------------------------------------------------------------------------------- /stage0/stage0_executable.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import subprocess 4 | import sys 5 | from pathlib import Path 6 | from typing import List, NamedTuple 7 | 8 | 9 | class Args(NamedTuple): 10 | dist: Path 11 | exe: str 12 | env: List[str] 13 | rest: List[str] 14 | 15 | 16 | if __name__ == "__main__": 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument("--dist", type=Path) 19 | parser.add_argument("--exe", type=str) 20 | parser.add_argument("--env", action="append", default=[]) 21 | parser.add_argument("rest", nargs="*", type=str) 22 | args = Args(**vars(parser.parse_args())) 23 | 24 | env = os.environ.copy() 25 | for entry in args.env: 26 | k, v = entry.split("=", 1) 27 | env[k] = v 28 | 29 | toplevel = os.listdir(args.dist) 30 | if len(toplevel) != 1: 31 | raise RuntimeError( 32 | "unexpected top-level directory entries: {}".format(toplevel), 33 | ) 34 | 35 | components = args.dist / toplevel[0] / "components" 36 | with open(components) as f: 37 | component = f.read().strip() 38 | 39 | exe = args.dist / toplevel[0] / component / "bin" / args.exe 40 | res = subprocess.run([exe] + args.rest, env=env) 41 | sys.exit(res.returncode) 42 | -------------------------------------------------------------------------------- /stage0/stage0_overlay.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | from typing import NamedTuple 6 | 7 | 8 | class Args(NamedTuple): 9 | dist: Path 10 | exe: str 11 | libdir: Path 12 | overlay: Path 13 | 14 | 15 | if __name__ == "__main__": 16 | parser = argparse.ArgumentParser() 17 | parser.add_argument("--dist", type=Path) 18 | parser.add_argument("--exe", type=str) 19 | parser.add_argument("--libdir", type=Path) 20 | parser.add_argument("--overlay", type=Path) 21 | args = Args(**vars(parser.parse_args())) 22 | 23 | toplevel = os.listdir(args.dist) 24 | if len(toplevel) != 1: 25 | raise RuntimeError( 26 | "unexpected top-level directory entries: {}".format(toplevel), 27 | ) 28 | 29 | components = args.dist / toplevel[0] / "components" 30 | with open(components) as f: 31 | component = f.read().strip() 32 | 33 | # Copy binary 34 | os.mkdir(args.overlay) 35 | os.mkdir(args.overlay / "bin") 36 | shutil.copy2( 37 | args.dist / toplevel[0] / component / "bin" / args.exe, 38 | args.overlay / "bin", 39 | ) 40 | 41 | toplevel = os.listdir(args.overlay / args.libdir) 42 | if len(toplevel) != 1: 43 | raise RuntimeError( 44 | "unexpected top-level directory entries: {}".format(toplevel), 45 | ) 46 | 47 | components = args.overlay / args.libdir / toplevel[0] / "components" 48 | with open(components) as f: 49 | component = f.read().strip() 50 | 51 | # Symlink lib dir 52 | os.symlink( 53 | args.libdir / toplevel[0] / component / "lib", 54 | args.overlay / "lib", 55 | ) 56 | -------------------------------------------------------------------------------- /stage0/stage0_sysroot.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | from pathlib import Path 4 | from typing import NamedTuple 5 | 6 | 7 | class Args(NamedTuple): 8 | dist: Path 9 | relative: Path 10 | symlink: Path 11 | 12 | 13 | if __name__ == "__main__": 14 | parser = argparse.ArgumentParser() 15 | parser.add_argument("--dist", type=Path) 16 | parser.add_argument("--relative", type=Path) 17 | parser.add_argument("--symlink", type=Path) 18 | args = Args(**vars(parser.parse_args())) 19 | 20 | toplevel = os.listdir(args.dist) 21 | if len(toplevel) != 1: 22 | raise RuntimeError( 23 | "unexpected top-level directory entries: {}".format(toplevel), 24 | ) 25 | 26 | components = args.dist / toplevel[0] / "components" 27 | with open(components) as f: 28 | component = f.read().strip() 29 | 30 | src = args.relative / toplevel[0] / component 31 | os.symlink(src, args.symlink) 32 | -------------------------------------------------------------------------------- /stage1/BUCK: -------------------------------------------------------------------------------- 1 | load("//constraints:defs.bzl", "transition_alias") 2 | load(":defs.bzl", "SYSROOT_CRATES", "rust_tool", "sysroot") 3 | 4 | [ 5 | transition_alias( 6 | name = crate, 7 | actual = "//:{}".format(crate), 8 | incoming_transition = "//platforms/stage1:library", 9 | visibility = ["PUBLIC"], 10 | ) 11 | for crate in SYSROOT_CRATES 12 | ] 13 | 14 | transition_alias( 15 | name = "rust_allocator", 16 | actual = "//allocator:rust_allocator", 17 | incoming_transition = "//platforms/stage1:library", 18 | visibility = ["toolchains//:rust"], 19 | ) 20 | 21 | rust_tool( 22 | name = "rustc", 23 | exe = "//:rustc-main-rustc-main", 24 | incoming_transition = "//platforms/stage1:compiler", 25 | llvm = "//stage0:ci_llvm", 26 | visibility = ["toolchains//:rust"], 27 | ) 28 | 29 | rust_tool( 30 | name = "rustdoc", 31 | exe = "//:rustdoc-tool-rustdoc_tool_binary", 32 | incoming_transition = "//platforms/stage1:compiler", 33 | llvm = "//stage0:ci_llvm", 34 | visibility = ["toolchains//:rust"], 35 | ) 36 | 37 | rust_tool( 38 | name = "clippy-driver", 39 | exe = "//:clippy-clippy-driver", 40 | incoming_transition = "//platforms/stage1:compiler", 41 | llvm = "//stage0:ci_llvm", 42 | visibility = ["toolchains//:rust"], 43 | ) 44 | 45 | sysroot( 46 | name = "sysroot", 47 | incoming_transition = "//platforms/stage1:library", 48 | visibility = ["toolchains//:rust"], 49 | deps = [":std"], 50 | ) 51 | -------------------------------------------------------------------------------- /stage1/defs.bzl: -------------------------------------------------------------------------------- 1 | load("@prelude//linking:link_info.bzl", "LinkStrategy") 2 | load("@prelude//rust:build_params.bzl", "MetadataKind") 3 | load("@prelude//rust:context.bzl", "DepCollectionContext") 4 | load("@prelude//rust:link_info.bzl", "RustDependency", "RustLinkInfo", "resolve_deps") 5 | load("@prelude//rust:rust_toolchain.bzl", "PanicRuntime", "RustToolchainInfo") 6 | 7 | SYSROOT_CRATES = [ 8 | "alloc", 9 | "compiler_builtins", 10 | "core", 11 | "panic_abort", 12 | "panic_unwind", 13 | "proc_macro", 14 | "std", 15 | "test", 16 | ] 17 | 18 | def _rust_tool_impl(ctx: AnalysisContext) -> list[Provider]: 19 | llvm = ctx.actions.symlinked_dir( 20 | "llvm", 21 | { 22 | "lib": ctx.attrs.llvm[DefaultInfo].default_outputs[0].project("lib"), 23 | }, 24 | ) 25 | 26 | bin_path = "bin/{}".format(ctx.label.name) 27 | dist = ctx.actions.copied_dir( 28 | "toolchain", 29 | { 30 | bin_path: ctx.attrs.exe[DefaultInfo].default_outputs[0], 31 | "lib": llvm.project("lib"), 32 | }, 33 | ) 34 | 35 | tool = dist.project(bin_path) 36 | 37 | return [ 38 | DefaultInfo( 39 | default_output = tool, 40 | sub_targets = { 41 | name: [providers[DefaultInfo]] 42 | for name, providers in ctx.attrs.exe[DefaultInfo].sub_targets.items() 43 | }, 44 | ), 45 | RunInfo(tool), 46 | ] 47 | 48 | rust_tool = rule( 49 | impl = _rust_tool_impl, 50 | attrs = { 51 | "exe": attrs.dep(), 52 | "llvm": attrs.dep(), 53 | }, 54 | supports_incoming_transition = True, 55 | ) 56 | 57 | def _sysroot_impl(ctx: AnalysisContext) -> list[Provider]: 58 | dep_ctx = DepCollectionContext( 59 | advanced_unstable_linking = True, 60 | include_doc_deps = False, 61 | is_proc_macro = False, 62 | explicit_sysroot_deps = None, 63 | panic_runtime = PanicRuntime("unwind"), 64 | ) 65 | 66 | all_deps = resolve_deps(ctx = ctx, dep_ctx = dep_ctx) 67 | 68 | rust_deps = [] 69 | for crate in all_deps: 70 | rust_deps.append(RustDependency( 71 | info = crate.dep[RustLinkInfo], 72 | label = crate.dep.label, 73 | dep = crate.dep, 74 | name = crate.name, 75 | flags = crate.flags, 76 | proc_macro_marker = None, 77 | )) 78 | 79 | rustc_target_triple = ctx.attrs.rust_toolchain[RustToolchainInfo].rustc_target_triple 80 | 81 | sysroot = {} 82 | for dep in rust_deps: 83 | strategy = dep.info.strategies[LinkStrategy("static_pic")] 84 | dep_metadata_kind = MetadataKind("full") 85 | artifact = strategy.outputs[dep_metadata_kind] 86 | path = "lib/rustlib/{}/lib/{}".format(rustc_target_triple, artifact.basename) 87 | sysroot[path] = artifact 88 | 89 | for artifact in strategy.transitive_deps[dep_metadata_kind].keys(): 90 | path = "lib/rustlib/{}/lib/{}".format(rustc_target_triple, artifact.basename) 91 | sysroot[path] = artifact 92 | 93 | sysroot = ctx.actions.symlinked_dir("sysroot", sysroot) 94 | return [DefaultInfo(default_output = sysroot)] 95 | 96 | sysroot = rule( 97 | impl = _sysroot_impl, 98 | attrs = { 99 | "deps": attrs.list(attrs.dep()), 100 | "named_deps": attrs.default_only(attrs.dict(key = attrs.string(), value = attrs.dep(), default = {})), 101 | "flagged_deps": attrs.default_only(attrs.list(attrs.tuple(attrs.dep(), attrs.list(attrs.string())), default = [])), 102 | "rust_toolchain": attrs.default_only(attrs.toolchain_dep(providers = [RustToolchainInfo], default = "toolchains//:rust")), 103 | }, 104 | supports_incoming_transition = True, 105 | ) 106 | -------------------------------------------------------------------------------- /stage2/BUCK: -------------------------------------------------------------------------------- 1 | load("//constraints:defs.bzl", "transition_alias") 2 | load("//stage1:defs.bzl", "SYSROOT_CRATES", "rust_tool", "sysroot") 3 | 4 | [ 5 | transition_alias( 6 | name = crate, 7 | actual = "//:{}".format(crate), 8 | incoming_transition = "//platforms/stage2:library", 9 | visibility = ["PUBLIC"], 10 | ) 11 | for crate in SYSROOT_CRATES 12 | ] 13 | 14 | transition_alias( 15 | name = "rust_allocator", 16 | actual = "//allocator:rust_allocator", 17 | incoming_transition = "//platforms/stage2:library", 18 | visibility = ["toolchains//:rust"], 19 | ) 20 | 21 | rust_tool( 22 | name = "rustc", 23 | exe = "//:rustc-main-rustc-main", 24 | incoming_transition = "//platforms/stage2:compiler", 25 | llvm = "//stage0:ci_llvm", 26 | visibility = ["toolchains//:rust"], 27 | ) 28 | 29 | rust_tool( 30 | name = "rustdoc", 31 | exe = "//:rustdoc-tool-rustdoc_tool_binary", 32 | incoming_transition = "//platforms/stage2:compiler", 33 | llvm = "//stage0:ci_llvm", 34 | visibility = ["toolchains//:rust"], 35 | ) 36 | 37 | rust_tool( 38 | name = "clippy-driver", 39 | exe = "//:clippy-clippy-driver", 40 | incoming_transition = "//platforms/stage2:compiler", 41 | llvm = "//stage0:ci_llvm", 42 | visibility = ["toolchains//:rust"], 43 | ) 44 | 45 | sysroot( 46 | name = "sysroot", 47 | incoming_transition = "//platforms/stage2:library", 48 | visibility = ["toolchains//:rust"], 49 | deps = [":std"], 50 | ) 51 | -------------------------------------------------------------------------------- /submodule_init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | cd -P -- "$(dirname -- "$0")" 5 | 6 | git submodule update --init rust 7 | cd rust 8 | git submodule update --init library/backtrace 9 | git submodule update --init library/stdarch 10 | -------------------------------------------------------------------------------- /toolchains/BUCK: -------------------------------------------------------------------------------- 1 | load("@prelude//tests:test_toolchain.bzl", "noop_test_toolchain") 2 | load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain") 3 | load("@prelude//toolchains:remote_test_execution.bzl", "remote_test_execution_toolchain") 4 | load(":cxx.bzl", "cxx_toolchain") 5 | load(":rust.bzl", "rust_toolchain") 6 | 7 | system_python_bootstrap_toolchain( 8 | name = "python_bootstrap", 9 | visibility = ["PUBLIC"], 10 | ) 11 | 12 | cxx_toolchain( 13 | name = "cxx", 14 | c_flags = select({ 15 | "DEFAULT": [], 16 | "rust//constraints:opt-level=0": ["-O0"], 17 | "rust//constraints:opt-level=3": ["-O3"], 18 | }), 19 | cxx_flags = select({ 20 | "DEFAULT": [], 21 | "prelude//os:linux": ["-stdlib=libstdc++"], 22 | }) + select({ 23 | "DEFAULT": [], 24 | "rust//constraints:opt-level=0": ["-O0"], 25 | "rust//constraints:opt-level=3": ["-O3"], 26 | }), 27 | visibility = ["PUBLIC"], 28 | ) 29 | 30 | rust_toolchain( 31 | name = "rust", 32 | clippy_driver = select({ 33 | "rust//constraints:stage1": "rust//stage0:clippy-driver", 34 | "rust//constraints:stage2": "rust//stage1:clippy-driver", 35 | }), 36 | compiler = select({ 37 | "rust//constraints:stage1": "rust//stage0:rustc", 38 | "rust//constraints:stage2": select({ 39 | "rust//constraints:sysroot-deps=explicit": "rust//stage1:rustc", 40 | "rust//constraints:sysroot-deps=implicit": select({ 41 | "rust//constraints:library": "rust//stage0:rustc", 42 | "rust//constraints:compiler": "rust//stage1:rustc", 43 | }), 44 | }), 45 | }), 46 | exec_compatible_with = [ 47 | "rust//constraints:opt-level=0", 48 | "rust//constraints:sysroot-deps=implicit", 49 | ] + select({ 50 | "rust//constraints:compiler": ["rust//constraints:compiler"], 51 | "rust//constraints:library": ["rust//constraints:library"], 52 | }) + select({ 53 | "rust//constraints:stage1": ["rust//constraints:stage1"], 54 | "rust//constraints:stage2": ["rust//constraints:stage2"], 55 | }), 56 | rustc_flags = [ 57 | "-Zunstable-options", 58 | select({ 59 | "rust//constraints:opt-level=0": "-Copt-level=0", 60 | "rust//constraints:opt-level=3": "-Copt-level=3", 61 | }), 62 | ] + select({ 63 | "rust//constraints:stage1": ["--cfg=bootstrap"], 64 | "rust//constraints:stage2": [], 65 | }) + select({ 66 | "DEFAULT": [], 67 | "prelude//os:linux": ["-Clink-arg=-Wl,--undefined-version"], 68 | }), 69 | rustdoc = select({ 70 | "rust//constraints:stage1": "rust//stage0:rustdoc", 71 | "rust//constraints:stage2": "rust//stage1:rustdoc", 72 | }), 73 | sysroot = select({ 74 | "rust//constraints:sysroot-deps=explicit": None, 75 | "rust//constraints:sysroot-deps=implicit": select({ 76 | "rust//constraints:library": "rust//stage0:sysroot", 77 | "rust//constraints:compiler": select({ 78 | "rust//constraints:stage1": dict( 79 | alloc = "rust//stage1:alloc", 80 | compiler_builtins = "rust//stage1:compiler_builtins", 81 | core = "rust//stage1:core", 82 | panic_abort = "rust//stage1:panic_abort", 83 | panic_unwind = "rust//stage1:panic_unwind", 84 | proc_macro = "rust//stage1:proc_macro", 85 | rust_allocator = "rust//stage1:rust_allocator", 86 | std = "rust//stage1:std", 87 | test = "rust//stage1:test", 88 | ), 89 | "rust//constraints:stage2": dict( 90 | alloc = "rust//stage2:alloc", 91 | compiler_builtins = "rust//stage2:compiler_builtins", 92 | core = "rust//stage2:core", 93 | panic_abort = "rust//stage2:panic_abort", 94 | panic_unwind = "rust//stage2:panic_unwind", 95 | proc_macro = "rust//stage2:proc_macro", 96 | rust_allocator = "rust//stage2:rust_allocator", 97 | std = "rust//stage2:std", 98 | test = "rust//stage2:test", 99 | ), 100 | }), 101 | }), 102 | }), 103 | visibility = ["PUBLIC"], 104 | ) 105 | 106 | noop_test_toolchain( 107 | name = "test", 108 | visibility = ["PUBLIC"], 109 | ) 110 | 111 | remote_test_execution_toolchain( 112 | name = "remote_test_execution", 113 | visibility = ["PUBLIC"], 114 | ) 115 | -------------------------------------------------------------------------------- /toolchains/cxx.bzl: -------------------------------------------------------------------------------- 1 | load( 2 | "@prelude//cxx:cxx_toolchain_types.bzl", 3 | "BinaryUtilitiesInfo", 4 | "CCompilerInfo", 5 | "CxxCompilerInfo", 6 | "CxxInternalTools", 7 | "CxxPlatformInfo", 8 | "CxxToolchainInfo", 9 | "LinkerInfo", 10 | "LinkerType", 11 | "PicBehavior", 12 | "ShlibInterfacesMode", 13 | ) 14 | load("@prelude//cxx:headers.bzl", "HeaderMode") 15 | load("@prelude//linking:link_info.bzl", "LinkStyle") 16 | load("@prelude//linking:lto.bzl", "LtoMode") 17 | load("@prelude//os_lookup:defs.bzl", "Os", "OsLookup") 18 | load("@prelude//toolchains:cxx.bzl", "CxxToolsInfo") 19 | load("//target:target_triple.bzl", "TargetTriple") 20 | 21 | def _cxx_toolchain_impl(ctx: AnalysisContext): 22 | target = ctx.attrs._target_os_type[OsLookup] 23 | target_triple = ctx.attrs.target_triple[TargetTriple].value 24 | tools = ctx.attrs._cxx_tools_info[CxxToolsInfo] 25 | 26 | linker_flags = [] 27 | if target.os == Os("linux") and tools.linker != "g++" and tools.cxx_compiler != "g++": 28 | linker_flags.append("-fuse-ld=lld") 29 | 30 | if target.os == Os("windows"): 31 | binary_extension = "exe" 32 | object_file_extension = "obj" 33 | static_library_extension = "lib" 34 | shared_library_name_default_prefix = "" 35 | shared_library_name_format = "{}.dll" 36 | shared_library_versioned_name_format = "{}.dll" 37 | linker_type = LinkerType("windows") 38 | pic_behavior = PicBehavior("not_supported") 39 | else: 40 | binary_extension = "" 41 | object_file_extension = "o" 42 | static_library_extension = "a" 43 | shared_library_name_default_prefix = "lib" 44 | shared_library_name_format = "{}.so" 45 | shared_library_versioned_name_format = "{}.so.{}" 46 | if target.os == Os("macos"): 47 | linker_type = LinkerType("darwin") 48 | pic_behavior = PicBehavior("always_enabled") 49 | else: 50 | linker_type = LinkerType("gnu") 51 | pic_behavior = PicBehavior("supported") 52 | 53 | return [ 54 | DefaultInfo(), 55 | CxxPlatformInfo( 56 | name = "{}-{}".format(target.os, target.cpu), 57 | ), 58 | CxxToolchainInfo( 59 | internal_tools = ctx.attrs._internal_tools[CxxInternalTools], 60 | linker_info = LinkerInfo( 61 | type = linker_type, 62 | linker = RunInfo(tools.linker), 63 | linker_flags = linker_flags, 64 | archiver = RunInfo(tools.archiver), 65 | archiver_type = tools.archiver_type, 66 | lto_mode = LtoMode("none"), 67 | link_binaries_locally = True, 68 | archive_objects_locally = True, 69 | use_archiver_flags = True, 70 | shlib_interfaces = ShlibInterfacesMode("disabled"), 71 | link_style = LinkStyle("shared"), 72 | binary_extension = binary_extension, 73 | object_file_extension = object_file_extension, 74 | static_library_extension = static_library_extension, 75 | shared_library_name_default_prefix = shared_library_name_default_prefix, 76 | shared_library_name_format = shared_library_name_format, 77 | shared_library_versioned_name_format = shared_library_versioned_name_format, 78 | ), 79 | binary_utilities_info = BinaryUtilitiesInfo( 80 | strip = RunInfo("strip"), 81 | ), 82 | cxx_compiler_info = CxxCompilerInfo( 83 | compiler = RunInfo(tools.cxx_compiler), 84 | compiler_flags = ["--target={}".format(target_triple)] + ctx.attrs.cxx_flags, 85 | compiler_type = tools.compiler_type, 86 | ), 87 | c_compiler_info = CCompilerInfo( 88 | compiler = RunInfo(tools.compiler), 89 | compiler_flags = ["--target={}".format(target_triple)] + ctx.attrs.c_flags, 90 | compiler_type = tools.compiler_type, 91 | ), 92 | as_compiler_info = CCompilerInfo( 93 | compiler = RunInfo(tools.compiler), 94 | compiler_flags = ["--target={}".format(target_triple)], 95 | compiler_type = tools.compiler_type, 96 | ), 97 | asm_compiler_info = CCompilerInfo( 98 | compiler = RunInfo(tools.asm_compiler), 99 | compiler_flags = ["--target={}".format(target_triple)], 100 | compiler_type = tools.asm_compiler_type, 101 | ), 102 | header_mode = HeaderMode("symlink_tree_only"), 103 | pic_behavior = pic_behavior, 104 | ), 105 | ] 106 | 107 | cxx_toolchain = rule( 108 | impl = _cxx_toolchain_impl, 109 | attrs = { 110 | "c_flags": attrs.list(attrs.arg(), default = []), 111 | "cxx_flags": attrs.list(attrs.arg(), default = []), 112 | "target_triple": attrs.default_only(attrs.dep(providers = [TargetTriple], default = "//target:target_triple")), 113 | "_cxx_tools_info": attrs.exec_dep(providers = [CxxToolsInfo], default = "prelude//toolchains/msvc:msvc_tools" if host_info().os.is_windows else "prelude//toolchains/cxx/clang:path_clang_tools"), 114 | "_internal_tools": attrs.default_only(attrs.exec_dep(providers = [CxxInternalTools], default = "prelude//cxx/tools:internal_tools")), 115 | "_target_os_type": attrs.default_only(attrs.dep(providers = [OsLookup], default = "prelude//os_lookup/targets:os_lookup")), 116 | }, 117 | is_toolchain_rule = True, 118 | ) 119 | -------------------------------------------------------------------------------- /toolchains/cxx/BUCK: -------------------------------------------------------------------------------- 1 | load("@rust//constraints:defs.bzl", "configuration_transition") 2 | 3 | # Transition to share identical C++ compilations between stage1 and stage2. 4 | configuration_transition( 5 | name = "prune_cxx_configuration", 6 | discard_settings = [ 7 | "rust//constraints:bootstrap-stage", 8 | "rust//constraints:reindeer-universe", 9 | "rust//constraints:sysroot-deps", 10 | ], 11 | label = "cxx", 12 | ) 13 | 14 | prebuilt_cxx_library( 15 | name = "stdlib", 16 | default_target_platform = "rust//platforms:host", 17 | exported_linker_flags = select({ 18 | "DEFAULT": None, 19 | "prelude//os:linux": ["-lstdc++"], 20 | "prelude//os:macos": ["-lc++"], 21 | }), 22 | visibility = ["PUBLIC"], 23 | ) 24 | -------------------------------------------------------------------------------- /toolchains/rust.bzl: -------------------------------------------------------------------------------- 1 | load( 2 | "@prelude//rust:rust_toolchain.bzl", 3 | "PanicRuntime", 4 | "RustExplicitSysrootDeps", 5 | "RustToolchainInfo", 6 | ) 7 | load("//target:target_triple.bzl", "TargetTriple") 8 | 9 | def _rust_toolchain_impl(ctx: AnalysisContext) -> list[Provider]: 10 | sysroot_path = None 11 | explicit_sysroot_deps = None 12 | sub_targets = {} 13 | if ctx.attrs.sysroot == None: 14 | explicit_sysroot_deps = RustExplicitSysrootDeps( 15 | core = None, 16 | proc_macro = None, 17 | std = None, 18 | panic_unwind = None, 19 | panic_abort = None, 20 | others = [], 21 | ) 22 | elif isinstance(ctx.attrs.sysroot, dict): 23 | sub_targets = { 24 | name: list(dep.providers) 25 | for name, dep in ctx.attrs.sysroot.items() 26 | } 27 | explicit_sysroot_deps = RustExplicitSysrootDeps( 28 | core = ctx.attrs.sysroot.pop("core", None), 29 | proc_macro = ctx.attrs.sysroot.pop("proc_macro", None), 30 | std = ctx.attrs.sysroot.pop("std", None), 31 | panic_unwind = ctx.attrs.sysroot.pop("panic_unwind", None), 32 | panic_abort = ctx.attrs.sysroot.pop("panic_abort", None), 33 | others = ctx.attrs.sysroot.values(), 34 | ) 35 | elif isinstance(ctx.attrs.sysroot, Dependency): 36 | sysroot_path = ctx.attrs.sysroot[DefaultInfo].default_outputs[0] 37 | 38 | return [ 39 | DefaultInfo(sub_targets = sub_targets), 40 | RustToolchainInfo( 41 | advanced_unstable_linking = True, 42 | clippy_driver = ctx.attrs.clippy_driver[RunInfo], 43 | compiler = ctx.attrs.compiler[RunInfo], 44 | explicit_sysroot_deps = explicit_sysroot_deps, 45 | panic_runtime = PanicRuntime("unwind"), 46 | rustc_flags = ctx.attrs.rustc_flags, 47 | rustc_target_triple = ctx.attrs.target_triple[TargetTriple].value, 48 | rustdoc = ctx.attrs.rustdoc[RunInfo], 49 | rustdoc_flags = ctx.attrs.rustdoc_flags, 50 | sysroot_path = sysroot_path, 51 | ), 52 | ] 53 | 54 | rust_toolchain = rule( 55 | impl = _rust_toolchain_impl, 56 | attrs = { 57 | "clippy_driver": attrs.exec_dep(providers = [RunInfo]), 58 | "compiler": attrs.exec_dep(providers = [RunInfo]), 59 | "rustc_flags": attrs.list(attrs.arg(), default = []), 60 | "rustdoc": attrs.exec_dep(providers = [RunInfo]), 61 | "rustdoc_flags": attrs.list(attrs.arg(), default = []), 62 | "sysroot": attrs.one_of( 63 | # None = no sysroot deps 64 | # Artifact = path to implicit sysroot deps 65 | # Dict = explicit sysroot deps 66 | attrs.option(attrs.dep()), 67 | attrs.dict(key = attrs.string(), value = attrs.dep()), 68 | ), 69 | "target_triple": attrs.default_only(attrs.dep(providers = [TargetTriple], default = "//target:target_triple")), 70 | }, 71 | is_toolchain_rule = True, 72 | ) 73 | -------------------------------------------------------------------------------- /toolchains/rust/BUCK: -------------------------------------------------------------------------------- 1 | load(":defs.bzl", "toolchain_sysroot") 2 | 3 | toolchain_sysroot( 4 | name = "sysroot", 5 | visibility = ["PUBLIC"], 6 | ) 7 | -------------------------------------------------------------------------------- /toolchains/rust/defs.bzl: -------------------------------------------------------------------------------- 1 | def _toolchain_sysroot_impl(ctx: AnalysisContext) -> list[Provider]: 2 | return [ctx.attrs.rust_toolchain[DefaultInfo]] 3 | 4 | toolchain_sysroot = rule( 5 | impl = _toolchain_sysroot_impl, 6 | attrs = { 7 | "rust_toolchain": attrs.default_only(attrs.toolchain_dep(default = "toolchains//:rust")), 8 | }, 9 | ) 10 | -------------------------------------------------------------------------------- /toolchains/target/BUCK: -------------------------------------------------------------------------------- 1 | load(":target_triple.bzl", "target_triple") 2 | 3 | target_triple( 4 | name = "target_triple", 5 | incoming_transition = "rust//stage0:stage0_configuration", 6 | value = select({ 7 | "prelude//os:linux": select({ 8 | "prelude//cpu:arm64": "aarch64-unknown-linux-gnu", 9 | "prelude//cpu:x86_64": "x86_64-unknown-linux-gnu", 10 | }), 11 | "prelude//os:macos": select({ 12 | "prelude//cpu:arm64": "aarch64-apple-darwin", 13 | "prelude//cpu:x86_64": "x86_64-apple-darwin", 14 | }), 15 | "prelude//os:windows": select({ 16 | "prelude//cpu:arm64": "aarch64-pc-windows-msvc", 17 | "prelude//cpu:x86_64": "x86_64-pc-windows-msvc", 18 | }), 19 | }), 20 | visibility = ["PUBLIC"], 21 | ) 22 | -------------------------------------------------------------------------------- /toolchains/target/target_triple.bzl: -------------------------------------------------------------------------------- 1 | TargetTriple = provider(fields = { 2 | "value": str, 3 | }) 4 | 5 | def _target_triple_impl(ctx: AnalysisContext) -> list[Provider]: 6 | return [ 7 | DefaultInfo(), 8 | TargetTriple(value = ctx.attrs.value), 9 | TemplatePlaceholderInfo( 10 | unkeyed_variables = { 11 | "target_triple": ctx.attrs.value, 12 | }, 13 | ), 14 | ] 15 | 16 | target_triple = rule( 17 | impl = _target_triple_impl, 18 | attrs = {"value": attrs.string()}, 19 | supports_incoming_transition = True, 20 | ) 21 | --------------------------------------------------------------------------------