From 1861eff7b8547bf5e9f2c5007f3eb1515e277565 Mon Sep 17 00:00:00 2001
From: Ben Gamari <ben@smart-cactus.org>
Date: Fri, 25 Feb 2022 10:00:01 -0500
Subject: [PATCH] hadrian: Clean up handling of libffi dependencies

(cherry picked from commit b2721819f391ab49871271283f32df54810c4387)
---
 compiler/GHC/Driver/CodeOutput.hs |  9 +++++++++
 hadrian/src/Rules/Libffi.hs       |  3 +++
 hadrian/src/Rules/Rts.hs          |  2 ++
 hadrian/src/Settings/Packages.hs  | 15 ++++++---------
 libraries/ghci/ghci.cabal.in      |  2 --
 rts/rts.cabal.in                  |  5 ++++-
 6 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/compiler/GHC/Driver/CodeOutput.hs b/compiler/GHC/Driver/CodeOutput.hs
index 8c990b16cbcf..66e5e69d21d2 100644
--- a/compiler/GHC/Driver/CodeOutput.hs
+++ b/compiler/GHC/Driver/CodeOutput.hs
@@ -199,6 +199,15 @@ outputLlvm logger dflags filenm cmm_stream =
 ************************************************************************
 -}
 
+{-
+Note [Packaging libffi headers]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The C code emitted by GHC for libffi adjustors must depend upon the ffi_arg type,
+defined in <ffi.h>. For this reason, we must ensure that <ffi.h> is available
+in binary distributions. To do so, we install these headers as part of the
+`rts` package.
+-}
+
 outputForeignStubs
     :: Logger
     -> TmpFs
diff --git a/hadrian/src/Rules/Libffi.hs b/hadrian/src/Rules/Libffi.hs
index 86238c30a44d..659c75886b88 100644
--- a/hadrian/src/Rules/Libffi.hs
+++ b/hadrian/src/Rules/Libffi.hs
@@ -95,6 +95,9 @@ libffiName' dynamic = (if dynamic     then ""      else "C")
 libffiLibrary :: FilePath
 libffiLibrary = "inst/lib/libffi.a"
 
+-- | These are the headers that we must package with GHC since foreign export
+-- adjustor code produced by GHC depends upon them.
+-- See Note [Packaging libffi headers] in GHC.Driver.CodeOutput.
 libffiHeaderFiles :: [FilePath]
 libffiHeaderFiles = ["ffi.h", "ffitarget.h"]
 
diff --git a/hadrian/src/Rules/Rts.hs b/hadrian/src/Rules/Rts.hs
index efcd5f614a6f..633b4ed408a5 100644
--- a/hadrian/src/Rules/Rts.hs
+++ b/hadrian/src/Rules/Rts.hs
@@ -26,6 +26,7 @@ rtsRules = priority 3 $ do
         let buildPath = root -/- buildDir (rtsContext stage)
 
         -- Header files
+        -- See Note [Packaging libffi headers] in GHC.Driver.CodeOutput.
         (fmap (buildPath -/-) libffiHeaderFiles) &%> const (copyLibffiHeaders stage)
 
         -- Static libraries.
@@ -43,6 +44,7 @@ withLibffi stage action = needLibffi stage
 
 -- | Copy all header files wither from the system libffi or from the libffi
 -- build dir to the rts build dir.
+-- See Note [Packaging libffi headers] in GHC.Driver.CodeOutput.
 copyLibffiHeaders :: Stage -> Action ()
 copyLibffiHeaders stage = do
     rtsPath      <- rtsBuildPath stage
diff --git a/hadrian/src/Settings/Packages.hs b/hadrian/src/Settings/Packages.hs
index e5a3569d36d2..deba4860d5ac 100644
--- a/hadrian/src/Settings/Packages.hs
+++ b/hadrian/src/Settings/Packages.hs
@@ -24,6 +24,8 @@ packageArgs = do
 
     cursesIncludeDir <- getSetting CursesIncludeDir
     cursesLibraryDir <- getSetting CursesLibDir
+    ffiIncludeDir  <- getSetting FfiIncludeDir
+    ffiLibraryDir  <- getSetting FfiLibDir
 
     mconcat
         --------------------------------- base ---------------------------------
