1use std::collections::BTreeMap;
2use std::str::FromStr;
3
4use rustc_abi::{Align, AlignFromBytesError};
5
6use super::crt_objects::CrtObjects;
7use super::{
8 Abi, Arch, BinaryFormat, CodeModel, DebuginfoKind, Env, FloatAbi, FramePointer, LinkArgsCli,
9 LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor,
10 MergeFunctions, Os, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet,
11 SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target,
12 TargetKind, TargetOptions, TargetWarnings, TlsModel,
13};
14use crate::json::{Json, ToJson};
15use crate::spec::AbiMap;
16
17impl Target {
18 pub fn from_json(json: &str) -> Result<(Target, TargetWarnings), String> {
20 let json_deserializer = &mut serde_json::Deserializer::from_str(json);
21
22 let json: TargetSpecJson =
23 serde_path_to_error::deserialize(json_deserializer).map_err(|err| err.to_string())?;
24
25 let mut base = Target {
26 llvm_target: json.llvm_target,
27 metadata: Default::default(),
28 pointer_width: json.target_pointer_width,
29 data_layout: json.data_layout,
30 arch: json.arch,
31 options: Default::default(),
32 };
33
34 if let Some(metadata) = json.metadata {
38 base.metadata.description = metadata.description;
39 base.metadata.tier = metadata.tier.filter(|tier| (1..=3).contains(tier));
40 base.metadata.host_tools = metadata.host_tools;
41 base.metadata.std = metadata.std;
42 }
43
44 let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String {
45 let msg = match error {
46 AlignFromBytesError::NotPowerOfTwo(_) => "not a power of 2 number of bytes",
47 AlignFromBytesError::TooLarge(_) => "too large",
48 };
49 format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8)
50 };
51
52 macro_rules! forward {
53 ($name:ident) => {
54 if let Some($name) = json.$name {
55 base.$name = $name;
56 }
57 };
58 }
59 macro_rules! forward_opt {
60 ($name:ident) => {
61 if let Some($name) = json.$name {
62 base.$name = Some($name);
63 }
64 };
65 }
66
67 if let Some(target_endian) = json.target_endian {
68 base.endian = target_endian.0;
69 }
70
71 forward!(frame_pointer);
72 forward!(c_int_width);
73 forward_opt!(c_enum_min_bits); forward!(os);
75 forward!(env);
76 forward!(abi);
77 forward!(vendor);
78 forward_opt!(linker);
79 forward!(linker_flavor_json);
80 forward!(lld_flavor_json);
81 forward!(linker_is_gnu_json);
82 forward!(pre_link_objects);
83 forward!(post_link_objects);
84 forward!(pre_link_objects_self_contained);
85 forward!(post_link_objects_self_contained);
86
87 if let Some(link_self_contained) = json.link_self_contained_backwards_compatible {
89 base.link_self_contained = link_self_contained;
90 }
91 if let Some(link_self_contained) = json.link_self_contained {
93 let components = link_self_contained
94 .components
95 .into_iter()
96 .fold(LinkSelfContainedComponents::empty(), |a, b| a | b);
97 base.link_self_contained = LinkSelfContainedDefault::WithComponents(components);
98 }
99
100 forward!(pre_link_args_json);
101 forward!(late_link_args_json);
102 forward!(late_link_args_dynamic_json);
103 forward!(late_link_args_static_json);
104 forward!(post_link_args_json);
105 forward_opt!(link_script);
106
107 if let Some(link_env) = json.link_env {
108 for s in link_env {
109 if let [k, v] = *s.split('=').collect::<Vec<_>>() {
110 base.link_env.to_mut().push((k.to_string().into(), v.to_string().into()))
111 } else {
112 return Err(format!("link-env value '{s}' must be of the pattern 'KEY=VALUE'"));
113 }
114 }
115 }
116
117 forward!(link_env_remove);
118 forward!(asm_args);
119 forward!(cpu);
120 forward!(need_explicit_cpu);
121 forward!(features);
122 forward!(dynamic_linking);
123 forward_opt!(direct_access_external_data);
124 forward!(dll_tls_export);
125 forward!(only_cdylib);
126 forward!(executables);
127 forward!(relocation_model);
128 forward_opt!(code_model);
129 forward!(tls_model);
130 forward!(disable_redzone);
131 forward!(function_sections);
132 forward!(dll_prefix);
133 forward!(dll_suffix);
134 forward!(exe_suffix);
135 forward!(staticlib_prefix);
136 forward!(staticlib_suffix);
137
138 if let Some(target_family) = json.target_family {
139 match target_family {
140 TargetFamiliesJson::Array(families) => base.families = families,
141 TargetFamiliesJson::String(family) => base.families = vec![family].into(),
142 }
143 }
144
145 forward!(abi_return_struct_as_int);
146 forward!(is_like_aix);
147 forward!(is_like_darwin);
148 forward!(is_like_solaris);
149 forward!(is_like_windows);
150 forward!(is_like_gpu);
151 forward!(is_like_msvc);
152 forward!(is_like_wasm);
153 forward!(is_like_android);
154 forward!(is_like_vexos);
155 forward!(binary_format);
156 forward!(default_dwarf_version);
157 forward!(allows_weak_linkage);
158 forward!(has_rpath);
159 forward!(no_default_libraries);
160 forward!(position_independent_executables);
161 forward!(static_position_independent_executables);
162 forward!(plt_by_default);
163 forward!(relro_level);
164 forward!(archive_format);
165 forward!(allow_asm);
166 forward!(static_initializer_must_be_acyclic);
167 forward!(main_needs_argc_argv);
168 forward!(has_thread_local);
169 forward!(obj_is_bitcode);
170 forward_opt!(max_atomic_width);
171 forward_opt!(min_atomic_width);
172 forward!(atomic_cas);
173 forward!(panic_strategy);
174 forward!(crt_static_allows_dylibs);
175 forward!(crt_static_default);
176 forward!(crt_static_respected);
177 forward!(stack_probes);
178
179 if let Some(min_global_align) = json.min_global_align {
180 match Align::from_bits(min_global_align) {
181 Ok(align) => base.min_global_align = Some(align),
182 Err(e) => return Err(alignment_error("min-global-align", e)),
183 }
184 }
185
186 forward_opt!(default_codegen_units);
187 forward_opt!(default_codegen_backend);
188 forward!(trap_unreachable);
189 forward!(requires_lto);
190 forward!(singlethread);
191 forward!(no_builtins);
192 forward_opt!(default_visibility);
193 forward!(emit_debug_gdb_scripts);
194 forward!(requires_uwtable);
195 forward!(default_uwtable);
196 forward!(simd_types_indirect);
197 forward!(limit_rdylib_exports);
198 forward_opt!(override_export_symbols);
199 forward!(merge_functions);
200 forward!(mcount);
201 forward_opt!(llvm_mcount_intrinsic);
202 forward!(llvm_abiname);
203 forward_opt!(llvm_floatabi);
204 forward_opt!(rustc_abi);
205 forward!(relax_elf_relocations);
206 forward!(llvm_args);
207 forward!(use_ctors_section);
208 forward!(eh_frame_header);
209 forward!(has_thumb_interworking);
210 forward!(debuginfo_kind);
211 forward!(split_debuginfo);
212 forward!(supported_split_debuginfo);
213
214 if let Some(supported_sanitizers) = json.supported_sanitizers {
215 base.supported_sanitizers =
216 supported_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
217 }
218
219 if let Some(default_sanitizers) = json.default_sanitizers {
220 base.default_sanitizers =
221 default_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
222 }
223
224 forward!(generate_arange_section);
225 forward!(supports_stack_protector);
226 forward!(small_data_threshold_support);
227 forward!(entry_name);
228 forward!(supports_xray);
229
230 let abi_map = AbiMap::from_target(&base);
233 if let Some(entry_abi) = json.entry_abi {
234 base.options.entry_abi = abi_map.canonize_abi(entry_abi.0, false).unwrap();
235 }
236
237 base.update_from_cli();
238 base.check_consistency(TargetKind::Json)?;
239
240 Ok((base, TargetWarnings { unused_fields: vec![] }))
241 }
242}
243
244impl ToJson for Target {
245 fn to_json(&self) -> Json {
246 let mut d = serde_json::Map::new();
247 let default: TargetOptions = Default::default();
248 let mut target = self.clone();
249 target.update_to_cli();
250
251 macro_rules! target_val {
252 ($attr:ident) => {
253 target_val!($attr, (stringify!($attr)).replace("_", "-"))
254 };
255 ($attr:ident, $json_name:expr) => {{
256 let name = $json_name;
257 d.insert(name.into(), target.$attr.to_json());
258 }};
259 }
260
261 macro_rules! target_option_val {
262 ($attr:ident) => {{ target_option_val!($attr, (stringify!($attr)).replace("_", "-")) }};
263 ($attr:ident, $json_name:expr) => {{
264 let name = $json_name;
265 #[allow(rustc::bad_opt_access)]
266 if default.$attr != target.$attr {
267 d.insert(name.into(), target.$attr.to_json());
268 }
269 }};
270 (link_args - $attr:ident, $json_name:expr) => {{
271 let name = $json_name;
272 if default.$attr != target.$attr {
273 let obj = target
274 .$attr
275 .iter()
276 .map(|(k, v)| (k.desc().to_string(), v.clone()))
277 .collect::<BTreeMap<_, _>>();
278 d.insert(name.to_string(), obj.to_json());
279 }
280 }};
281 (env - $attr:ident) => {{
282 let name = (stringify!($attr)).replace("_", "-");
283 if default.$attr != target.$attr {
284 let obj = target
285 .$attr
286 .iter()
287 .map(|&(ref k, ref v)| format!("{k}={v}"))
288 .collect::<Vec<_>>();
289 d.insert(name, obj.to_json());
290 }
291 }};
292 }
293
294 target_val!(llvm_target);
295 target_val!(metadata);
296 target_val!(pointer_width, "target-pointer-width");
297 target_val!(arch);
298 target_val!(data_layout);
299
300 target_option_val!(endian, "target-endian");
301 target_option_val!(c_int_width, "target-c-int-width");
302 target_option_val!(os);
303 target_option_val!(env);
304 target_option_val!(abi);
305 target_option_val!(vendor);
306 target_option_val!(linker);
307 target_option_val!(linker_flavor_json, "linker-flavor");
308 target_option_val!(lld_flavor_json, "lld-flavor");
309 target_option_val!(linker_is_gnu_json, "linker-is-gnu");
310 target_option_val!(pre_link_objects);
311 target_option_val!(post_link_objects);
312 target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
313 target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
314 target_option_val!(link_args - pre_link_args_json, "pre-link-args");
315 target_option_val!(link_args - late_link_args_json, "late-link-args");
316 target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic");
317 target_option_val!(link_args - late_link_args_static_json, "late-link-args-static");
318 target_option_val!(link_args - post_link_args_json, "post-link-args");
319 target_option_val!(link_script);
320 target_option_val!(env - link_env);
321 target_option_val!(link_env_remove);
322 target_option_val!(asm_args);
323 target_option_val!(cpu);
324 target_option_val!(need_explicit_cpu);
325 target_option_val!(features);
326 target_option_val!(dynamic_linking);
327 target_option_val!(direct_access_external_data);
328 target_option_val!(dll_tls_export);
329 target_option_val!(only_cdylib);
330 target_option_val!(executables);
331 target_option_val!(relocation_model);
332 target_option_val!(code_model);
333 target_option_val!(tls_model);
334 target_option_val!(disable_redzone);
335 target_option_val!(frame_pointer);
336 target_option_val!(function_sections);
337 target_option_val!(dll_prefix);
338 target_option_val!(dll_suffix);
339 target_option_val!(exe_suffix);
340 target_option_val!(staticlib_prefix);
341 target_option_val!(staticlib_suffix);
342 target_option_val!(families, "target-family");
343 target_option_val!(abi_return_struct_as_int);
344 target_option_val!(is_like_aix);
345 target_option_val!(is_like_darwin);
346 target_option_val!(is_like_solaris);
347 target_option_val!(is_like_windows);
348 target_option_val!(is_like_gpu);
349 target_option_val!(is_like_msvc);
350 target_option_val!(is_like_wasm);
351 target_option_val!(is_like_android);
352 target_option_val!(is_like_vexos);
353 target_option_val!(binary_format);
354 target_option_val!(default_dwarf_version);
355 target_option_val!(allows_weak_linkage);
356 target_option_val!(has_rpath);
357 target_option_val!(no_default_libraries);
358 target_option_val!(position_independent_executables);
359 target_option_val!(static_position_independent_executables);
360 target_option_val!(plt_by_default);
361 target_option_val!(relro_level);
362 target_option_val!(archive_format);
363 target_option_val!(allow_asm);
364 target_option_val!(static_initializer_must_be_acyclic);
365 target_option_val!(main_needs_argc_argv);
366 target_option_val!(has_thread_local);
367 target_option_val!(obj_is_bitcode);
368 target_option_val!(min_atomic_width);
369 target_option_val!(max_atomic_width);
370 target_option_val!(atomic_cas);
371 target_option_val!(panic_strategy);
372 target_option_val!(crt_static_allows_dylibs);
373 target_option_val!(crt_static_default);
374 target_option_val!(crt_static_respected);
375 target_option_val!(stack_probes);
376 target_option_val!(min_global_align);
377 target_option_val!(default_codegen_units);
378 target_option_val!(default_codegen_backend);
379 target_option_val!(trap_unreachable);
380 target_option_val!(requires_lto);
381 target_option_val!(singlethread);
382 target_option_val!(no_builtins);
383 target_option_val!(default_visibility);
384 target_option_val!(emit_debug_gdb_scripts);
385 target_option_val!(requires_uwtable);
386 target_option_val!(default_uwtable);
387 target_option_val!(simd_types_indirect);
388 target_option_val!(limit_rdylib_exports);
389 target_option_val!(override_export_symbols);
390 target_option_val!(merge_functions);
391 target_option_val!(mcount, "target-mcount");
392 target_option_val!(llvm_mcount_intrinsic);
393 target_option_val!(llvm_abiname);
394 target_option_val!(llvm_floatabi);
395 target_option_val!(rustc_abi);
396 target_option_val!(relax_elf_relocations);
397 target_option_val!(llvm_args);
398 target_option_val!(use_ctors_section);
399 target_option_val!(eh_frame_header);
400 target_option_val!(has_thumb_interworking);
401 target_option_val!(debuginfo_kind);
402 target_option_val!(split_debuginfo);
403 target_option_val!(supported_split_debuginfo);
404 target_option_val!(supported_sanitizers);
405 target_option_val!(default_sanitizers);
406 target_option_val!(c_enum_min_bits);
407 target_option_val!(generate_arange_section);
408 target_option_val!(supports_stack_protector);
409 target_option_val!(small_data_threshold_support);
410 target_option_val!(entry_name);
411 target_option_val!(entry_abi);
412 target_option_val!(supports_xray);
413
414 d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json());
417
418 Json::Object(d)
419 }
420}
421
422#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
423struct LinkSelfContainedComponentsWrapper {
424 components: Vec<LinkSelfContainedComponents>,
425}
426
427#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
428#[serde(untagged)]
429enum TargetFamiliesJson {
430 Array(StaticCow<[StaticCow<str>]>),
431 String(StaticCow<str>),
432}
433
434struct EndianWrapper(rustc_abi::Endian);
436impl FromStr for EndianWrapper {
437 type Err = String;
438 fn from_str(s: &str) -> Result<Self, Self::Err> {
439 rustc_abi::Endian::from_str(s).map(Self)
440 }
441}
442crate::json::serde_deserialize_from_str!(EndianWrapper);
443impl schemars::JsonSchema for EndianWrapper {
444 fn schema_name() -> std::borrow::Cow<'static, str> {
445 "Endian".into()
446 }
447 fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
448 schemars::json_schema! ({
449 "type": "string",
450 "enum": ["big", "little"]
451 })
452 .into()
453 }
454}
455
456struct ExternAbiWrapper(rustc_abi::ExternAbi);
458impl FromStr for ExternAbiWrapper {
459 type Err = String;
460 fn from_str(s: &str) -> Result<Self, Self::Err> {
461 rustc_abi::ExternAbi::from_str(s)
462 .map(Self)
463 .map_err(|_| format!("{s} is not a valid extern ABI"))
464 }
465}
466crate::json::serde_deserialize_from_str!(ExternAbiWrapper);
467impl schemars::JsonSchema for ExternAbiWrapper {
468 fn schema_name() -> std::borrow::Cow<'static, str> {
469 "ExternAbi".into()
470 }
471 fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
472 let all =
473 rustc_abi::ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect::<Vec<_>>();
474 schemars::json_schema! ({
475 "type": "string",
476 "enum": all,
477 })
478 .into()
479 }
480}
481
482#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
483struct TargetSpecJsonMetadata {
484 description: Option<StaticCow<str>>,
485 tier: Option<u64>,
486 host_tools: Option<bool>,
487 std: Option<bool>,
488}
489
490#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
491#[serde(rename_all = "kebab-case")]
492#[serde(deny_unknown_fields)]
496struct TargetSpecJson {
497 llvm_target: StaticCow<str>,
498 target_pointer_width: u16,
499 data_layout: StaticCow<str>,
500 arch: Arch,
501
502 metadata: Option<TargetSpecJsonMetadata>,
503
504 target_endian: Option<EndianWrapper>,
506 frame_pointer: Option<FramePointer>,
507 #[serde(rename = "target-c-int-width")]
508 c_int_width: Option<u16>,
509 c_enum_min_bits: Option<u64>,
510 os: Option<Os>,
511 env: Option<Env>,
512 abi: Option<Abi>,
513 vendor: Option<StaticCow<str>>,
514 linker: Option<StaticCow<str>>,
515 #[serde(rename = "linker-flavor")]
516 linker_flavor_json: Option<LinkerFlavorCli>,
517 #[serde(rename = "lld-flavor")]
518 lld_flavor_json: Option<LldFlavor>,
519 #[serde(rename = "linker-is-gnu")]
520 linker_is_gnu_json: Option<bool>,
521 #[serde(rename = "pre-link-objects")]
522 pre_link_objects: Option<CrtObjects>,
523 #[serde(rename = "post-link-objects")]
524 post_link_objects: Option<CrtObjects>,
525 #[serde(rename = "pre-link-objects-fallback")]
526 pre_link_objects_self_contained: Option<CrtObjects>,
527 #[serde(rename = "post-link-objects-fallback")]
528 post_link_objects_self_contained: Option<CrtObjects>,
529 #[serde(rename = "crt-objects-fallback")]
530 link_self_contained_backwards_compatible: Option<LinkSelfContainedDefault>,
531 link_self_contained: Option<LinkSelfContainedComponentsWrapper>,
532 #[serde(rename = "pre-link-args")]
533 pre_link_args_json: Option<LinkArgsCli>,
534 #[serde(rename = "late-link-args")]
535 late_link_args_json: Option<LinkArgsCli>,
536 #[serde(rename = "late-link-args-dynamic")]
537 late_link_args_dynamic_json: Option<LinkArgsCli>,
538 #[serde(rename = "late-link-args-static")]
539 late_link_args_static_json: Option<LinkArgsCli>,
540 #[serde(rename = "post-link-args")]
541 post_link_args_json: Option<LinkArgsCli>,
542 link_script: Option<StaticCow<str>>,
543 link_env: Option<Vec<StaticCow<str>>>,
544 link_env_remove: Option<StaticCow<[StaticCow<str>]>>,
545 asm_args: Option<StaticCow<[StaticCow<str>]>>,
546 cpu: Option<StaticCow<str>>,
547 need_explicit_cpu: Option<bool>,
548 features: Option<StaticCow<str>>,
549 dynamic_linking: Option<bool>,
550 direct_access_external_data: Option<bool>,
551 dll_tls_export: Option<bool>,
552 only_cdylib: Option<bool>,
553 executables: Option<bool>,
554 relocation_model: Option<RelocModel>,
555 code_model: Option<CodeModel>,
556 tls_model: Option<TlsModel>,
557 disable_redzone: Option<bool>,
558 function_sections: Option<bool>,
559 dll_prefix: Option<StaticCow<str>>,
560 dll_suffix: Option<StaticCow<str>>,
561 exe_suffix: Option<StaticCow<str>>,
562 staticlib_prefix: Option<StaticCow<str>>,
563 staticlib_suffix: Option<StaticCow<str>>,
564 target_family: Option<TargetFamiliesJson>,
565 abi_return_struct_as_int: Option<bool>,
566 is_like_aix: Option<bool>,
567 is_like_darwin: Option<bool>,
568 is_like_solaris: Option<bool>,
569 is_like_windows: Option<bool>,
570 is_like_gpu: Option<bool>,
571 is_like_msvc: Option<bool>,
572 is_like_wasm: Option<bool>,
573 is_like_android: Option<bool>,
574 is_like_vexos: Option<bool>,
575 binary_format: Option<BinaryFormat>,
576 default_dwarf_version: Option<u32>,
577 allows_weak_linkage: Option<bool>,
578 has_rpath: Option<bool>,
579 no_default_libraries: Option<bool>,
580 position_independent_executables: Option<bool>,
581 static_position_independent_executables: Option<bool>,
582 plt_by_default: Option<bool>,
583 relro_level: Option<RelroLevel>,
584 archive_format: Option<StaticCow<str>>,
585 allow_asm: Option<bool>,
586 static_initializer_must_be_acyclic: Option<bool>,
587 main_needs_argc_argv: Option<bool>,
588 has_thread_local: Option<bool>,
589 obj_is_bitcode: Option<bool>,
590 max_atomic_width: Option<u64>,
591 min_atomic_width: Option<u64>,
592 atomic_cas: Option<bool>,
593 panic_strategy: Option<PanicStrategy>,
594 crt_static_allows_dylibs: Option<bool>,
595 crt_static_default: Option<bool>,
596 crt_static_respected: Option<bool>,
597 stack_probes: Option<StackProbeType>,
598 min_global_align: Option<u64>,
599 default_codegen_units: Option<u64>,
600 default_codegen_backend: Option<StaticCow<str>>,
601 trap_unreachable: Option<bool>,
602 requires_lto: Option<bool>,
603 singlethread: Option<bool>,
604 no_builtins: Option<bool>,
605 default_visibility: Option<SymbolVisibility>,
606 emit_debug_gdb_scripts: Option<bool>,
607 requires_uwtable: Option<bool>,
608 default_uwtable: Option<bool>,
609 simd_types_indirect: Option<bool>,
610 limit_rdylib_exports: Option<bool>,
611 override_export_symbols: Option<StaticCow<[StaticCow<str>]>>,
612 merge_functions: Option<MergeFunctions>,
613 #[serde(rename = "target-mcount")]
614 mcount: Option<StaticCow<str>>,
615 llvm_mcount_intrinsic: Option<StaticCow<str>>,
616 llvm_abiname: Option<StaticCow<str>>,
617 llvm_floatabi: Option<FloatAbi>,
618 rustc_abi: Option<RustcAbi>,
619 relax_elf_relocations: Option<bool>,
620 llvm_args: Option<StaticCow<[StaticCow<str>]>>,
621 use_ctors_section: Option<bool>,
622 eh_frame_header: Option<bool>,
623 has_thumb_interworking: Option<bool>,
624 debuginfo_kind: Option<DebuginfoKind>,
625 split_debuginfo: Option<SplitDebuginfo>,
626 supported_split_debuginfo: Option<StaticCow<[SplitDebuginfo]>>,
627 supported_sanitizers: Option<Vec<SanitizerSet>>,
628 default_sanitizers: Option<Vec<SanitizerSet>>,
629 generate_arange_section: Option<bool>,
630 supports_stack_protector: Option<bool>,
631 small_data_threshold_support: Option<SmallDataThresholdSupport>,
632 entry_name: Option<StaticCow<str>>,
633 supports_xray: Option<bool>,
634 entry_abi: Option<ExternAbiWrapper>,
635}
636
637pub fn json_schema() -> schemars::Schema {
638 schemars::schema_for!(TargetSpecJson)
639}