Skip to content

Commit 7b69bc5

Browse files
committed
Use ar -L when available
As of 9.4, GHC on Windows may produce .o files that are in fact archive files due to the lack of object merging support in the lld linker (see GHC #21068). Consequently, we must ensure that `ar` merges input archives' members, not add them as a single entry.
1 parent 927b8fe commit 7b69bc5

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

Cabal/src/Distribution/Simple/Compiler.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ module Distribution.Simple.Compiler (
6262
profilingSupported,
6363
backpackSupported,
6464
arResponseFilesSupported,
65+
arDashLSupported,
6566
libraryDynDirSupported,
6667
libraryVisibilitySupported,
6768

@@ -365,6 +366,12 @@ libraryDynDirSupported comp = case compilerFlavor comp of
365366
arResponseFilesSupported :: Compiler -> Bool
366367
arResponseFilesSupported = ghcSupported "ar supports at file"
367368

369+
-- | Does this compiler's "ar" command support llvm-ar's -L flag,
370+
-- which compels the archiver to add an input archive's members
371+
-- rather than adding the archive itself.
372+
arDashLSupported :: Compiler -> Bool
373+
arDashLSupported = ghcSupported "ar supports -L"
374+
368375
-- | Does this compiler support Haskell program coverage?
369376
coverageSupported :: Compiler -> Bool
370377
coverageSupported comp =

Cabal/src/Distribution/Simple/Program/Ar.hs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Distribution.Compat.Prelude
2424
import qualified Data.ByteString as BS
2525
import qualified Data.ByteString.Char8 as BS8
2626
import Distribution.Compat.CopyFile (filesEqual)
27-
import Distribution.Simple.Compiler (arResponseFilesSupported)
27+
import Distribution.Simple.Compiler (arResponseFilesSupported, arDashLSupported)
2828
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
2929
import Distribution.Simple.Program
3030
( ProgramInvocation, arProgram, requireProgram )
@@ -68,17 +68,25 @@ createArLibArchive verbosity lbi targetPath files = do
6868
-- do that. We have duplicates because of modules like "A.M" and "B.M"
6969
-- both make an object file "M.o" and ar does not consider the directory.
7070
--
71+
-- -- llvm-ar, which GHC >=9.4 uses on Windows, supports a "L" modifier
72+
-- in "q" mode which compels the archiver to add the members of an input
73+
-- archive to the output, rather than the archive itself. This is
74+
-- necessary as GHC may produce .o files that are actually archives. See
75+
-- https://gitlab.haskell.org/ghc/ghc/-/issues/21068.
76+
--
7177
-- Our solution is to use "ar r" in the simple case when one call is enough.
7278
-- When we need to call ar multiple times we use "ar q" and for the last
7379
-- call on OSX we use "ar qs" so that it'll make the index.
7480

7581
let simpleArgs = case hostOS of
7682
OSX -> ["-r", "-s"]
83+
_ | dashLSupported -> ["-qL"]
7784
_ -> ["-r"]
7885

7986
initialArgs = ["-q"]
8087
finalArgs = case hostOS of
8188
OSX -> ["-q", "-s"]
89+
_ | dashLSupported -> ["-qL"]
8290
_ -> ["-q"]
8391

8492
extraArgs = verbosityOpts verbosity ++ [tmpPath]
@@ -90,8 +98,10 @@ createArLibArchive verbosity lbi targetPath files = do
9098

9199
oldVersionManualOverride =
92100
fromFlagOrDefault False $ configUseResponseFiles $ configFlags lbi
93-
responseArgumentsNotSupported =
101+
responseArgumentsNotSupported =
94102
not (arResponseFilesSupported (compiler lbi))
103+
dashLSupported =
104+
arDashLSupported (compiler lbi)
95105

96106
invokeWithResponesFile :: FilePath -> ProgramInvocation
97107
invokeWithResponesFile atFile =

0 commit comments

Comments
 (0)