diff options
author | Alec Theriault <alec.theriault@gmail.com> | 2019-01-07 11:38:11 -0800 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2019-01-16 14:16:51 -0500 |
commit | 2f65025eeb4a79458af26d759e932d70633a64db (patch) | |
tree | 4e4951d5e5d9e183b246201c4c8efc3f9b5d3c0a | |
parent | 6a7a6b865bdb637a3ab69b9bccc390b85c147878 (diff) | |
download | haskell-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.hs | 9 | ||||
-rw-r--r-- | hadrian/src/Hadrian/Haskell/Cabal/Parse.hs | 14 | ||||
-rw-r--r-- | hadrian/src/Oracles/Setting.hs | 10 | ||||
-rw-r--r-- | hadrian/src/Rules/BinaryDist.hs | 4 | ||||
-rw-r--r-- | hadrian/src/Settings/Builders/Ghc.hs | 21 |
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 |