diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 41c99f7edeeff..b74b869cc305d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -19,8 +19,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION}; use rustc_span::source_map::FilePathMapping; use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm}; +use rustc_target::spec::{has_ext_ignore_case, SplitDebuginfo, Target, TargetTriple}; use rustc_target::spec::{FramePointer, LinkSelfContainedComponents, LinkerFeatures}; -use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple}; use std::collections::btree_map::{ Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter, }; @@ -1991,7 +1991,7 @@ fn collect_print_requests( pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTriple { match matches.opt_str("target") { - Some(target) if target.ends_with(".json") => { + Some(target) if has_ext_ignore_case(&target, "json") => { let path = Path::new(&target); TargetTriple::from_path(path).unwrap_or_else(|_| { early_dcx.early_fatal(format!("target file {path:?} does not exist")) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 81ada30a59437..3b77c5a2fc849 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -46,6 +46,7 @@ use rustc_span::symbol::{kw, sym, Symbol}; use serde_json::Value; use std::borrow::Cow; use std::collections::BTreeMap; +use std::ffi::OsStr; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; use std::path::{Path, PathBuf}; @@ -3716,3 +3717,11 @@ impl fmt::Display for TargetTriple { write!(f, "{}", self.debug_triple()) } } + +/// Helper function to check if the given `s` ends with `ext` __case-insensitive__. +/// The `ext` should not starts with a dot. +/// +/// Does not check if the path exists. +pub fn has_ext_ignore_case, Ext: AsRef>(s: S, ext: Ext) -> bool { + Path::new(&s).extension().is_some_and(|s| s.eq_ignore_ascii_case(ext)) +} diff --git a/tests/run-make/target-specs-filename/ALL-IN-CAPS.JSON b/tests/run-make/target-specs-filename/ALL-IN-CAPS.JSON new file mode 100644 index 0000000000000..0091a7d408cbd --- /dev/null +++ b/tests/run-make/target-specs-filename/ALL-IN-CAPS.JSON @@ -0,0 +1,6 @@ +{ + "arch": "x86_64", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "llvm-target": "x86_64-unknown-unknown-gnu", + "target-pointer-width": "64" +} diff --git a/tests/run-make/target-specs-filename/ext-in-caps.JSON b/tests/run-make/target-specs-filename/ext-in-caps.JSON new file mode 100644 index 0000000000000..0091a7d408cbd --- /dev/null +++ b/tests/run-make/target-specs-filename/ext-in-caps.JSON @@ -0,0 +1,6 @@ +{ + "arch": "x86_64", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "llvm-target": "x86_64-unknown-unknown-gnu", + "target-pointer-width": "64" +} diff --git a/tests/run-make/target-specs-filename/normal-target-triple.json b/tests/run-make/target-specs-filename/normal-target-triple.json new file mode 100644 index 0000000000000..0091a7d408cbd --- /dev/null +++ b/tests/run-make/target-specs-filename/normal-target-triple.json @@ -0,0 +1,6 @@ +{ + "arch": "x86_64", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "llvm-target": "x86_64-unknown-unknown-gnu", + "target-pointer-width": "64" +} diff --git a/tests/run-make/target-specs-filename/rmake.rs b/tests/run-make/target-specs-filename/rmake.rs new file mode 100644 index 0000000000000..1f3a226c61354 --- /dev/null +++ b/tests/run-make/target-specs-filename/rmake.rs @@ -0,0 +1,22 @@ +// This test checks the rustc can accept target-spec-json with cases +// including file extension - it could be in upper and lower case. +// Used to test: print target-spec-json and cfg +// Issue: https://github.com/rust-lang/rust/issues/127387 + +use run_make_support::rustc; + +fn main() { + // This is a matrix [files x args], files for target, args for print. + for file in [ + "normal-target-triple", + "normal-target-triple.json", + "ext-in-caps.JSON", + "ALL-IN-CAPS.JSON", + ] { + for args in [["cfg"].as_slice(), &["target-spec-json", "-Zunstable-options"]] { + let output = rustc().arg("--print").args(args).args(["--target", file]).run(); + // check that the target triple is read correctly + output.assert_stdout_contains("x86_64"); + } + } +}