Add Install Rules (#312)
authorZhen Zhang <izgzhen@gmail.com>
Sun, 25 Jun 2017 17:37:20 +0000 (01:37 +0800)
committerAndrey Mokhov <andrey.mokhov@gmail.com>
Sun, 25 Jun 2017 17:37:20 +0000 (19:37 +0200)
14 files changed:
hadrian.cabal
src/GHC.hs
src/Main.hs
src/Oracles/Config/Setting.hs
src/Rules.hs
src/Rules/Generate.hs
src/Rules/Install.hs [new file with mode: 0644]
src/Rules/Program.hs
src/Rules/Wrappers.hs
src/Settings.hs
src/Settings/Builders/GhcCabal.hs
src/Settings/Packages/Rts.hs
src/Settings/Path.hs
src/UserSettings.hs

index f737d03..fbda4b0 100644 (file)
@@ -55,6 +55,7 @@ executable hadrian
                        , Rules.Generators.GhcVersionH
                        , Rules.Generators.VersionHs
                        , Rules.Gmp
+                       , Rules.Install
                        , Rules.Libffi
                        , Rules.Library
                        , Rules.Oracles
index 78bb356..0f5e2fb 100644 (file)
@@ -4,7 +4,7 @@ module GHC (
     array, base, binary, bytestring, cabal, checkApiAnnotations, compareSizes,
     compiler, containers, deepseq, deriveConstants, directory, dllSplit, filepath,
     genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCabal, ghcCompact, ghci,
-    ghcPkg, ghcPrim, ghcTags, haddock, haskeline, hsc2hs, hp2ps,
+    ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock, haskeline, hsc2hs, hp2ps,
     hpc, hpcBin, integerGmp, integerSimple, iservBin, libffi, mkUserGuidePart,
     parallel, pretty, primitive, process, rts, runGhc, stm, templateHaskell,
     terminfo, time, touchy, transformers, unlit, unix, win32, xhtml,
@@ -59,6 +59,7 @@ ghci                = library  "ghci"
 ghcPkg              = utility  "ghc-pkg"
 ghcPrim             = library  "ghc-prim"
 ghcTags             = utility  "ghctags"
+ghcSplit            = utility  "ghc-split"
 haddock             = utility  "haddock"
 haskeline           = library  "haskeline"
 hsc2hs              = utility  "hsc2hs"
index a780545..0f65ecf 100644 (file)
@@ -6,6 +6,7 @@ import qualified CmdLineFlag
 import qualified Environment
 import qualified Rules
 import qualified Rules.Clean
+import qualified Rules.Install
 import qualified Rules.Oracles
 import qualified Rules.SourceDist
 import qualified Rules.Selftest
@@ -29,6 +30,7 @@ main = shakeArgsWith options CmdLineFlag.cmdFlags $ \cmdLineFlags targets -> do
         Rules.Test.testRules
         Rules.buildRules
         Rules.topLevelTargets
+        Rules.Install.installRules
     options :: ShakeOptions
     options = shakeOptions
         { shakeChange   = ChangeModtimeAndDigest
index 8bdc387..88fb382 100644 (file)
@@ -53,6 +53,7 @@ data Setting = BuildArch
              | IconvIncludeDir
              | IconvLibDir
              -- Paths to where GHC is installed
+             -- ref: mk/install.mk
              | InstallPrefix
              | InstallBinDir
              | InstallLibDir
index 082d509..71d631f 100644 (file)
@@ -1,4 +1,4 @@
-module Rules (topLevelTargets, buildRules) where
+module Rules (topLevelTargets, buildLib, buildRules) where
 
 import Base
 import Context
@@ -30,18 +30,21 @@ topLevelTargets = do
     want $ Rules.Generate.inplaceLibCopyTargets
 
     forM_ allStages $ \stage ->
-        forM_ (knownPackages \\ [rts, libffi]) $ \pkg -> action $ do
-            let context = vanillaContext stage pkg
-            activePackages <- interpretInContext context getPackages
-            when (pkg `elem` activePackages) $
-                if isLibrary pkg
-                then do -- build a library
-                    ways <- interpretInContext context getLibraryWays
-                    libs <- mapM (pkgLibraryFile . Context stage pkg) ways
-                    docs <- interpretInContext context $ buildHaddock flavour
-                    need $ libs ++ [ pkgHaddockFile context | docs && stage == Stage1 ]
-                else -- otherwise build a program
-                    need =<< maybeToList <$> programPath (programContext stage pkg)
+        forM_ (knownPackages \\ [rts, libffi]) $ \pkg -> action (buildLib stage pkg)
+
+buildLib :: Stage -> Package -> Action ()
+buildLib stage pkg = do
+    let context = vanillaContext stage pkg
+    activePackages <- interpretInContext context getPackages
+    when (pkg `elem` activePackages) $
+        if isLibrary pkg
+        then do -- build a library
+            ways <- interpretInContext context getLibraryWays
+            libs <- mapM (pkgLibraryFile . Context stage pkg) ways
+            docs <- interpretInContext context $ buildHaddock flavour
+            need $ libs ++ [ pkgHaddockFile context | docs && stage == Stage1 ]
+        else -- otherwise build a program
+            need =<< maybeToList <$> programPath (programContext stage pkg)
 
 packageRules :: Rules ()
 packageRules = do
index 2e4fa73..3507027 100644 (file)
@@ -1,6 +1,6 @@
 module Rules.Generate (
     isGeneratedCFile, isGeneratedCmmFile, generatePackageCode, generateRules,
-    inplaceLibCopyTargets, copyRules, includesDependencies, generatedDependencies
+    copyRules, includesDependencies, generatedDependencies, inplaceLibCopyTargets
     ) where
 
 import Base
@@ -64,7 +64,7 @@ ghcPrimDependencies = do
     return [path -/- "GHC/Prim.hs", path -/- "GHC/PrimopWrappers.hs"]
 
 derivedConstantsDependencies :: [FilePath]
-derivedConstantsDependencies = inplaceLibCopyTargets ++ fmap (generatedPath -/-)
+derivedConstantsDependencies = fmap (generatedPath -/-)
     [ "DerivedConstants.h"
     , "GHCConstantsHaskellExports.hs"
     , "GHCConstantsHaskellType.hs"
diff --git a/src/Rules/Install.hs b/src/Rules/Install.hs
new file mode 100644 (file)
index 0000000..3499b26
--- /dev/null
@@ -0,0 +1,310 @@
+{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}
+module Rules.Install (installRules) where
+
+import Base
+import Target
+import Context
+import Predicate hiding (builder)
+import Settings
+import Settings.Path
+import Util
+import GHC
+import Rules
+import Rules.Wrappers (WrappedBinary(..), installWrappers)
+import Rules.Libffi
+import Rules.Generate
+import Settings.Packages.Rts
+import Oracles.Config.Setting
+import Oracles.PackageData
+import Oracles.Path
+
+import qualified System.Directory.Extra as IO
+
+{- | Install the built binaries etc. to the @destDir ++ prefix@.
+
+The installation prefix is usually like @/usr/local@ on Unix system.
+The resulting tree structure is organized under @destDir ++ prefix@, like below
+
+* @bin@: executable wrapper scripts, installed by 'installBins', e.g. @ghc@
+* @lib/ghc-<version>/bin@: executable binaries/scripts,
+  installed by 'installLibExecs' and 'installLibExecScripts'
+* @lib/ghc-<version>/include@: headers etc., installed by 'installIncludes'
+* @lib/ghc-<version>/<pkg-name>@: built packages, installed by 'installPackages',
+  e.g. @base@
+* @lib/ghc-<version>/settings@ etc.: other files in @lib@ path, installed by
+  'installCommonLibs'
+
+XXX (izgzhen): Do we need @INSTALL_OPTS@ in the make scripts?
+-}
+installRules :: Rules ()
+installRules = do
+    "install" ~> do
+        installPackageConf
+        installIncludes
+        installCommonLibs
+        installLibExecs
+        installLibExecScripts
+        installBins
+        installPackages
+
+getLibExecDir :: Action FilePath
+getLibExecDir = (-/- "bin") <$> installGhcLibDir
+
+-- | Install executable scripts to @prefix/lib/bin@
+-- ref: ghc.mk
+installLibExecScripts :: Action ()
+installLibExecScripts = do
+    need libExecScripts
+    libExecDir <- getLibExecDir
+    installDir (destDir ++ libExecDir)
+    forM_ libExecScripts $ \script -> do
+        installScript script (destDir ++ libExecDir)
+  where
+    libExecScripts :: [FilePath]
+    libExecScripts = [ ghcSplitPath ]
+
+
+-- | Install executable binaries to @prefix/lib/bin@
+-- ref: ghc.mk
+installLibExecs :: Action ()
+installLibExecs = do
+    libExecDir <- getLibExecDir
+    installDir (destDir ++ libExecDir)
+    forM_ installBinPkgs $ \pkg -> do
+        withLatestBuildStage pkg $ \stg -> do
+            let context = programContext stg pkg
+            let bin = inplaceLibBinPath -/- programName context <.> exe
+            need [bin]
+            installProgram bin (destDir ++ libExecDir)
+            when (pkg == ghc) $ do
+                moveFile (destDir ++ libExecDir -/- programName context <.> exe)
+                         (destDir ++ libExecDir -/- "ghc" <.> exe)
+
+-- | Binaries to install
+-- TODO: Consider Stage1Only
+installBinPkgs :: [Package]
+installBinPkgs =
+    [ ghc, ghcPkg, ghcSplit, hp2ps
+    , hpc, hsc2hs, runGhc, unlit ]
+
+-- | Install executable wrapper scripts to @prefix/bin@
+-- ref: ghc.mk
+installBins :: Action ()
+installBins = do
+    binDir <- setting InstallBinDir
+    installDir (destDir ++ binDir)
+    forM_ installBinPkgs $ \pkg ->
+        withLatestBuildStage pkg $ \stg -> do
+            let context = programContext stg pkg
+            version <- setting ProjectVersion
+            -- binary's name
+            let binName = if pkg == ghc
+                          then "ghc-" ++ version <.> exe
+                          else programName context ++ "-" ++ version <.> exe
+            -- symbolic link's name
+            let symName = if pkg == ghc
+                          then "ghc" <.> exe
+                          else programName context <.> exe
+            case lookup context installWrappers of
+                Nothing -> return ()
+                Just wrapper -> do
+                    libDir <- installGhcLibDir
+                    contents <- interpretInContext context $
+                                    wrapper
+                                    (WrappedBinary (destDir ++ libDir) symName)
+                    withTempDir $ \tmp -> do
+                        let tmpfile = tmp -/- binName
+                        writeFileChanged tmpfile contents
+                        installProgram tmpfile (destDir ++ binDir)
+                    unlessM windowsHost $
+                        linkSymbolic (destDir ++ binDir -/- binName)
+                                     (destDir ++ binDir -/- symName)
+
+withLatestBuildStage :: Package -> (Stage -> Action ()) -> Action ()
+withLatestBuildStage pkg m = do
+  stg' <- latestBuildStage pkg
+  case stg' of
+      Nothing -> return ()
+      Just stg -> m stg
+
+-- | Install @package.conf.install@ for each package
+-- Note that each time it will be recreated
+-- ref: rules/manual-package-conf.mk
+installPackageConf :: Action ()
+installPackageConf = do
+    let context = vanillaContext Stage0 rts
+    build $ Target context HsCpp [ pkgPath rts -/- "package.conf.in" ]
+                                 [ pkgConfInstallPath <.> "raw" ]
+    Stdout out <- cmd ("grep" :: String) [ "-v", "^#pragma GCC"
+                                         , pkgConfInstallPath <.> "raw" ]
+    withTempFile $ \tmp -> do
+        liftIO $ writeFile tmp out
+        Stdout out' <- cmd ("sed" :: String)
+                           [ "-e", "s/\"\"//g", "-e", "s/:[   ]*,/: /g", tmp ]
+        liftIO $ writeFile pkgConfInstallPath out'
+
+-- | Install packages to @prefix/lib@
+-- ref: ghc.mk
+installPackages :: Action ()
+installPackages = do
+    need [ pkgConfInstallPath ]
+
+    ghcLibDir <- installGhcLibDir
+    binDir <- setting InstallBinDir
+
+    -- Install package.conf
+    let installedPackageConf = destDir ++ ghcLibDir -/- "package.conf.d"
+    installDir (destDir ++ ghcLibDir)
+    removeDirectory installedPackageConf
+    installDir installedPackageConf
+
+    -- Install RTS
+    let rtsDir = destDir ++ ghcLibDir -/- "rts"
+    installDir rtsDir
+    ways <- interpretInContext (vanillaContext Stage1 rts) getRtsWays
+    rtsLibs <- mapM pkgLibraryFile $ map (Context Stage1 rts) ways
+    ffiLibs <- sequence $ map rtsLibffiLibrary ways
+
+    -- TODO: Add dynamic ones
+    forM_ (rtsLibs ++ ffiLibs) $ \lib -> installData [lib] rtsDir
+
+    -- HACK (issue #327)
+    let ghcBootPlatformHeader =
+          buildPath (vanillaContext Stage1 compiler) -/-
+          "ghc_boot_platform.h"
+
+    copyFile ghcBootPlatformHeader (pkgPath compiler -/- "ghc_boot_platform.h")
+
+    -- TODO: Consider Stage1Only
+    -- TODO: Use automatic dependency analysis, rather than hardcoding
+    -- the ordering
+    let installLibPkgs = [ ghcPrim, integerSimple, base, filepath
+                         , array, deepseq, bytestring, containers, time, unix
+                         , directory, process, hpc, pretty, binary, cabal
+                         , ghcBootTh, ghcBoot, templateHaskell
+                         , transformers, terminfo, haskeline, ghci, compiler ]
+
+    forM_ installLibPkgs $ \pkg@Package{..} -> do
+        when (isLibrary pkg) $
+            withLatestBuildStage pkg $ \stg -> do
+                let context = vanillaContext stg pkg
+                top <- interpretInContext context getTopDirectory
+                let installDistDir = top -/- buildPath context
+                buildLib stg pkg
+                docDir <- installDocDir
+                ghclibDir <- installGhcLibDir
+                version <- interpretInContext context (getPkgData Version)
+                -- Copy over packages
+                let targetDest = destDir ++ ghclibDir -/-
+                                 pkgNameString pkg ++ "-" ++ version
+                strip <- stripCmdPath context
+                ways <- interpretInContext context getLibraryWays
+                let ghcCabalInplace = inplaceBinPath -/- "ghc-cabal" -- HACK?
+
+                -- HACK (#318): copy stuff back to the place favored by ghc-cabal
+                quietly $ copyDirectoryContents (Not excluded)
+                            installDistDir (installDistDir -/- "build")
+                pref <- setting InstallPrefix
+                unit $ cmd ghcCabalInplace
+                           [ "copy"
+                           , pkgPath
+                           , installDistDir
+                           , strip
+                           , destDir
+                           , pref
+                           , ghclibDir
+                           , docDir -/- "html/libraries"
+                           , intercalate "  " (map show ways) ]
+
+    -- Register packages
+    let installedGhcPkgReal = destDir ++ binDir -/- "ghc-pkg" <.> exe
+    let installedGhcReal = destDir ++ binDir -/- "ghc" <.> exe
+    -- TODO: Extend GhcPkg builder args to support --global-package-db
+    unit $ cmd installedGhcPkgReal
+               [ "--force", "--global-package-db"
+               , installedPackageConf, "update"
+               , pkgConfInstallPath ]
+
+    forM_ installLibPkgs $ \pkg@Package{..} -> do
+        when (isLibrary pkg) $
+            withLatestBuildStage pkg $ \stg -> do
+                let context = vanillaContext stg pkg
+                top <- interpretInContext context getTopDirectory
+                let installDistDir = top -/- buildPath context
+                -- TODO: better reference to the built inplace binary path
+                let ghcCabalInplace = inplaceBinPath -/- "ghc-cabal"
+                pref <- setting InstallPrefix
+                docDir <- installDocDir
+                r <- relocatableBuild
+                unit $ cmd ghcCabalInplace
+                           [ "register"
+                           , pkgPath
+                           , installDistDir
+                           , installedGhcReal
+                           , installedGhcPkgReal
+                           , destDir ++ ghcLibDir
+                           , destDir
+                           , destDir ++ pref
+                           , destDir ++ ghcLibDir
+                           , destDir ++ docDir -/- "html/libraries"
+                           , if r then "YES" else "NO" ]
+
+    confs <- getDirectoryContents installedPackageConf
+    forM_ confs (\f -> createData $ installedPackageConf -/- f)
+    unit $ cmd installedGhcPkgReal
+               [ "--force", "--global-package-db"
+               , installedPackageConf, "recache" ]
+  where
+    createData f = unit $ cmd ("chmod" :: String) [ "644", f ]
+    excluded = Or
+        [ Test "//haddock-prologue.txt"
+        , Test "//package-data.mk"
+        , Test "//setup-config"
+        , Test "//inplace-pkg-config"
+        , Test "//build" ]
+
+-- | Install settings etc. files to @prefix/lib@
+-- ref: ghc.mk
+installCommonLibs :: Action ()
+installCommonLibs = do
+    ghcLibDir <- installGhcLibDir
+    installLibsTo inplaceLibCopyTargets (destDir ++ ghcLibDir)
+
+-- | Install library files to some path
+-- ref: ghc.mk
+installLibsTo :: [FilePath] -> FilePath -> Action ()
+installLibsTo libs dir = do
+    installDir dir
+    forM_ libs $ \lib -> do
+       case takeExtension lib of
+           ".a" -> do
+               let out = dir -/- takeFileName lib
+               installData [out] dir
+               let context = vanillaContext Stage0 $ topLevel (PackageName "")
+               -- TODO: Get rid of meaningless context for certain builder like ranlib
+               build $ Target context Ranlib [out] [out]
+           _ -> installData [lib] dir
+
+-- | All header files are in includes/{one of these subdirectories}
+-- ref: includes/ghc.mk
+includeHSubdirs :: [FilePath]
+includeHSubdirs = [ ".", "rts", "rts/prof", "rts/storage", "stg" ]
+
+-- | Install header files to @prefix/lib/ghc-<version>/include@
+-- ref: includes/ghc.mk
+installIncludes ::Action ()
+installIncludes = do
+    ghclibDir <- installGhcLibDir
+    let ghcheaderDir = ghclibDir -/- "include"
+    installDir (destDir ++ ghcheaderDir)
+    forM_ includeHSubdirs $ \d -> do
+        installDir (destDir ++ ghcheaderDir -/- d)
+        headers <- getDirectoryFiles ("includes" -/- d) ["*.h"]
+        installHeader (map (("includes" -/- d) -/-) headers)
+                      (destDir ++ ghcheaderDir -/- d ++ "/")
+    installHeader (includesDependencies ++
+                   [generatedPath -/- "DerivedConstants.h"] ++
+                   libffiDependencies)
+                  (destDir ++ ghcheaderDir ++ "/")
+  where
+    installHeader = installData -- they share same arguments
index 5b2e66f..12e661b 100644 (file)
@@ -11,9 +11,7 @@ import Oracles.Dependencies
 import Oracles.ModuleFiles
 import Oracles.PackageData
 import Oracles.Path (topDirectory)
-import Rules.Wrappers (WrappedBinary(..), Wrapper,
-                       ghcWrapper, runGhcWrapper, inplaceGhcPkgWrapper,
-                       hpcWrapper, hp2psWrapper, hsc2hsWrapper)
+import Rules.Wrappers (WrappedBinary(..), Wrapper, inplaceWrappers)
 import Settings
 import Settings.Path (buildPath, inplaceLibBinPath, rtsContext, objectPath,
                       inplaceLibPath, inplaceBinPath)
@@ -21,16 +19,6 @@ import Target
 import UserSettings
 import Util
 
--- | List of wrappers we build.
-wrappers :: [(Context, Wrapper)]
-wrappers = [ (vanillaContext Stage0 ghc   , ghcWrapper)
-           , (vanillaContext Stage1 ghc   , ghcWrapper)
-           , (vanillaContext Stage1 runGhc, runGhcWrapper)
-           , (vanillaContext Stage0 ghcPkg, inplaceGhcPkgWrapper)
-           , (vanillaContext Stage1 hp2ps , hp2psWrapper)
-           , (vanillaContext Stage1 hpc   , hpcWrapper)
-           , (vanillaContext Stage1 hsc2hs, hsc2hsWrapper) ]
-
 buildProgram :: [(Resource, Int)] -> Context -> Rules ()
 buildProgram rs context@Context {..} = when (isProgram package) $ do
     let installStage = do
@@ -56,7 +44,7 @@ buildBinaryAndWrapper rs context bin = do
     windows <- windowsHost
     if windows
     then buildBinary rs context bin -- We don't build wrappers on Windows
-    else case lookup context wrappers of
+    else case lookup context inplaceWrappers of
         Nothing      -> buildBinary rs context bin -- No wrapper found
         Just wrapper -> do
             top <- topDirectory
index 246d28a..b793cfb 100644 (file)
@@ -1,11 +1,10 @@
 module Rules.Wrappers (
-  WrappedBinary(..), Wrapper, ghcWrapper, runGhcWrapper,
-  inplaceGhcPkgWrapper, installGhcPkgWrapper, hp2psWrapper,
-  hpcWrapper, hsc2hsWrapper
+  WrappedBinary(..), Wrapper, inplaceWrappers, installWrappers
   ) where
 
 import Base
 import Expression
+import GHC
 import Settings.Install (installPackageDbDirectory)
 import Settings.Path (inplacePackageDbDirectory)
 import Oracles.Path (getTopDirectory)
@@ -28,14 +27,22 @@ ghcWrapper WrappedBinary{..} = do
         , "exec " ++ (binaryLibPath -/- "bin" -/- binaryName)
           ++ " -B" ++ binaryLibPath ++ " ${1+\"$@\"}" ]
 
+inplaceRunGhcWrapper :: WrappedBinary -> Expr String
+inplaceRunGhcWrapper WrappedBinary{..} = do
+    lift $ need [sourcePath -/- "Rules/Wrappers.hs"]
+    return $ unlines
+        [ "#!/bin/bash"
+        , "exec " ++ (binaryLibPath -/- "bin" -/- binaryName)
+          ++ " -f" ++ (binaryLibPath -/- "bin/ghc-stage2") -- TODO: use ProgramName
+          ++ " -B" ++ binaryLibPath ++ " ${1+\"$@\"}" ]
 
-runGhcWrapper :: WrappedBinary -> Expr String
-runGhcWrapper WrappedBinary{..} = do
+installRunGhcWrapper :: WrappedBinary -> Expr String
+installRunGhcWrapper WrappedBinary{..} = do
     lift $ need [sourcePath -/- "Rules/Wrappers.hs"]
     return $ unlines
         [ "#!/bin/bash"
         , "exec " ++ (binaryLibPath -/- "bin" -/- binaryName)
-          ++ " -f" ++ (binaryLibPath -/- "bin/ghc-stage2") -- HACK
+          ++ " -f" ++ (binaryLibPath -/- "bin/ghc") -- TODO: use ProgramName
           ++ " -B" ++ binaryLibPath ++ " ${1+\"$@\"}" ]
 
 inplaceGhcPkgWrapper :: WrappedBinary -> Expr String
@@ -93,3 +100,23 @@ hsc2hsWrapper WrappedBinary{..} = do
         , "executablename=\"" ++ executableName ++ "\""
         , "HSC2HS_EXTRA=\"" ++ hsc2hsExtra ++ "\""
         , contents ]
+
+wrappersCommon :: [(Context, Wrapper)]
+wrappersCommon = [ (vanillaContext Stage0 ghc   , ghcWrapper)
+                 , (vanillaContext Stage1 ghc   , ghcWrapper)
+                 , (vanillaContext Stage1 hp2ps , hp2psWrapper)
+                 , (vanillaContext Stage1 hpc   , hpcWrapper)
+                 , (vanillaContext Stage1 hsc2hs, hsc2hsWrapper) ]
+
+-- | List of wrappers for inplace artefacts
+inplaceWrappers :: [(Context, Wrapper)]
+inplaceWrappers = wrappersCommon ++
+                  [ (vanillaContext Stage0 ghcPkg, inplaceGhcPkgWrapper)
+                  , (vanillaContext Stage1 runGhc, inplaceRunGhcWrapper) ]
+
+-- | List of wrappers for installation
+installWrappers :: [(Context, Wrapper)]
+installWrappers = wrappersCommon ++
+                  [ (vanillaContext Stage0 ghcPkg, installGhcPkgWrapper)
+                  , (vanillaContext Stage1 runGhc, installRunGhcWrapper) ]
+
index d581ec4..d09fa31 100644 (file)
@@ -3,7 +3,7 @@ module Settings (
     findKnownPackage, getPkgData, getPkgDataList, isLibrary, getPackagePath,
     getContextDirectory, getBuildPath, stagePackages, builderPath,
     getBuilderPath, isSpecified, latestBuildStage, programPath, programContext,
-    integerLibraryName
+    integerLibraryName, destDir, pkgConfInstallPath
     ) where
 
 import Base
@@ -114,3 +114,6 @@ programPath context@Context {..} = do
         install <- (\l -> l == stage || package == ghc) <$> maybeLatest
         let path = if install then installPath package else buildPath context
         return $ path -/- programName context <.> exe
+
+pkgConfInstallPath :: FilePath
+pkgConfInstallPath = buildPath (vanillaContext Stage0 rts) -/- "package.conf.install"
index 428c376..f9416df 100644 (file)
@@ -33,9 +33,10 @@ ghcCabalBuilderArgs = builder GhcCabal ? do
 
 ghcCabalHsColourBuilderArgs :: Args
 ghcCabalHsColourBuilderArgs = builder GhcCabalHsColour ? do
-    path <- getPackagePath
-    dir  <- getContextDirectory
-    append [ "hscolour", path, dir ]
+    path    <- getPackagePath
+    top     <- getTopDirectory
+    context <- getContext
+    append [ "hscolour", path, top -/- buildPath context ]
 
 -- TODO: Isn't vanilla always built? If yes, some conditions are redundant.
 -- TODO: Need compiler_stage1_CONFIGURE_OPTS += --disable-library-for-ghci?
index e278204..9252e26 100644 (file)
@@ -48,6 +48,7 @@ rtsPackageArgs = package rts ? do
     libffiName     <- lift rtsLibffiLibraryName
     ffiIncludeDir  <- getSetting FfiIncludeDir
     ffiLibraryDir  <- getSetting FfiLibDir
+    ghclibDir      <- lift installGhcLibDir
     mconcat
         [ builder Cc ? mconcat
           [ arg "-Irts"
@@ -91,7 +92,10 @@ rtsPackageArgs = package rts ? do
             , inputs ["//Evac_thr.c", "//Scav_thr.c"] ?
               append [ "-DPARALLEL_GC", "-Irts/sm" ]
 
-            , input "//StgCRun.c" ? windowsHost ? arg "-Wno-return-local-addr" ]
+            , input "//StgCRun.c" ? windowsHost ? arg "-Wno-return-local-addr"
+            , input "//RetainerProfile.c" ? flag GccIsClang ?
+                append [ "-Wno-incompatible-pointer-types" ]
+            ]
 
         , builder Ghc ? arg "-Irts"
 
@@ -99,7 +103,17 @@ rtsPackageArgs = package rts ? do
           [ "-DTOP="             ++ show top
           , "-DFFI_INCLUDE_DIR=" ++ show ffiIncludeDir
           , "-DFFI_LIB_DIR="     ++ show ffiLibraryDir
-          , "-DFFI_LIB="         ++ show libffiName ] ]
+          , "-DFFI_LIB="         ++ show libffiName ]
+
+        , builder HsCpp ?
+          input "//package.conf.in" ?
+          output "//package.conf.install.raw" ?
+          append
+            [ "-DINSTALLING"
+            , "-DLIB_DIR=\"" ++ destDir ++ ghclibDir ++ "\""
+            , "-DINCLUDE_DIR=\"" ++ destDir ++ ghclibDir -/- "include\""
+            ]
+        ]
 
 -- # If we're compiling on windows, enforce that we only support XP+
 -- # Adding this here means it doesn't have to be done in individual .c files
index 8c975bd..240f992 100644 (file)
@@ -5,7 +5,7 @@ module Settings.Path (
     rtsContext, rtsBuildPath, rtsConfIn, shakeFilesPath,inplacePackageDbDirectory,
     pkgConfFile, packageDbStamp, bootPackageConstraints, packageDependencies,
     objectPath, inplaceBinPath, inplaceLibBinPath, inplaceLibPath,
-    installPath, autogenPath, pkgInplaceConfig, ghcSplitPath
+    installPath, autogenPath, pkgInplaceConfig, ghcSplitPath, stripCmdPath
     ) where
 
 import Base
@@ -13,6 +13,8 @@ import Context
 import Expression
 import GHC
 import Oracles.PackageData
+import Oracles.Config.Setting (setting, Setting(..))
+import Oracles.Path (getTopDirectory)
 import UserSettings
 
 -- | Path to the directory containing the Shake database and other auxiliary
@@ -192,3 +194,16 @@ installPath pkg
 -- generated in "Rules.Generators.GhcSplit".
 ghcSplitPath :: FilePath
 ghcSplitPath = inplaceLibBinPath -/- "ghc-split"
+
+-- | Command line tool for stripping
+-- ref: mk/config.mk
+stripCmdPath :: Context -> Action FilePath
+stripCmdPath ctx = do
+    targetPlatform <- setting TargetPlatform
+    top <- interpretInContext ctx getTopDirectory
+    case targetPlatform of
+        "x86_64-unknown-mingw32" ->
+             return (top -/- "inplace/mingw/bin/strip.exe")
+        "arm-unknown-linux" ->
+             return ":" -- HACK: from the make-based system, see the ref above
+        _ -> return "strip"
index 09d70e1..96e6f4b 100644 (file)
@@ -4,7 +4,7 @@
 -- accidentally commit them.
 module UserSettings (
     buildRootPath, userFlavours, userKnownPackages, verboseCommands,
-    putBuild, putSuccess
+    putBuild, putSuccess, destDir
     ) where
 
 import System.Console.ANSI
@@ -42,3 +42,10 @@ putBuild = putColoured Dull Magenta
 -- | Customise build success messages (e.g. a package is built successfully).
 putSuccess :: String -> Action ()
 putSuccess = putColoured Dull Green
+
+-- | Path to the GHC install destination
+-- It is by default empty, representing the root of file system,
+-- or it might be a directory.
+-- It is usually used with @prefix@, like @/usr/local@
+destDir :: FilePath
+destDir = ""