about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-09-13 03:26:01 -0400
committerGitHub <noreply@github.com>2025-09-13 03:26:01 -0400
commit544644476d9c304648801dae76d85b1c17fc35d1 (patch)
treeceeb6ffcfbe92d361b50563382d416df6a2663d3 /src
parent9642c0ef6749e57ce76ac153807df1cc38cd26ee (diff)
parentf157ce994ea45e9faea9eff89c5f8b3d4ea77b6e (diff)
downloadrust-544644476d9c304648801dae76d85b1c17fc35d1.tar.gz
rust-544644476d9c304648801dae76d85b1c17fc35d1.zip
Rollup merge of #144498 - Noratrieb:rustc-json-schema, r=jieyouxu,davidtwco
Add --print target-spec-json-schema

This schema is helpful for people writing custom target spec JSON. It can provide autocomplete in the editor, and also serves as documentation when there are documentation comments on the structs, as `schemars` will put them in the schema.

I was motivated to do this because I saw someone write their own version of this schema by hand, so demand for this clearly exists. It's not a lot of effort to implement, so I thought it would make sense.

MCP: https://github.com/rust-lang/compiler-team/issues/905

I think it would also be useful to put this in the sysroot in `etc` so people can link it directly in their editors.

I would have loved to add a test that validates the JSON schema against the spec JSON of every builtin target, but I don't want to do it as the JSON schema validation crates have incredible amounts of dependencies because JSON schema supports a ton of random features. I don't want to add that, even as a dev dependency.
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs24
-rw-r--r--src/bootstrap/src/utils/proc_macro_deps.rs1
-rw-r--r--src/doc/rustc/src/targets/custom.md15
-rw-r--r--src/tools/tidy/src/deps.rs6
4 files changed, 46 insertions, 0 deletions
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index a5f0718bc01..99a1062109a 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -590,6 +590,8 @@ impl Step for Rustc {
             // Debugger scripts
             builder.ensure(DebuggerScripts { sysroot: image.to_owned(), target });
 
+            generate_target_spec_json_schema(builder, image);
+
             // HTML copyright files
             let file_list = builder.ensure(super::run::GenerateCopyright);
             for file in file_list {
@@ -618,6 +620,28 @@ impl Step for Rustc {
     }
 }
 
+fn generate_target_spec_json_schema(builder: &Builder<'_>, sysroot: &Path) {
+    // Since we run rustc in bootstrap, we need to ensure that we use the host compiler.
+    // We do this by using the stage 1 compiler, which is always compiled for the host,
+    // even in a cross build.
+    let stage1_host = builder.compiler(1, builder.host_target);
+    let mut rustc = command(builder.rustc(stage1_host)).fail_fast();
+    rustc
+        .env("RUSTC_BOOTSTRAP", "1")
+        .args(["--print=target-spec-json-schema", "-Zunstable-options"]);
+    let schema = rustc.run_capture(builder).stdout();
+
+    let schema_dir = tmpdir(builder);
+    t!(fs::create_dir_all(&schema_dir));
+    let schema_file = schema_dir.join("target-spec-json-schema.json");
+    t!(std::fs::write(&schema_file, schema));
+
+    let dst = sysroot.join("etc");
+    t!(fs::create_dir_all(&dst));
+
+    builder.install(&schema_file, &dst, FileType::Regular);
+}
+
 /// Copies debugger scripts for `target` into the given compiler `sysroot`.
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct DebuggerScripts {
diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs
index 777c8601aa1..db2369097d6 100644
--- a/src/bootstrap/src/utils/proc_macro_deps.rs
+++ b/src/bootstrap/src/utils/proc_macro_deps.rs
@@ -43,6 +43,7 @@ pub static CRATES: &[&str] = &[
     "rustc-hash",
     "self_cell",
     "serde",
+    "serde_derive_internals",
     "sha2",
     "smallvec",
     "stable_deref_trait",
diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md
index 6c1494186a4..e1750e27f0b 100644
--- a/src/doc/rustc/src/targets/custom.md
+++ b/src/doc/rustc/src/targets/custom.md
@@ -16,6 +16,21 @@ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print targe
 
 To use a custom target, see the (unstable) [`build-std` feature](../../cargo/reference/unstable.html#build-std) of `cargo`.
 
+<div class="warning">
+
+The target JSON properties are not stable and subject to change.
+Always pin your compiler version when using custom targets!
+
+</div>
+
+## JSON Schema
+
+`rustc` provides a JSON schema for the custom target JSON specification.
+Because the schema is subject to change, you should always use the schema from the version of rustc which you are passing the target to.
+
+It can be found in `etc/target-spec-json-schema.json` in the sysroot (`rustc --print sysroot`) or printed with `rustc +nightly -Zunstable-options --print target-spec-json-schema`.
+The existence and name of this schema is, just like the properties of the JSON specification, not stable and subject to change.
+
 ## Custom Target Lookup Path
 
 When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic:
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 60347b2ea64..a9804761400 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -267,6 +267,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "digest",
     "displaydoc",
     "dissimilar",
+    "dyn-clone",
     "either",
     "elsa",
     "ena",
@@ -346,6 +347,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "rand_xorshift", // dependency for doc-tests in rustc_thread_pool
     "rand_xoshiro",
     "redox_syscall",
+    "ref-cast",
+    "ref-cast-impl",
     "regex",
     "regex-automata",
     "regex-syntax",
@@ -357,11 +360,14 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "rustix",
     "ruzstd", // via object in thorin-dwp
     "ryu",
+    "schemars",
+    "schemars_derive",
     "scoped-tls",
     "scopeguard",
     "self_cell",
     "serde",
     "serde_derive",
+    "serde_derive_internals",
     "serde_json",
     "serde_path_to_error",
     "sha1",