Repository: rust-lang/cc-rs
Pull request #1263 (2024-11-02 22:11:29)

Do not add -fPIC by default on UEFI targets
This fixes a regression caused by 290a6293c5e061a8a1d91a6521ff4ffc66d93a2a.

nicholasbishop: Pushed a fix to my commit message, the regression was in 290a6293c5e061a8a1d91a6521ff4ffc66d93a2a rather than 9c663ca.

Patch:
diff --git a/dev-tools/gen-target-info/src/main.rs b/dev-tools/gen-target-info/src/main.rs
index 95f8563..c0c17f2 100644
--- a/dev-tools/gen-target-info/src/main.rs
+++ b/dev-tools/gen-target-info/src/main.rs
@@ -26,17 +26,47 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
         let env = spec.env.as_deref().unwrap_or("");
         let abi = spec.abi.as_deref().unwrap_or("");
 
-        // Remove deployment target information from LLVM target triples (we
-        // will add this in another part of CC).
-        //
-        // FIXME(madsmtm): Should become unnecessary after
-        // https://github.com/rust-lang/rust/pull/131037
         let unversioned_llvm_target = if spec.llvm_target.contains("apple") {
+            // Remove deployment target information from LLVM target triples (we
+            // will add this in another part of CC).
+            //
+            // FIXME(madsmtm): Should become unnecessary after
+            // https://github.com/rust-lang/rust/pull/131037
             let mut components = spec.llvm_target.split("-").collect::<Vec<_>>();
 
             components[2] = components[2].trim_end_matches(|c: char| c.is_numeric() || c == '.');
 
             components.join("-")
+        } else if os == "uefi" {
+            // Override the UEFI LLVM targets.
+            //
+            // The rustc mappings (as of 1.82) for the UEFI targets are:
+            // * i686-unknown-uefi -> i686-unknown-windows-gnu
+            // * x86_64-unknown-uefi -> x86_64-unknown-windows
+            // * aarch64-unknown-uefi -> aarch64-unknown-windows
+            //
+            // However, in cc-rs all the UEFI targets use
+            // -windows-gnu. This has been the case since 2021 [1].
+            // * i686-unknown-uefi -> i686-unknown-windows-gnu
+            // * x86_64-unknown-uefi -> x86_64-unknown-windows-gnu
+            // * aarch64-unknown-uefi -> aarch64-unknown-windows-gnu
+            //
+            // For now, override the UEFI mapping to keep the behavior
+            // of cc-rs unchanged.
+            //
+            // TODO: as discussed in [2], it may be possible to switch
+            // to new UEFI targets added to clang, and regardless it
+            // would be good to have consistency between rustc and
+            // cc-rs.
+            //
+            // [1]: https://github.com/rust-lang/cc-rs/pull/623
+            // [2]: https://github.com/rust-lang/cc-rs/pull/1264
+            let arch = if spec.arch == "x86" {
+                "i686"
+            } else {
+                &spec.arch
+            };
+            format!("{}-unknown-windows-gnu", arch)
         } else {
             spec.llvm_target.clone()
         };
diff --git a/src/lib.rs b/src/lib.rs
index b64bff5..14d8f01 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1997,7 +1997,7 @@ impl Build {
                 if self.pic.unwrap_or(
                     target.os != "windows"
                         && target.os != "none"
-                        && target.env != "uefi"
+                        && target.os != "uefi"
                         && target.os != "wasi",
                 ) {
                     cmd.push_cc_arg("-fPIC".into());
diff --git a/src/target/generated.rs b/src/target/generated.rs
index ce3a4b0..973c10f 100644
--- a/src/target/generated.rs
+++ b/src/target/generated.rs
@@ -409,7 +409,7 @@ pub(crate) const LIST: &[(&str, TargetInfo<'static>)] = &[
             os: "uefi",
             env: "",
             abi: "",
-            unversioned_llvm_target: "aarch64-unknown-windows",
+            unversioned_llvm_target: "aarch64-unknown-windows-gnu",
         },
     ),
     (
@@ -3205,7 +3205,7 @@ pub(crate) const LIST: &[(&str, TargetInfo<'static>)] = &[
             os: "uefi",
             env: "",
             abi: "",
-            unversioned_llvm_target: "x86_64-unknown-windows",
+            unversioned_llvm_target: "x86_64-unknown-windows-gnu",
         },
     ),
     (


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 14e72ec..62976d6 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -283,6 +283,23 @@ fn gnu_aarch64_none_no_pic() {
     }
 }
 
+#[test]
+fn gnu_uefi_no_pic() {
+    reset_env();
+
+    for arch in &["aarch64", "i686", "x86_64"] {
+        let target = format!("{}-unknown-uefi", arch);
+        let test = Test::gnu();
+        test.gcc()
+            .target(&target)
+            .host(&target)
+            .file("foo.c")
+            .compile("foo");
+
+        test.cmd(0).must_not_have("-fPIC");
+    }
+}
+
 #[test]
 fn gnu_set_stdlib() {
     reset_env();