diff options
| author | Alp Mestanogullari <alpmestan@gmail.com> | 2019-02-01 09:53:34 +0100 |
|---|---|---|
| committer | Alp Mestanogullari <alpmestan@gmail.com> | 2019-02-01 09:53:34 +0100 |
| commit | 587e8103d17b65334e9c2b289596d7341e15f8dc (patch) | |
| tree | 6b382b9888b48738a5758ba793fdc4fcc8be9539 | |
| parent | 886ddb27bfbbb52c41690cd29e2ab3ed80bf5450 (diff) | |
| download | haskell-587e8103d17b65334e9c2b289596d7341e15f8dc.tar.gz | |
first attempt at a validate script
| -rw-r--r-- | hadrian/src/CommandLine.hs | 72 | ||||
| -rw-r--r-- | hadrian/src/Oracles/TestSettings.hs | 38 | ||||
| -rw-r--r-- | hadrian/src/Rules/BinaryDist.hs | 68 | ||||
| -rw-r--r-- | hadrian/src/Rules/Program.hs | 3 | ||||
| -rw-r--r-- | hadrian/src/Rules/Test.hs | 84 | ||||
| -rw-r--r-- | hadrian/src/Settings/Builders/Make.hs | 8 | ||||
| -rw-r--r-- | hadrian/src/Settings/Builders/RunTest.hs | 87 | ||||
| -rw-r--r-- | hadrian/src/Settings/Default.hs | 3 | ||||
| -rwxr-xr-x | validate | 182 |
9 files changed, 332 insertions, 213 deletions
diff --git a/hadrian/src/CommandLine.hs b/hadrian/src/CommandLine.hs index 1f940f2152..6d606a7914 100644 --- a/hadrian/src/CommandLine.hs +++ b/hadrian/src/CommandLine.hs @@ -8,11 +8,11 @@ import Data.Either import qualified Data.HashMap.Strict as Map import Data.List.Extra import Development.Shake hiding (Normal) -import Hadrian.Utilities hiding (buildRoot) +import qualified Hadrian.Utilities as HU import System.Console.GetOpt import System.Environment -data TestSpeed = Slow | Average | Fast deriving (Show, Eq) +data TestSpeed = Slow | Normal | Fast deriving (Show, Eq) -- | All arguments that can be passed to Hadrian via the command line. data CommandLineArgs = CommandLineArgs @@ -20,10 +20,10 @@ data CommandLineArgs = CommandLineArgs , flavour :: Maybe String , freeze1 :: Bool , integerSimple :: Bool - , progressColour :: UseColour - , progressInfo :: ProgressInfo + , progressColour :: HU.UseColour + , progressInfo :: HU.ProgressInfo , splitObjects :: Bool - , buildRoot :: BuildRoot + , buildRoot :: HU.BuildRoot , testArgs :: TestArgs } deriving (Eq, Show) @@ -34,10 +34,10 @@ defaultCommandLineArgs = CommandLineArgs , flavour = Nothing , freeze1 = False , integerSimple = False - , progressColour = Auto - , progressInfo = Brief + , progressColour = HU.Auto + , progressInfo = HU.Brief , splitObjects = False - , buildRoot = BuildRoot "_build" + , buildRoot = HU.BuildRoot "_build" , testArgs = defaultTestArgs } -- | These arguments are used by the `test` target. @@ -80,9 +80,9 @@ readBuildRoot :: Maybe FilePath -> Either String (CommandLineArgs -> CommandLine readBuildRoot ms = maybe (Left "Cannot parse build-root") (Right . set) (go =<< ms) where - go :: String -> Maybe BuildRoot - go = Just . BuildRoot - set :: BuildRoot -> CommandLineArgs -> CommandLineArgs + go :: String -> Maybe HU.BuildRoot + go = Just . HU.BuildRoot + set :: HU.BuildRoot -> CommandLineArgs -> CommandLineArgs set flag flags = flags { buildRoot = flag } readFreeze1 :: Either String (CommandLineArgs -> CommandLineArgs) @@ -95,25 +95,25 @@ readProgressColour :: Maybe String -> Either String (CommandLineArgs -> CommandL readProgressColour ms = maybe (Left "Cannot parse progress-colour") (Right . set) (go =<< lower <$> ms) where - go :: String -> Maybe UseColour - go "never" = Just Never - go "auto" = Just Auto - go "always" = Just Always + go :: String -> Maybe HU.UseColour + go "never" = Just HU.Never + go "auto" = Just HU.Auto + go "always" = Just HU.Always go _ = Nothing - set :: UseColour -> CommandLineArgs -> CommandLineArgs + set :: HU.UseColour -> CommandLineArgs -> CommandLineArgs set flag flags = flags { progressColour = flag } readProgressInfo :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readProgressInfo ms = maybe (Left "Cannot parse progress-info") (Right . set) (go =<< lower <$> ms) where - go :: String -> Maybe ProgressInfo - go "none" = Just None - go "brief" = Just Brief - go "normal" = Just Normal - go "unicorn" = Just Unicorn + go :: String -> Maybe HU.ProgressInfo + go "none" = Just HU.None + go "brief" = Just HU.Brief + go "normal" = Just HU.Normal + go "unicorn" = Just HU.Unicorn go _ = Nothing - set :: ProgressInfo -> CommandLineArgs -> CommandLineArgs + set :: HU.ProgressInfo -> CommandLineArgs -> CommandLineArgs set flag flags = flags { progressInfo = flag } readSplitObjects :: Either String (CommandLineArgs -> CommandLineArgs) @@ -160,7 +160,7 @@ readTestSpeed ms = go :: String -> Maybe TestSpeed go "fast" = Just Fast go "slow" = Just Slow - go "average" = Just Average + go "normal" = Just Normal go _ = Nothing set :: TestSpeed -> CommandLineArgs -> CommandLineArgs set flag flags = flags { testArgs = (testArgs flags) {testSpeed = flag} } @@ -223,18 +223,18 @@ optDescrs = -- | A type-indexed map containing Hadrian command line arguments to be passed -- to Shake via 'shakeExtra'. -cmdLineArgsMap :: IO (Map.HashMap TypeRep Dynamic) +cmdLineArgsMap :: IO (Map.HashMap HU.TypeRep HU.Dynamic) cmdLineArgsMap = do (opts, _, _) <- getOpt Permute optDescrs <$> getArgs let args = foldl (flip id) defaultCommandLineArgs (rights opts) - return $ insertExtra (progressColour args) -- Accessed by Hadrian.Utilities - $ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities - $ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities - $ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest - $ insertExtra args Map.empty + return $ HU.insertExtra (progressColour args) -- Accessed by Hadrian.Utilities + $ HU.insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities + $ HU.insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities + $ HU.insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest + $ HU.insertExtra args Map.empty cmdLineArgs :: Action CommandLineArgs -cmdLineArgs = userSetting defaultCommandLineArgs +cmdLineArgs = HU.userSetting defaultCommandLineArgs cmdConfigure :: Action Bool cmdConfigure = configure <$> cmdLineArgs @@ -242,19 +242,19 @@ cmdConfigure = configure <$> cmdLineArgs cmdFlavour :: Action (Maybe String) cmdFlavour = flavour <$> cmdLineArgs -lookupBuildRoot :: Map.HashMap TypeRep Dynamic -> BuildRoot -lookupBuildRoot = buildRoot . lookupExtra defaultCommandLineArgs +lookupBuildRoot :: Map.HashMap HU.TypeRep HU.Dynamic -> HU.BuildRoot +lookupBuildRoot = buildRoot . HU.lookupExtra defaultCommandLineArgs -lookupFreeze1 :: Map.HashMap TypeRep Dynamic -> Bool -lookupFreeze1 = freeze1 . lookupExtra defaultCommandLineArgs +lookupFreeze1 :: Map.HashMap HU.TypeRep HU.Dynamic -> Bool +lookupFreeze1 = freeze1 . HU.lookupExtra defaultCommandLineArgs cmdIntegerSimple :: Action Bool cmdIntegerSimple = integerSimple <$> cmdLineArgs -cmdProgressColour :: Action UseColour +cmdProgressColour :: Action HU.UseColour cmdProgressColour = progressColour <$> cmdLineArgs -cmdProgressInfo :: Action ProgressInfo +cmdProgressInfo :: Action HU.ProgressInfo cmdProgressInfo = progressInfo <$> cmdLineArgs cmdSplitObjects :: Action Bool diff --git a/hadrian/src/Oracles/TestSettings.hs b/hadrian/src/Oracles/TestSettings.hs index 1bf75b527d..827121c13d 100644 --- a/hadrian/src/Oracles/TestSettings.hs +++ b/hadrian/src/Oracles/TestSettings.hs @@ -2,10 +2,16 @@ -- | compiler. We need to search this file for required keys and setting -- | required for testsuite e.g. WORDSIZE, HOSTOS etc. -module Oracles.TestSettings (TestSetting (..), testSetting, testRTSSettings) where +module Oracles.TestSettings + ( TestSetting (..), testSetting, testRTSSettings + , getCompilerPath, getBinaryDirectory + ) where import Base import Hadrian.Oracles.TextFile +import Oracles.Setting (topDirectory, setting, Setting(..)) +import Settings (programContext) +import Packages testConfigFile :: Action FilePath testConfigFile = buildRoot <&> (-/- "test/ghcconfig") @@ -67,3 +73,33 @@ testRTSSettings :: Action [String] testRTSSettings = do file <- testConfigFile words <$> lookupValueOrError file "GhcRTSWays" + +-- | Directory to look for Binaries +-- | We assume that required programs are present in the same binary directory +-- | in which ghc is stored and that they have their conventional name. +-- | QUESTION : packages can be named different from their conventional names. +-- | For example, ghc-pkg can be named as ghc-pkg-version. In such cases, it will +-- | be impossible to search the binary. Only possible way will be to take user +-- | inputs for these directory also. boilerplate soes not account for this +-- | problem, but simply returns an error. How should we handle such cases? +getBinaryDirectory :: String -> Action FilePath +getBinaryDirectory "stage0" = takeDirectory <$> setting SystemGhc +getBinaryDirectory "stage1" = liftM2 (-/-) topDirectory (stageBinPath Stage0) +getBinaryDirectory "stage2" = liftM2 (-/-) topDirectory (stageBinPath Stage1) +getBinaryDirectory compiler = pure $ parentPath compiler + +-- | Set Test Compiler. +getCompilerPath :: String -> Action FilePath +getCompilerPath "stage0" = setting SystemGhc +getCompilerPath "stage1" = liftM2 (-/-) topDirectory (fullPath Stage0 ghc) +getCompilerPath "stage2" = liftM2 (-/-) topDirectory (fullPath Stage1 ghc) +getCompilerPath compiler = pure compiler + +-- | Returns parent path of test compiler +-- | TODO: Is there a simpler way to find parent directory? +parentPath :: String -> String +parentPath path = intercalate "/" $ init $ splitOn "/" path + +-- | TODO: Move to Hadrian utilities. +fullPath :: Stage -> Package -> Action FilePath +fullPath stage pkg = programPath =<< programContext stage pkg diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs index 03740cdad9..f73e8d22a6 100644 --- a/hadrian/src/Rules/BinaryDist.hs +++ b/hadrian/src/Rules/BinaryDist.hs @@ -91,11 +91,16 @@ you can simply do: bindistRules :: Rules () bindistRules = do root <- buildRootRules + phony "binary-dist" $ do - -- We 'need' all binaries and libraries - targets <- mapM pkgTarget =<< stagePackages Stage1 - need targets + version <- setting ProjectVersion + targetPlatform <- setting TargetPlatformFull + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + need [ root -/- "bindist" -/- ghcVersionPretty <.> "tar.xz" ] + + + root -/- "bindist" -/- "ghc-*.tar.xz" %> \archivePath -> do version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull distDir <- Context.distDir @@ -107,6 +112,10 @@ bindistRules = do rtsIncludeDir = ghcBuildDir -/- "lib" -/- distDir -/- rtsDir -/- "include" + -- We 'need' all binaries and libraries built by stage 1 + targets <- mapM pkgTarget =<< stagePackages Stage1 + need targets + -- We create the bindist directory at <root>/bindist/ghc-X.Y.Z-platform/ -- and populate it with Stage2 build results createDirectory bindistFilesDir @@ -131,11 +140,10 @@ bindistRules = do , "ghci-script", "ghci", "haddock", "hpc", "hp2ps", "hsc2hs" , "runghc"] - -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz command [Cwd $ root -/- "bindist"] "tar" - [ "-c", "--xz", "-f" - , ghcVersionPretty <.> "tar.xz" - , ghcVersionPretty ] + [ "-c", "--xz", "-f" + , takeFileName archivePath + , ghcVersionPretty ] -- Prepare binary distribution configure script -- (generated under <ghc root>/distrib/configure by 'autoreconf') @@ -224,19 +232,19 @@ bindistMakefile = unlines , "# to it. This implementation is a bit hacky and depends on consistency" , "# of program names. For hadrian build this will work as programs have a" , "# consistent naming procedure." - , "\trm -f $2" - , "\t$(CREATE_SCRIPT) $2" - , "\t@echo \"#!$(SHELL)\" >> $2" - , "\t@echo \"exedir=\\\"$4\\\"\" >> $2" - , "\t@echo \"exeprog=\\\"$1\\\"\" >> $2" - , "\t@echo \"executablename=\\\"$5\\\"\" >> $2" - , "\t@echo \"bindir=\\\"$3\\\"\" >> $2" - , "\t@echo \"libdir=\\\"$6\\\"\" >> $2" - , "\t@echo \"docdir=\\\"$7\\\"\" >> $2" - , "\t@echo \"includedir=\\\"$8\\\"\" >> $2" - , "\t@echo \"\" >> $2 " - , "\tcat wrappers/$1 >> $2" - , "\t$(EXECUTABLE_FILE) $2 ;" + , "\trm -f '$2'" + , "\t$(CREATE_SCRIPT) '$2'" + , "\t@echo \"#!$(SHELL)\" >> '$2'" + , "\t@echo \"exedir=\\\"$4\\\"\" >> '$2'" + , "\t@echo \"exeprog=\\\"$1\\\"\" >> '$2'" + , "\t@echo \"executablename=\\\"$5\\\"\" >> '$2'" + , "\t@echo \"bindir=\\\"$3\\\"\" >> '$2'" + , "\t@echo \"libdir=\\\"$6\\\"\" >> '$2'" + , "\t@echo \"docdir=\\\"$7\\\"\" >> '$2'" + , "\t@echo \"includedir=\\\"$8\\\"\" >> '$2'" + , "\t@echo \"\" >> '$2'" + , "\tcat wrappers/$1 >> '$2'" + , "\t$(EXECUTABLE_FILE) '$2' ;" , "endef" , "" , "# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'" @@ -245,10 +253,10 @@ bindistMakefile = unlines , "# $1 = package name (ex: 'bytestring')" , "# $2 = path to .conf file" , "# $3 = Docs Directory" - , "\tcat $2 | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" - , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" - , "\t > $2.copy" - , "\tmv $2.copy $2" + , "\tcat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" + , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" + , "\t > '$2.copy'" + , "\tmv '$2.copy' '$2'" , "endef" , "" , "# QUESTION : should we use shell commands?" @@ -273,10 +281,10 @@ bindistMakefile = unlines , "" , "install_ghci:" , "\t@echo \"Copying and installing ghci\"" - , "\t$(CREATE_SCRIPT) $(WrapperBinsDir)/ghci" - , "\t@echo \"#!$(SHELL)\" >> $(WrapperBinsDir)/ghci" - , "\tcat wrappers/ghci-script >> $(WrapperBinsDir)/ghci" - , "\t$(EXECUTABLE_FILE) $(WrapperBinsDir)/ghci" + , "\t$(CREATE_SCRIPT) '$(WrapperBinsDir)/ghci'" + , "\t@echo \"#!$(SHELL)\" >> '$(WrapperBinsDir)/ghci'" + , "\tcat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'" + , "\t$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'" , "" , "LIBRARIES = $(wildcard ./lib/*)" , "install_lib:" @@ -302,7 +310,7 @@ bindistMakefile = unlines , "\t\tcp -R $$i \"$(docdir)/\"; \\" , "\tdone" , "" - , "BINARY_NAMES=$(shell ls ./bin/)" + , "BINARY_NAMES=$(shell ls ./wrappers/)" , "install_wrappers:" , "\t@echo \"Installing Wrapper scripts\"" , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\"" @@ -318,7 +326,7 @@ bindistMakefile = unlines , "\t\t$(call patchpackageconf," ++ "$(shell echo $(notdir $p) | sed 's/-\\([0-9]*[0-9]\\.\\)*conf//g')," ++ "$p,$(docdir)))" - , "\t$(WrapperBinsDir)/ghc-pkg recache" + , "\t'$(WrapperBinsDir)/ghc-pkg' recache" , "" , "# END INSTALL" , "# ----------------------------------------------------------------------" diff --git a/hadrian/src/Rules/Program.hs b/hadrian/src/Rules/Program.hs index d7bcb48712..c7fbf4ed20 100644 --- a/hadrian/src/Rules/Program.hs +++ b/hadrian/src/Rules/Program.hs @@ -34,8 +34,7 @@ getProgramContexts stage = do sPackages <- filter isProgram <$> stagePackages stage tPackages <- testsuitePackages -- TODO: Shall we use Stage2 for testsuite packages instead? - let allPackages = sPackages - ++ if stage == Stage1 then tPackages else [] + let allPackages = sPackages ++ tPackages fmap concat . forM allPackages $ \pkg -> do -- the iserv pkg results in three different programs at -- the moment, ghc-iserv (built the vanilla way), diff --git a/hadrian/src/Rules/Test.hs b/hadrian/src/Rules/Test.hs index 461a95f93a..f7d8d5edc9 100644 --- a/hadrian/src/Rules/Test.hs +++ b/hadrian/src/Rules/Test.hs @@ -3,8 +3,10 @@ module Rules.Test (testRules) where import System.Environment import Base +import CommandLine import Expression import Oracles.Setting +import Oracles.TestSettings import Packages import Settings import Settings.Default @@ -28,67 +30,66 @@ testRules = do -- Using program shipped with testsuite to generate ghcconfig file. root -/- ghcConfigProgPath ~> do - ghc <- builderPath $ Ghc CompileHs Stage0 + ghc0Path <- getCompilerPath "stage0" createDirectory $ takeDirectory (root -/- ghcConfigProgPath) - cmd ghc [ghcConfigHsPath, "-o" , root -/- ghcConfigProgPath] + cmd ghc0Path [ghcConfigHsPath, "-o" , root -/- ghcConfigProgPath] -- TODO : Use input test compiler and not just stage2 compiler. root -/- ghcConfigPath ~> do - ghcPath <- needFile Stage1 ghc + args <- userSetting defaultTestArgs + let testGhc = testCompiler args + ghcPath <- getCompilerPath testGhc + when (testGhc `elem` ["stage1", "stage2"]) $ need [ ghcPath ] need [root -/- ghcConfigProgPath] cmd [FileStdout $ root -/- ghcConfigPath] (root -/- ghcConfigProgPath) [ghcPath] root -/- timeoutPath ~> timeoutProgBuilder - "validate" ~> do - needTestBuilders - build $ target (vanillaContext Stage2 compiler) (Make "testsuite/tests") [] [] - "test" ~> do - needTestBuilders + -- needTestBuilders -- TODO : Should we remove the previosly generated config file? -- Prepare Ghc configuration file for input compiler. need [root -/- ghcConfigPath, root -/- timeoutPath] + args <- userSetting defaultTestArgs + ghcPath <- getCompilerPath (testCompiler args) + -- TODO This approach doesn't work. -- Set environment variables for test's Makefile. env <- sequence [ builderEnvironment "MAKE" $ Make "" - , builderEnvironment "TEST_HC" $ Ghc CompileHs Stage2 + , pure (AddEnv "TEST_HC" ghcPath) , AddEnv "TEST_HC_OPTS" <$> runTestGhcFlags ] makePath <- builderPath $ Make "" top <- topDirectory - ghcPath <- (top -/-) <$> builderPath (Ghc CompileHs Stage2) ghcFlags <- runTestGhcFlags - checkPprPath <- (top -/-) <$> needFile Stage1 checkPpr - annotationsPath <- (top -/-) <$> needFile Stage1 checkApiAnnotations + + -- where to get those from? + checkPprPath <- needFile Stage0 checkPpr + annotationsPath <- needFile Stage0 checkApiAnnotations + pythonPath <- builderPath Python + need [ checkPprPath, annotationsPath ] -- Set environment variables for test's Makefile. liftIO $ do setEnv "MAKE" makePath + setEnv "PYTHON" pythonPath setEnv "TEST_HC" ghcPath setEnv "TEST_HC_OPTS" ghcFlags - setEnv "CHECK_PPR" checkPprPath - setEnv "CHECK_API_ANNOTATIONS" annotationsPath + setEnv "CHECK_PPR" (top </> checkPprPath) + setEnv "CHECK_API_ANNOTATIONS" (top </> annotationsPath) -- Execute the test target. -- We override the verbosity setting to make sure the user can see -- the test output: https://ghc.haskell.org/trac/ghc/ticket/15951. withVerbosity Loud $ buildWithCmdOptions env $ + -- is it really the right target, especially with an + -- external ghc? target (vanillaContext Stage2 compiler) RunTest [] [] --- | Build extra programs and libraries required by testsuite -needTestsuitePackages :: Action () -needTestsuitePackages = do - targets <- mapM (needFile Stage1) =<< testsuitePackages - -- iserv is not supported under Windows - windows <- windowsHost - when (not windows) needIservBins - need targets - -- | Build the timeout program. -- See: https://github.com/ghc/ghc/blob/master/testsuite/timeout/Makefile#L23 timeoutProgBuilder :: Action () @@ -108,11 +109,36 @@ timeoutProgBuilder = do writeFile' (root -/- timeoutPath) script makeExecutable (root -/- timeoutPath) +needTestBuilders :: Action () +needTestBuilders = do + testGhc <- testCompiler <$> userSetting defaultTestArgs + ghcPath <- getCompilerPath testGhc + bindir <- getBinaryDirectory testGhc + when (testGhc `elem` ["stage1", "stage2"]) needTestsuitePackages + +-- | Build extra programs and libraries required by testsuite +needTestsuitePackages :: Action () +needTestsuitePackages = do + testGhc <- testCompiler <$> userSetting defaultTestArgs + when (testGhc `elem` ["stage1", "stage2"]) $ do + let stg = stageOf testGhc + targets <- mapM (needFile stg) =<< testsuitePackages + -- iserv is not supported under Windows + windows <- windowsHost + when (not windows) needIservBins + need targets + + where stageOf "stage1" = Stage1 + stageOf "stage2" = Stage2 + stageOf _ = error "unexpected argument" + needIservBins :: Action () needIservBins = do - rtsways <- interpretInContext (vanillaContext Stage1 ghc) getRtsWays + testGhc <- testCompiler <$> userSetting defaultTestArgs + let stg = if testGhc == "stage1" then Stage0 else Stage1 + rtsways <- interpretInContext (vanillaContext stg ghc) getRtsWays need =<< traverse programPath - [ Context Stage1 iserv w + [ Context stg iserv w | w <- [vanilla, profiling -- TODO dynamic way has been reverted as the dynamic build -- is broken. See #15837. @@ -121,14 +147,6 @@ needIservBins = do , w `elem` rtsways ] -needTestBuilders :: Action () -needTestBuilders = do - needBuilder $ Ghc CompileHs Stage2 - needBuilder $ GhcPkg Update Stage1 - needBuilder Hpc - needBuilder $ Hsc2Hs Stage1 - needTestsuitePackages - needFile :: Stage -> Package -> Action FilePath needFile stage pkg -- TODO (Alp): we might sometimes need more than vanilla! diff --git a/hadrian/src/Settings/Builders/Make.hs b/hadrian/src/Settings/Builders/Make.hs index 0433888279..dda42f10c0 100644 --- a/hadrian/src/Settings/Builders/Make.hs +++ b/hadrian/src/Settings/Builders/Make.hs @@ -3,7 +3,7 @@ module Settings.Builders.Make (makeBuilderArgs, validateBuilderArgs) where import Oracles.Setting import Packages import Rules.Gmp -import Settings.Builders.Common +import Settings.Builders.Common hiding (Normal) import CommandLine makeBuilderArgs :: Args @@ -37,6 +37,6 @@ validateBuilderArgs = builder (Make "testsuite/tests") ? do -- | Support for speed of validation setTestSpeed :: TestSpeed -> String -setTestSpeed Fast = "fasttest" -setTestSpeed Average = "test" -setTestSpeed Slow = "slowtest" +setTestSpeed Fast = "fasttest" +setTestSpeed Normal = "test" +setTestSpeed Slow = "slowtest" diff --git a/hadrian/src/Settings/Builders/RunTest.hs b/hadrian/src/Settings/Builders/RunTest.hs index 55a5e5871a..05b6555170 100644 --- a/hadrian/src/Settings/Builders/RunTest.hs +++ b/hadrian/src/Settings/Builders/RunTest.hs @@ -1,14 +1,13 @@ module Settings.Builders.RunTest (runTestBuilderArgs, runTestGhcFlags) where -import Hadrian.Utilities +import Hadrian.Utilities hiding (Normal) import System.Environment import CommandLine import Flavour -import Oracles.Setting (setting) import Oracles.TestSettings import Packages -import Settings.Builders.Common +import Settings.Builders.Common hiding (Normal) getTestSetting :: TestSetting -> Expr String getTestSetting key = expr $ testSetting key @@ -58,18 +57,19 @@ runTestBuilderArgs = builder RunTest ? do [ [ pkgPath pkg -/- "tests", pkgPath pkg -/- "tests-ghc" ] | pkg <- pkgs, isLibrary pkg, pkg /= rts, pkg /= libffi ] + testGhc <- expr (testCompiler <$> userSetting defaultTestArgs) flav <- expr flavour rtsWays <- expr testRTSSettings - libWays <- libraryWays flav + libWays <- expr (inferLibraryWays testGhc) let hasRtsWay w = elem w rtsWays hasLibWay w = elem w libWays - debugged = ghcDebugged flav hasDynamic <- getBooleanSetting TestGhcDynamic hasDynamicByDefault <- getBooleanSetting TestGhcDynamicByDefault withNativeCodeGen <- getBooleanSetting TestGhcWithNativeCodeGen withInterpreter <- getBooleanSetting TestGhcWithInterpreter unregisterised <- getBooleanSetting TestGhcUnregisterised withSMP <- getBooleanSetting TestGhcWithSMP + debugged <- read <$> getTestSetting TestGhcDebugged windows <- expr windowsHost darwin <- expr osxHost @@ -93,8 +93,9 @@ runTestBuilderArgs = builder RunTest ? do , pure ["--rootdir=" ++ test | test <- libTests] , arg "-e", arg $ "windows=" ++ show windows , arg "-e", arg $ "darwin=" ++ show darwin - , arg "-e", arg $ "config.local=True" - , arg "-e", arg $ "config.cleanup=False" -- Don't clean up. + , arg "-e", arg $ "config.local=" ++ + show (elem testGhc ["stage1", "stage2"]) + , arg "-e", arg $ "config.cleanup=False" -- Don't clean up for now. , arg "-e", arg $ "config.compiler_debugged=" ++ quote (yesNo debugged) , arg "-e", arg $ "ghc_debugged=" ++ quote (yesNo debugged) , arg "-e", arg $ asZeroOne "ghc_with_native_codegen=" withNativeCodeGen @@ -115,9 +116,6 @@ runTestBuilderArgs = builder RunTest ? do , arg "-e", arg $ "config.ghc_dynamic=" ++ show hasDynamic , arg "-e", arg $ "config.ghc_built_by_llvm=" ++ show ghcBuiltByLlvm - -- Use default value, see: - -- https://github.com/ghc/ghc/blob/master/testsuite/mk/boilerplate.mk - , arg "-e", arg $ "config.in_tree_compiler=True" , arg "-e", arg $ "config.top=" ++ show (top -/- "testsuite") , arg "-e", arg $ "config.wordsize=" ++ show wordsize , arg "-e", arg $ "config.os=" ++ show os @@ -136,8 +134,8 @@ getTestArgs = do -- targets specified in the TEST env var testEnvTargets <- maybe [] words <$> expr (liftIO $ lookupEnv "TEST") args <- expr $ userSetting defaultTestArgs - bindir <- expr $ setBinaryDirectory (testCompiler args) - compiler <- expr $ setCompiler (testCompiler args) + bindir <- expr $ getBinaryDirectory (testCompiler args) + compiler <- expr $ getCompilerPath (testCompiler args) globalVerbosity <- shakeVerbosity <$> expr getShakeOptions let configFileArg= ["--config-file=" ++ (testConfigFile args)] testOnlyArg = map ("--only=" ++) (testOnly args ++ testEnvTargets) @@ -149,10 +147,10 @@ getTestArgs = do else Nothing speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)] summaryArg = case testSummary args of - Just filepath -> Just $ "--summary-file" ++ quote filepath + Just filepath -> Just $ "--summary-file \"" ++ filepath ++ "\"" Nothing -> Just $ "--summary-file=testsuite_summary.txt" junitArg = case testJUnit args of - Just filepath -> Just $ "--junit " ++ quote filepath + Just filepath -> Just $ "--junit=" ++ filepath Nothing -> Nothing configArgs = concat [["-e", configArg] | configArg <- testConfigs args] verbosityArg = case testVerbosity args of @@ -164,46 +162,35 @@ getTestArgs = do haddockArg = ["--config", "haddock=" ++ show (bindir -/- "haddock")] hp2psArg = ["--config", "hp2ps=" ++ show (bindir -/- "hp2ps")] hpcArg = ["--config", "hpc=" ++ show (bindir -/- "hpc")] + inTreeArg = [ "-e", "config.in_tree_compiler=" + ++ show (testCompiler args `elem` ["stage1", "stage2"]) ] + pure $ configFileArg ++ testOnlyArg ++ speedArg ++ catMaybes [ onlyPerfArg, skipPerfArg, summaryArg , junitArg, verbosityArg ] ++ configArgs ++ wayArgs ++ compilerArg ++ ghcPkgArg - ++ haddockArg ++ hp2psArg ++ hpcArg - --- TODO: Switch to 'Stage' as the first argument instead of 'String'. --- | Directory to look for Binaries --- | We assume that required programs are present in the same binary directory --- | in which ghc is stored and that they have their conventional name. --- | QUESTION : packages can be named different from their conventional names. --- | For example, ghc-pkg can be named as ghc-pkg-version. In such cases, it will --- | be impossible to search the binary. Only possible way will be to take user --- | inputs for these directory also. boilerplate soes not account for this --- | problem, but simply returns an error. How should we handle such cases? -setBinaryDirectory :: String -> Action FilePath -setBinaryDirectory "stage0" = takeDirectory <$> setting SystemGhc -setBinaryDirectory "stage1" = liftM2 (-/-) topDirectory (stageBinPath Stage0) -setBinaryDirectory "stage2" = liftM2 (-/-) topDirectory (stageBinPath Stage1) -setBinaryDirectory compiler = pure $ parentPath compiler - --- TODO: Switch to 'Stage' as the first argument instead of 'String'. --- | Set Test Compiler. -setCompiler :: String -> Action FilePath -setCompiler "stage0" = setting SystemGhc -setCompiler "stage1" = liftM2 (-/-) topDirectory (fullPath Stage0 ghc) -setCompiler "stage2" = liftM2 (-/-) topDirectory (fullPath Stage1 ghc) -setCompiler compiler = pure compiler + ++ haddockArg ++ hp2psArg ++ hpcArg ++ inTreeArg -- | Set speed for test setTestSpeed :: TestSpeed -> String -setTestSpeed Slow = "0" -setTestSpeed Average = "1" -setTestSpeed Fast = "2" - --- | Returns parent path of test compiler --- | TODO: Is there a simpler way to find parent directory? -parentPath :: String -> String -parentPath path = intercalate "/" $ init $ splitOn "/" path - --- | TODO: Move to Hadrian utilities. -fullPath :: Stage -> Package -> Action FilePath -fullPath stage pkg = programPath =<< programContext stage pkg +setTestSpeed Slow = "0" +setTestSpeed Normal = "1" +setTestSpeed Fast = "2" + +inferLibraryWays :: String -> Action [Way] +inferLibraryWays compiler = do + bindir <- getBinaryDirectory compiler + Stdout ghcPrimLibdir <- cmd [Cwd bindir] + ("ghc-pkg") + ["field", "ghc-prim", "library-dirs", "--simple-output"] + catMaybes <$> traverse (lookForWay ghcPrimLibdir) candidateWays + + where lookForWay dir (hifile, w) = do + exists <- doesFileExist (dir -/- hifile) + if exists then return (Just w) else return Nothing + + candidateWays = + [ ("GHC/PrimopWrappers.hi", vanilla) + , ("GHC/PrimopWrappers.dyn_hi", dynamic) + , ("GHC/PrimopWrappers.p_hi", profiling) + ] diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs index e2d7644beb..ca4b0d16e1 100644 --- a/hadrian/src/Settings/Default.hs +++ b/hadrian/src/Settings/Default.hs @@ -58,6 +58,8 @@ stage0Packages = do cross <- flag CrossCompiling return $ [ binary , cabal + , checkApiAnnotations + , checkPpr , compareSizes , compiler , deriveConstants @@ -100,6 +102,7 @@ stage1Packages = do , ghcPkg , ghcPrim , haskeline + , hp2ps , hsc2hs , intLib , pretty @@ -25,6 +25,7 @@ Flags: 2008-07-01: 14% slower than the default. --quiet More pretty build log. See Note [Default build system verbosity]. + --hadrian Build the compiler and run the tests through hadrian. --help shows this usage help. validate runs 'make -j\$THREADS', where by default THREADS is the number of @@ -54,6 +55,7 @@ be_quiet=0 # heavy cost of xz, which is the typical default. The options are defined in # mk/config.mk.in tar_comp=gzip +use_hadrian=NO while [ $# -gt 0 ] do @@ -82,6 +84,10 @@ do --quiet) be_quiet=1 ;; + --hadrian) + use_hadrian=YES + hadrian_build_root=_validatebuild + ;; --help) show_help exit 0;; @@ -96,7 +102,12 @@ done check_packages () { if [ "$bindistdir" = "" ] then - ghc_pkg=inplace/bin/ghc-pkg + if [ "$use_hadrian" = "YES" ] + then + ghc_pkg=$hadrian_build_root/stage1/bin/ghc-pkg + else + ghc_pkg=inplace/bin/ghc-pkg + fi else ghc_pkg="$bindistdir"/bin/ghc-pkg fi @@ -127,26 +138,37 @@ fi echo "using THREADS=${threads}" >&2 -if type gmake > /dev/null 2> /dev/null +if [ "$use_hadrian" = "NO" ] then - make="gmake" + if type gmake > /dev/null 2> /dev/null + then + make="gmake" + else + make="make" + fi + if [ $be_quiet -eq 1 ]; then + # See Note [Default build system verbosity]. + make="$make -s" + fi + $make -C utils/checkUniques else - make="make" -fi - -if [ $be_quiet -eq 1 ]; then - # See Note [Default build system verbosity]. - make="$make -s" + hadrian="hadrian/build.sh -j$threads --build-root=$hadrian_build_root" + if [ $be_quiet -eq 0 ]; then + hadrian="$hadrian -V" + fi fi -$make -C utils/checkUniques - if [ $testsuite_only -eq 0 ]; then thisdir=`pwd` if [ $no_clean -eq 0 ]; then - $make maintainer-clean + if [ "$use_hadrian" = "NO" ] + then + $make maintainer-clean + else + $hadrian clean && rm -rf $hadrian_build_root + fi INSTDIR="$thisdir/inst" @@ -154,27 +176,32 @@ if [ $no_clean -eq 0 ]; then ./configure --prefix="$INSTDIR" $config_args fi -echo "Validating=YES" > mk/are-validating.mk -echo "ValidateSpeed=$speed" >> mk/are-validating.mk -echo "ValidateHpc=$hpc" >> mk/are-validating.mk - -# Note [Default build system verbosity]. -# -# From https://ghc.haskell.org/trac/ghc/wiki/Design/BuildSystem: -# -# "The build system should clearly report what it's doing (and sometimes -# why), without being too verbose. It should emit actual command lines as -# much as possible, so that they can be inspected and cut & pasted." -# -# That should be the default. Only suppress commands, by setting V=0 and using -# `make -s`, when user explicitly asks for it with `./validate --quiet`. -if [ $be_quiet -eq 1 ]; then - # See Note [Default build system verbosity]. - echo "V=0" >> mk/are-validating.mk # Less gunk -fi +if [ "$use_hadrian" = "NO" ] +then + echo "Validating=YES" > mk/are-validating.mk + echo "ValidateSpeed=$speed" >> mk/are-validating.mk + echo "ValidateHpc=$hpc" >> mk/are-validating.mk -$make -j$threads -# For a "debug make", add "--debug=b --debug=m" + # Note [Default build system verbosity]. + # + # From https://ghc.haskell.org/trac/ghc/wiki/Design/BuildSystem: + # + # "The build system should clearly report what it's doing (and sometimes + # why), without being too verbose. It should emit actual command lines as + # much as possible, so that they can be inspected and cut & pasted." + # + # That should be the default. Only suppress commands, by setting V=0 and using + # `make -s`, when user explicitly asks for it with `./validate --quiet`. + if [ $be_quiet -eq 1 ]; then + # See Note [Default build system verbosity]. + echo "V=0" >> mk/are-validating.mk # Less gunk + fi + + $make -j$threads + # For a "debug make", add "--debug=b --debug=m" +else + $hadrian +fi check_packages post-build @@ -183,19 +210,47 @@ check_packages post-build if [ $speed != "FAST" ]; then - $make binary-dist-prep TAR_COMP=$tar_comp - $make test_bindist TEST_PREP=YES TAR_COMP=$tar_comp + bindistdir="bindisttest/install dir" + + if [ "$use_hadrian" = "NO" ] + then + $make binary-dist-prep TAR_COMP=$tar_comp + $make test_bindist TEST_PREP=YES TAR_COMP=$tar_comp + else + # $hadrian binary-dist + # cd $hadrian_build_root/bindist/ + # dir=$(ls | grep -v tar) + # cd $dir + # ./configure --prefix="$thisdir/$bindistdir" && make install + # cd $thisdir + ghc="$bindistdir/bin/ghc" + "$ghc" -e '1+1' + fi + + check_packages post-install # # Install the xhtml package into the bindist. # This verifies that we can install a package into the # bindist with Cabal. # - bindistdir="bindisttest/install dir" - - check_packages post-install - - $make validate_build_xhtml BINDIST_PREFIX="$thisdir/$bindistdir" + if [ "$use_hadrian" = "NO" ] + then + $make validate_build_xhtml BINDIST_PREFIX="$thisdir/$bindistdir" + else + cd libraries/xhtml + "$thisdir/$bindistdir/bin/ghc" --make Setup + # TODO: Add --with-haddock=... + ./Setup configure --with-ghc="$thisdir/$bindistdir/bin/ghc" \ + --global --builddir=dist-bindist \ + --prefix="$thisdir/$bindistdir" + ./Setup build --builddir=dist-bindist + # TODO: ./Setup haddock + ./Setup install --builddir=dist-bindist + ./Setup clean --builddir=dist-bindist + rm -f Setup Setup.exe Setup.hi Setup.o + cd ../../ + fi check_packages post-xhtml fi @@ -226,15 +281,18 @@ then fi case "$speed" in -SLOW) + SLOW) + HADRIAN_TEST_SPEED=slow MAKE_TEST_TARGET=slowtest BINDIST="BINDIST=YES" ;; -NORMAL) + NORMAL) + HADRIAN_TEST_SPEED=normal MAKE_TEST_TARGET=test BINDIST="BINDIST=YES" ;; -FAST) + FAST) + HADRIAN_TEST_SPEED=fast MAKE_TEST_TARGET=fasttest BINDIST="BINDIST=NO" ;; @@ -252,21 +310,31 @@ fi rm -f testsuite_summary.txt testsuite_summary_stage1.txt -# Use LOCAL=0, see Note [Running tests in /tmp]. -$make -C testsuite/tests $BINDIST $PYTHON_ARG \ - $MAKE_TEST_TARGET stage=2 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \ - NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../testsuite_summary.txt \ - JUNIT_FILE=../../testsuite.xml \ - 2>&1 | tee testlog - -# Run a few tests using the stage1 compiler. -# See Note [Why is there no stage1 setup function?]. -# Don't use BINDIST=YES, as stage1 is not available in a bindist. -$make -C testsuite/tests/stage1 $PYTHON_ARG \ - $MAKE_TEST_TARGET stage=1 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \ - NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../../testsuite_summary_stage1.txt \ - JUNIT_FILE=../../../testsuite_stage1.xml \ - 2>&1 | tee testlog-stage1 +if [ "$use_hadrian" = "NO" ] +then + # Use LOCAL=0, see Note [Running tests in /tmp]. + $make -C testsuite/tests $BINDIST $PYTHON_ARG \ + $MAKE_TEST_TARGET stage=2 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \ + NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../testsuite_summary.txt \ + JUNIT_FILE=../../testsuite.xml \ + 2>&1 | tee testlog + + # Run a few tests using the stage1 compiler. + # See Note [Why is there no stage1 setup function?]. + # Don't use BINDIST=YES, as stage1 is not available in a bindist. + $make -C testsuite/tests/stage1 $PYTHON_ARG \ + $MAKE_TEST_TARGET stage=1 LOCAL=0 $TEST_VERBOSITY THREADS=$threads \ + NO_PRINT_SUMMARY=YES SUMMARY_FILE=../../../testsuite_summary_stage1.txt \ + JUNIT_FILE=../../../testsuite_stage1.xml \ + 2>&1 | tee testlog-stage1 +else + # TODO: run stage 1 tests too + echo "Stage 1 tests not supported by hadrian" > testsuite_summary_stage1.txt + $hadrian test --test-speed=$HADRIAN_TEST_SPEED \ + --test-compiler="$thisdir/$bindistdir/bin/ghc" \ + --summary=$thisdir/testsuite_summary.txt \ + --summary-junit=$thisdir/testsuite.xml +fi echo echo '==== STAGE 1 TESTS ==== ' |
