From a51ad7971261963906ffe37710610fa3fbfba723 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <mati865@gmail.com>
Date: Tue, 23 Apr 2024 20:38:54 +0200
Subject: [PATCH 1/2] Refactor dlltool searching code into separate function

---
 src/tools/compiletest/src/header/needs.rs     | 65 ++++++-------------
 .../raw-dylib-cross-compilation/Makefile      |  4 +-
 .../rfcs/rfc-2627-raw-dylib/dlltool-failed.rs |  2 -
 .../rfc-2627-raw-dylib/invalid-dlltool.rs     |  3 +-
 4 files changed, 21 insertions(+), 53 deletions(-)

diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index db154932d5b54..20d3fd4734338 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -119,16 +119,6 @@ pub(super) fn handle_needs(
             condition: config.debugger != Some(Debugger::Lldb) || config.lldb_native_rust,
             ignore_reason: "ignored on targets without Rust's LLDB",
         },
-        Need {
-            name: "needs-i686-dlltool",
-            condition: cache.i686_dlltool,
-            ignore_reason: "ignored when dlltool for i686 is not present",
-        },
-        Need {
-            name: "needs-x86_64-dlltool",
-            condition: cache.x86_64_dlltool,
-            ignore_reason: "ignored when dlltool for x86_64 is not present",
-        },
         Need {
             name: "needs-dlltool",
             condition: cache.dlltool,
@@ -218,27 +208,11 @@ pub(super) struct CachedNeedsConditions {
     profiler_support: bool,
     xray: bool,
     rust_lld: bool,
-    i686_dlltool: bool,
-    x86_64_dlltool: bool,
     dlltool: bool,
 }
 
 impl CachedNeedsConditions {
     pub(super) fn load(config: &Config) -> Self {
-        let path = std::env::var_os("PATH").expect("missing PATH environment variable");
-        let path = std::env::split_paths(&path).collect::<Vec<_>>();
-
-        // On Windows, dlltool.exe is used for all architectures.
-        #[cfg(windows)]
-        let dlltool = path.iter().any(|dir| dir.join("dlltool.exe").is_file());
-
-        // For non-Windows, there are architecture specific dlltool binaries.
-        #[cfg(not(windows))]
-        let i686_dlltool = path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file());
-        #[cfg(not(windows))]
-        let x86_64_dlltool =
-            path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file());
-
         let target = &&*config.target;
         let sanitizers = &config.target_cfg().sanitizers;
         Self {
@@ -278,26 +252,25 @@ impl CachedNeedsConditions {
                 .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
                 .exists(),
 
-            #[cfg(windows)]
-            i686_dlltool: dlltool,
-            #[cfg(windows)]
-            x86_64_dlltool: dlltool,
-            #[cfg(windows)]
-            dlltool,
-
-            // For non-Windows, there are architecture specific dlltool binaries.
-            #[cfg(not(windows))]
-            i686_dlltool,
-            #[cfg(not(windows))]
-            x86_64_dlltool,
-            #[cfg(not(windows))]
-            dlltool: if config.matches_arch("x86") {
-                i686_dlltool
-            } else if config.matches_arch("x86_64") {
-                x86_64_dlltool
-            } else {
-                false
-            },
+            dlltool: find_dlltool(&config),
         }
     }
 }
+
+fn find_dlltool(config: &Config) -> bool {
+    let path = std::env::var_os("PATH").expect("missing PATH environment variable");
+    let path = std::env::split_paths(&path).collect::<Vec<_>>();
+
+    // On Windows, dlltool.exe is used for all architectures.
+    // For non-Windows, there are architecture specific dlltool binaries.
+    let dlltool_found = if cfg!(windows) {
+        path.iter().any(|dir| dir.join("dlltool.exe").is_file())
+    } else if config.matches_arch("i686") {
+        path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file())
+    } else if config.matches_arch("x86_64") {
+        path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file())
+    } else {
+        false
+    };
+    dlltool_found
+}
diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile
index a8f97edd68936..2524f8500e154 100644
--- a/tests/run-make/raw-dylib-cross-compilation/Makefile
+++ b/tests/run-make/raw-dylib-cross-compilation/Makefile
@@ -1,8 +1,6 @@
 # Tests that raw-dylib cross compilation works correctly
 
-# only-gnu
-# needs-i686-dlltool
-# needs-x86_64-dlltool
+# needs-dlltool
 
 # i686 dlltool.exe can't product x64 binaries.
 # ignore-i686-pc-windows-gnu
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
index 5ff3cd25e67be..402efaf50271a 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
@@ -1,7 +1,5 @@
 // Tests that dlltool failing to generate an import library will raise an error.
 
-//@ only-gnu
-//@ only-windows
 //@ needs-dlltool
 //@ compile-flags: --crate-type lib --emit link
 //@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL"
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
index ac6a2998a4762..bcf6dda7a44dc 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
@@ -1,7 +1,6 @@
 // Tests that failing to run dlltool will raise an error.
 
-//@ only-gnu
-//@ only-windows
+//@ needs-dlltool
 //@ compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe
 #[link(name = "foo", kind = "raw-dylib")]
 extern "C" {

From b1fd4a7a49f9558b00aface02d6a5c5ccfa59d4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <mati865@gmail.com>
Date: Tue, 23 Apr 2024 20:47:21 +0200
Subject: [PATCH 2/2] Skip dlltool tests on non `*windows-gnu` targets

---
 src/tools/compiletest/src/header/needs.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 20d3fd4734338..7bc7e4b868038 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -261,6 +261,11 @@ fn find_dlltool(config: &Config) -> bool {
     let path = std::env::var_os("PATH").expect("missing PATH environment variable");
     let path = std::env::split_paths(&path).collect::<Vec<_>>();
 
+    // dlltool is used ony by GNU based `*-*-windows-gnu`
+    if !(config.matches_os("windows") && config.matches_env("gnu") && config.matches_abi("")) {
+        return false;
+    }
+
     // On Windows, dlltool.exe is used for all architectures.
     // For non-Windows, there are architecture specific dlltool binaries.
     let dlltool_found = if cfg!(windows) {