Commit 2f65025e authored by Alec Theriault's avatar Alec Theriault Committed by Ben Gamari

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
parent 6a7a6b86
......@@ -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
......
......@@ -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
......@@ -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"]
......
......@@ -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"
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment