From e98051a5e7251390799f9fdead988c61d72e82e3 Mon Sep 17 00:00:00 2001
From: Rodrigo Mesquita <rodrigo.m.mesquita@gmail.com>
Date: Tue, 7 Nov 2023 16:13:16 +0000
Subject: [PATCH] Suppress duplicate librares linker warning of new macOS
 linker

Fixes #24167

XCode 15 introduced a new linker which warns on duplicate libraries being
linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as
suggested by Brad King in CMake issue #25297.

This flag isn't necessarily available to other linkers on darwin, so we must
only configure it into the CC linker arguments if valid.
---
 configure.ac                                  |  6 ++++
 distrib/configure.ac.in                       |  6 ++++
 m4/fp_ld_no_warn_duplicate_libraries.m4       | 29 +++++++++++++++++++
 .../src/GHC/Toolchain/Tools/Link.hs           | 15 +++++++++-
 4 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 m4/fp_ld_no_warn_duplicate_libraries.m4

diff --git a/configure.ac b/configure.ac
index 31c3c259d760..3a6dfd32da86 100644
--- a/configure.ac
+++ b/configure.ac
@@ -613,11 +613,17 @@ FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAG
 FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE2],[CONF_GCC_LINKER_OPTS_STAGE2],[CONF_LD_LINKER_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
 # Stage 3 won't be supported by cross-compilation
 
+#-no_fixup_chains
 FP_LD_NO_FIXUP_CHAINS([target], [LDFLAGS])
 FP_LD_NO_FIXUP_CHAINS([build], [CONF_GCC_LINKER_OPTS_STAGE0])
 FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE1])
 FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE2])
 
+#-no_warn_duplicate_libraries
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([build], [CONF_GCC_LINKER_OPTS_STAGE0])
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE1])
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE2])
+
 FP_MERGE_OBJECTS_SUPPORTS_RESPONSE_FILES
 
 GHC_LLVM_TARGET_SET_VAR
diff --git a/distrib/configure.ac.in b/distrib/configure.ac.in
index d1493fff4591..ecbfebef5784 100644
--- a/distrib/configure.ac.in
+++ b/distrib/configure.ac.in
@@ -175,11 +175,17 @@ FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAG
 # Stage 3 won't be supported by cross-compilation
 FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE2],[CONF_GCC_LINKER_OPTS_STAGE2],[CONF_LD_LINKER_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
 
+#-no_fixup_chains
 FP_LD_NO_FIXUP_CHAINS([target], [LDFLAGS])
 FP_LD_NO_FIXUP_CHAINS([build], [CONF_GCC_LINKER_OPTS_STAGE0])
 FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE1])
 FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE2])
 
+#-no_warn_duplicate_libraries
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([build], [CONF_GCC_LINKER_OPTS_STAGE0])
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE1])
+FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE2])
+
 FP_MERGE_OBJECTS_SUPPORTS_RESPONSE_FILES
 
 AC_SUBST(CONF_CC_OPTS_STAGE0)
diff --git a/m4/fp_ld_no_warn_duplicate_libraries.m4 b/m4/fp_ld_no_warn_duplicate_libraries.m4
new file mode 100644
index 000000000000..d0b8f2a91ce7
--- /dev/null
+++ b/m4/fp_ld_no_warn_duplicate_libraries.m4
@@ -0,0 +1,29 @@
+# FP_LD_NO_WARN_DUPLICATE_LIBRARIES
+# ---------------------------------
+# XCode 15 introduced a new linker which warns on duplicate libraries being
+# linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as
+# suggested by Brad King in CMake issue #25297.
+#
+# This flag isn't necessarily available to other linkers on darwin, so we must
+# only configure it into the CC linker arguments if valid.
+#
+# $1 = the platform
+# $2 = the name of the linker flags variable when linking with $CC
+AC_DEFUN([FP_LD_NO_WARN_DUPLICATE_LIBRARIES], [
+    case $$1 in
+      *-darwin)
+      AC_MSG_CHECKING([whether the linker requires -no_warn_duplicate_libraries])
+      echo 'int main(void) {return 0;}' > conftest.c
+      if $CC -o conftest -Wl,-no_warn_duplicate_libraries conftest.c > /dev/null 2>&1
+      then
+          $2="$$2 -Wl,-no_warn_duplicate_libraries"
+          AC_MSG_RESULT([yes])
+      else
+          AC_MSG_RESULT([no])
+      fi
+      rm -f conftest.c conftest.o conftest
+      ;;
+
+    esac
+])
+
diff --git a/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs b/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
index 61b7a1c822be..080427c7d634 100644
--- a/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
+++ b/utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
@@ -73,6 +73,7 @@ findCcLink target ld progOpt ldOverride archOs cc readelf = checking "for C comp
                        ccLinkSupportsCompactUnwind, ccLinkSupportsFilelist,
                        ccLinkIsGnu}
   ccLink <- linkRequiresNoFixupChains archOs cc ccLink
+  ccLink <- linkRequiresNoWarnDuplicateLibraries archOs cc ccLink
   return ccLink
 
 
@@ -320,7 +321,7 @@ addNoAsNeeded archOs cc ccLink
       return ccLink'
   | otherwise = return ccLink
 
--- See if whether we are using a version of ld64 on darwin platforms which
+-- | See if whether we are using a version of ld64 on darwin platforms which
 -- requires us to pass -no_fixup_chains
 linkRequiresNoFixupChains :: ArchOS -> Cc -> CcLink -> M CcLink
 linkRequiresNoFixupChains archOs cc ccLink
@@ -329,4 +330,16 @@ linkRequiresNoFixupChains archOs cc ccLink
        in (ccLink' <$ checkLinkWorks cc (ccLinkProgram ccLink')) <|> return ccLink
   | otherwise = return ccLink
 
+-- | XCode 15 introduced a new linker which warns on duplicate libraries being
+-- linked. To disable this warning, we pass -Wl,-no_warn_duplicate_libraries as
+-- suggested by Brad King in CMake issue #25297.
+--
+-- This flag isn't necessarily available to other linkers on darwin, so we must
+-- only configure it into the CC linker arguments if valid.
+linkRequiresNoWarnDuplicateLibraries :: ArchOS -> Cc -> CcLink -> M CcLink
+linkRequiresNoWarnDuplicateLibraries archOs cc ccLink
+  | OSDarwin <- archOS_OS archOs = checking "whether CC linker requires -no_warn_duplicate_libraries" $
+      let ccLink' = over (_ccLinkProgram % _prgFlags) (++["-Wl,-no_warn_duplicate_libraries"]) ccLink
+       in (ccLink' <$ checkLinkWorks cc (ccLinkProgram ccLink')) <|> return ccLink
+  | otherwise = return ccLink
 
-- 
GitLab