@@ -132,7 +134,8 @@ packageArgs = do
           -- the Stage1 libraries, as we already know that the bootstrap
           -- compiler comes with the same versions as the one we are building.
           --
-            builder (Cabal Flags) ? ifM stage0
+            builder (Cabal Setup) ? cabalExtraDirs ffiIncludeDir ffiLibraryDir
+          , builder (Cabal Flags) ? ifM stage0
               (andM [cross, bootCross] `cabalFlag` "internal-interpreter")
               (arg "internal-interpreter")
 
@@ -250,7 +253,6 @@ rtsPackageArgs = package rts ? do
     path           <- getBuildPath
     top            <- expr topDirectory
     useSystemFfi   <- expr $ flag UseSystemFfi
-    libffiName     <- expr libffiLibraryName
     ffiIncludeDir  <- getSetting FfiIncludeDir
     ffiLibraryDir  <- getSetting FfiLibDir
     libdwIncludeDir   <- getSetting LibdwIncludeDir
@@ -277,8 +279,6 @@ rtsPackageArgs = package rts ? do
 
     let cArgs = mconcat
           [ rtsWarnings
-          , flag UseSystemFfi ? not (null ffiIncludeDir) ? arg ("-I" ++ ffiIncludeDir)
-          , flag WithLibdw ? not (null libdwIncludeDir) ? arg ("-I" ++ libdwIncludeDir)
           , arg "-fomit-frame-pointer"
           -- RTS *must* be compiled with optimisations. The INLINE_HEADER macro
           -- requires that functions are inlined to work as expected. Inlining
@@ -372,6 +372,7 @@ rtsPackageArgs = package rts ? do
         , builder (Cabal Setup) ? mconcat
               [ cabalExtraDirs libdwIncludeDir libdwLibraryDir
               , cabalExtraDirs libnumaIncludeDir libnumaLibraryDir
+              , useSystemFfi ? cabalExtraDirs ffiIncludeDir ffiLibraryDir
               ]
         , builder (Cc FindCDependencies) ? cArgs
         , builder (Ghc CompileCWithGhc) ? map ("-optc" ++) <$> cArgs
@@ -379,11 +380,7 @@ rtsPackageArgs = package rts ? do
         , builder Ghc ? ghcArgs
 
         , builder HsCpp ? pure
-          [ "-DTOP="             ++ show top
-          , "-DFFI_INCLUDE_DIR=" ++ show ffiIncludeDir
-          , "-DFFI_LIB_DIR="     ++ show ffiLibraryDir
-          , "-DFFI_LIB="         ++ show libffiName
-          , "-DLIBDW_LIB_DIR="   ++ show libdwLibraryDir ]
+          [ "-DTOP="             ++ show top ]
 
         , builder HsCpp ? flag WithLibdw ? arg "-DUSE_LIBDW"
         , builder HsCpp ? flag HaveLibMingwEx ? arg "-DHAVE_LIBMINGWEX" ]
diff --git a/libraries/ghci/ghci.cabal.in b/libraries/ghci/ghci.cabal.in
index e9922ab24a57..06f7eca0c514 100644
--- a/libraries/ghci/ghci.cabal.in
+++ b/libraries/ghci/ghci.cabal.in
@@ -58,8 +58,6 @@ library
             GHCi.StaticPtrTable
             GHCi.TH
 
-    include-dirs: @FFIIncludeDir@
-
     exposed-modules:
         GHCi.BreakArray
         GHCi.BinaryArray
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index 3e7c94ae8208..be94c2383957 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -151,7 +151,10 @@ library
     install-includes: Cmm.h HsFFI.h MachDeps.h Rts.h RtsAPI.h Stg.h
                       ghcautoconf.h ghcconfig.h ghcplatform.h ghcversion.h
                       -- ^ from ../includes
-                      DerivedConstants.h ffi.h ffitarget.h
+                      DerivedConstants.h
+                      ffi.h ffitarget.h
+                      -- ^ see Note [Packaging libffi headers] in
+                      -- GHC.Driver.CodeOutput.
                       -- ^ generated
                       rts/Adjustor.h
                       rts/ExecPage.h
-- 
GitLab