summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Theriault <alec.theriault@gmail.com>2019-01-07 11:38:11 -0800
committerBen Gamari <ben@smart-cactus.org>2019-01-16 14:16:51 -0500
commit2f65025eeb4a79458af26d759e932d70633a64db (patch)
tree4e4951d5e5d9e183b246201c4c8efc3f9b5d3c0a
parent6a7a6b865bdb637a3ab69b9bccc390b85c147878 (diff)
downloadhaskell-2f65025eeb4a79458af26d759e932d70633a64db.tar.gz
Hadrian: support extra libraries + OSX rpath
Summary: This fixes some of the issues that surfaced when trying to build dynamic GHC on OSX. Unfortunately, due some other `libffi` issues, this doesn't completely fix dynamic builds on OSX. - Use 'extra-libraries' from .cabal files instead of hardcoding which packages need which extra libs. Also add support for 'extra-lib-dirs'. - Make sure Hadrian looks in the right places to support both plain '<pkg>.buildinfo' and '<pkg>.buildinfo.in' files. - Make the '-rpath' support more robust across OS's (it previously didn't work on OSX and possibly windows either). Reviewers: angerman, alpmestan, adamse, DavidEichmann, bgamari, Phyx Subscribers: rwbarton, carter GHC Trac Issues: #15990 Differential Revision: https://phabricator.haskell.org/D5409
-rw-r--r--hadrian/src/Context.hs9
-rw-r--r--hadrian/src/Hadrian/Haskell/Cabal/Parse.hs14
-rw-r--r--hadrian/src/Oracles/Setting.hs10
-rw-r--r--hadrian/src/Rules/BinaryDist.hs4
-rw-r--r--hadrian/src/Settings/Builders/Ghc.hs21
5 files changed, 34 insertions, 24 deletions
diff --git a/hadrian/src/Context.hs b/hadrian/src/Context.hs
index 8036eb00bc..7943e6dfce 100644
--- a/hadrian/src/Context.hs
+++ b/hadrian/src/Context.hs
@@ -51,12 +51,15 @@ libPath :: Context -> Action FilePath
libPath context = buildRoot <&> (-/- libDir context)
-- | Get the directory name for binary distribution files
--- <arch>-<os>-ghc-<version>.
+-- @<arch>-<os>-ghc-<version>@.
+--
+-- We preform some renaming to accomodate Cabal's slightly different naming
+-- conventions (see 'cabalOsString' and 'cabalArchString').
distDir :: Action FilePath
distDir = do
version <- setting ProjectVersion
- hostOs <- setting BuildOs
- hostArch <- setting BuildArch
+ hostOs <- cabalOsString <$> setting BuildOs
+ hostArch <- cabalArchString <$> setting BuildArch
return $ hostArch ++ "-" ++ hostOs ++ "-ghc-" ++ version
pkgFile :: Context -> String -> String -> Action FilePath
diff --git a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
index bb2f0be3da..995270184b 100644
--- a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
+++ b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
@@ -208,7 +208,7 @@ resolveContextData context@Context {..} = do
-- Create the @cabal_macros.h@, ...
-- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path
-- from the local build info @lbi@.
- pdi <- liftIO $ getHookedBuildInfo (pkgPath package)
+ pdi <- liftIO $ getHookedBuildInfo [pkgPath package, cPath -/- "build"]
let pd' = C.updatePackageDescription pdi pd
lbi' = lbi { C.localPkgDescr = pd' }
liftIO $ C.initialBuildSteps cPath pd' lbi' C.silent
@@ -282,12 +282,12 @@ resolveContextData context@Context {..} = do
, depLdOpts = forDeps Installed.ldOptions
, buildGhciLib = C.withGHCiLib lbi' }
-getHookedBuildInfo :: FilePath -> IO C.HookedBuildInfo
-getHookedBuildInfo baseDir = do
- -- TODO: We should probably better generate this in the build directory,
- -- rather than in the base directory? However, @configure@ is run in the
- -- base directory.
+-- | Look for a @.buildinfo@ in all of the specified directories, stopping on
+-- the first one we find.
+getHookedBuildInfo :: [FilePath] -> IO C.HookedBuildInfo
+getHookedBuildInfo [] = return C.emptyHookedBuildInfo
+getHookedBuildInfo (baseDir:baseDirs) = do
maybeInfoFile <- C.findHookedPackageDesc baseDir
case maybeInfoFile of
- Nothing -> return C.emptyHookedBuildInfo
+ Nothing -> getHookedBuildInfo baseDirs
Just infoFile -> C.readHookedBuildInfo C.silent infoFile
diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs
index 5197b8ea54..02ac42e0c9 100644
--- a/hadrian/src/Oracles/Setting.hs
+++ b/hadrian/src/Oracles/Setting.hs
@@ -3,7 +3,7 @@ module Oracles.Setting (
getSettingList, anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs,
ghcWithInterpreter, ghcEnableTablesNextToCode, useLibFFIForAdjustors,
ghcCanonVersion, cmdLineLengthLimit, iosHost, osxHost, windowsHost,
- topDirectory, libsuf
+ hostSupportsRPaths, topDirectory, libsuf
) where
import Hadrian.Expression
@@ -166,6 +166,14 @@ iosHost = anyHostOs ["ios"]
osxHost :: Action Bool
osxHost = anyHostOs ["darwin"]
+-- | Check whether the host OS supports the @-rpath@ linker option when
+-- using dynamic linking.
+--
+-- TODO: Windows supports lazy binding (but GHC doesn't currently support
+-- dynamic way on Windows anyways).
+hostSupportsRPaths :: Action Bool
+hostSupportsRPaths = anyHostOs ["linux", "darwin", "freebsd"]
+
-- | Check whether the host OS setting is set to @"mingw32"@ or @"cygwin32"@.
windowsHost :: Action Bool
windowsHost = anyHostOs ["mingw32", "cygwin32"]
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs
index a589c7af98..f847af9166 100644
--- a/hadrian/src/Rules/BinaryDist.hs
+++ b/hadrian/src/Rules/BinaryDist.hs
@@ -98,14 +98,12 @@ bindistRules = do
version <- setting ProjectVersion
targetPlatform <- setting TargetPlatformFull
- cabalHostOs <- cabalOsString <$> setting BuildOs
- cabalHostArch <- cabalArchString <$> setting BuildArch
+ distDir <- Context.distDir
rtsDir <- pkgIdentifier rts
let ghcBuildDir = root -/- stageString Stage1
bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty
ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
- distDir = cabalHostArch ++ "-" ++ cabalHostOs ++ "-ghc-" ++ version
rtsIncludeDir = ghcBuildDir -/- "lib" -/- distDir -/- rtsDir
-/- "include"
diff --git a/hadrian/src/Settings/Builders/Ghc.hs b/hadrian/src/Settings/Builders/Ghc.hs
index a605873d77..4957de77fe 100644
--- a/hadrian/src/Settings/Builders/Ghc.hs
+++ b/hadrian/src/Settings/Builders/Ghc.hs
@@ -43,10 +43,10 @@ compileC = builder (Ghc CompileCWithGhc) ? do
ghcLinkArgs :: Args
ghcLinkArgs = builder (Ghc LinkHs) ? do
pkg <- getPackage
- libs <- pkg == hp2ps ? pure ["m"]
- intLib <- getIntegerPackage
- gmpLibs <- notStage0 ? intLib == integerGmp ? pure ["gmp"]
+ libs <- getContextData extraLibs
+ libDirs <- getContextData extraLibDirs
dynamic <- requiresDynamic
+ darwin <- expr osxHost
-- Relative path from the output (rpath $ORIGIN).
originPath <- dropFileName <$> getOutput
@@ -56,20 +56,21 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
let
distPath = libPath' -/- distDir
originToLibsDir = makeRelativeNoSysLink originPath distPath
+ rpath | darwin = "@loader_path" -/- originToLibsDir
+ | otherwise = "$ORIGIN" -/- originToLibsDir
mconcat [ dynamic ? mconcat
[ arg "-dynamic"
- -- TODO what about windows / OSX?
- , notStage0 ? pure
- [ "-optl-Wl,-rpath"
- , "-optl-Wl," ++ ("$ORIGIN" -/- originToLibsDir) ]
+ -- TODO what about windows?
+ , isLibrary pkg ? pure [ "-shared", "-dynload", "deploy" ]
+ , notStage0 ?
+ hostSupportsRPaths ? arg ("-optl-Wl,-rpath," ++ rpath)
]
- , (dynamic && isLibrary pkg) ?
- pure [ "-shared", "-dynload", "deploy" ]
, arg "-no-auto-link-packages"
, nonHsMainPackage pkg ? arg "-no-hs-main"
, not (nonHsMainPackage pkg) ? arg "-rtsopts"
- , pure [ "-optl-l" ++ lib | lib <- libs ++ gmpLibs ]
+ , pure [ "-l" ++ lib | lib <- libs ]
+ , pure [ "-L" ++ libDir | libDir <- libDirs ]
]
findHsDependencies :: Args