summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-01-31 19:08:01 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2022-02-04 09:38:47 +0000
commitf76886edbc9b0b8feeeed95e25cb20b9035f8eaf (patch)
tree9e0fea48143276c2903c3567709f7ad6c9f9eb29
parente59446c6a682587c21424e5830f305ab2f8f8cfa (diff)
downloadhaskell-wip/testsuite-linters.tar.gz
testsuite: Run testsuite dependency calculation before GHC is builtwip/testsuite-linters
The main motivation for this patch is to allow tests to be added to the testsuite which test things about the source tree without needing to build GHC. In particular the notes linter can easily start failing and by integrating it into the testsuite the process of observing these changes is caught by normal validation procedures rather than having to run the linter specially. With this patch I can run ``` ./hadrian/build test --flavour=devel2 --only="uniques" ``` In a clean tree to run the checkUniques linter without having to build GHC. Fixes #21029
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--hadrian/src/Oracles/Setting.hs4
-rw-r--r--hadrian/src/Oracles/TestSettings.hs20
-rw-r--r--hadrian/src/Rules/Test.hs45
-rw-r--r--hadrian/src/Settings/Builders/RunTest.hs147
-rw-r--r--testsuite/config/ghc27
-rw-r--r--testsuite/driver/runtests.py16
-rw-r--r--testsuite/driver/testlib.py6
-rw-r--r--testsuite/mk/ghc-config.hs5
-rw-r--r--testsuite/mk/test.mk8
-rw-r--r--testsuite/tests/linters/Makefile4
-rw-r--r--testsuite/tests/linters/all.T1
-rwxr-xr-xtestsuite/tests/linters/checkUniques/check-uniques.py (renamed from utils/checkUniques/check-uniques.py)0
-rw-r--r--utils/checkUniques/Makefile8
14 files changed, 212 insertions, 81 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0cd7e2673f..8a30cac651 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -186,7 +186,7 @@ ghc-linters:
- .gitlab/linters/check-makefiles.py commits $base $CI_COMMIT_SHA
- .gitlab/linters/check-cpp.py commits $base $CI_COMMIT_SHA
- .gitlab/linters/check-version-number.sh
- - python3 utils/checkUniques/check-uniques.py .
+ - python3 testsuite/tests/linters/checkUniques/check-uniques.py .
dependencies: []
rules:
- if: $CI_MERGE_REQUEST_ID
diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs
index d006439646..0931c6f99f 100644
--- a/hadrian/src/Oracles/Setting.hs
+++ b/hadrian/src/Oracles/Setting.hs
@@ -77,6 +77,8 @@ data Setting = BuildArch
| TargetArchHaskell
| TargetOsHaskell
| TargetArmVersion
+ | TargetWordSize
+ | TargetHasRtsLinker
| BourneShell
-- TODO: Reduce the variety of similar flags (e.g. CPP and non-CPP versions).
@@ -176,6 +178,8 @@ setting key = lookupValueOrError configFile $ case key of
TargetVendor -> "target-vendor"
TargetArchHaskell -> "target-arch-haskell"
TargetOsHaskell -> "target-os-haskell"
+ TargetWordSize -> "target-word-size"
+ TargetHasRtsLinker -> "target-has-rts-linker"
BourneShell -> "bourne-shell"
-- | Look up the value of a 'SettingList' in @cfg/system.config@, tracking the
diff --git a/hadrian/src/Oracles/TestSettings.hs b/hadrian/src/Oracles/TestSettings.hs
index d59819187f..7541ab628f 100644
--- a/hadrian/src/Oracles/TestSettings.hs
+++ b/hadrian/src/Oracles/TestSettings.hs
@@ -5,6 +5,7 @@
module Oracles.TestSettings
( TestSetting (..), testSetting, testRTSSettings
, getCompilerPath, getBinaryDirectory, isInTreeCompiler
+ , stageOfTestCompiler
) where
import Base
@@ -28,6 +29,7 @@ data TestSetting = TestHostOS
| TestGhcDebugged
| TestGhcWithNativeCodeGen
| TestGhcWithInterpreter
+ | TestGhcWithRtsLinker
| TestGhcUnregisterised
| TestGhcWithSMP
| TestGhcDynamic
@@ -40,6 +42,9 @@ data TestSetting = TestHostOS
| TestGhcPackageDbFlag
| TestMinGhcVersion711
| TestMinGhcVersion801
+ | TestLeadingUnderscore
+ | TestGhcPackageDb
+ | TestGhcLibDir
deriving (Show)
-- | Lookup a test setting in @ghcconfig@ file.
@@ -57,6 +62,7 @@ testSetting key = do
TestGhcDebugged -> "GhcDebugged"
TestGhcWithNativeCodeGen -> "GhcWithNativeCodeGen"
TestGhcWithInterpreter -> "GhcWithInterpreter"
+ TestGhcWithRtsLinker -> "GhcWithRtsLinker"
TestGhcUnregisterised -> "GhcUnregisterised"
TestGhcWithSMP -> "GhcWithSMP"
TestGhcDynamic -> "GhcDynamic"
@@ -69,6 +75,9 @@ testSetting key = do
TestGhcPackageDbFlag -> "GhcPackageDbFlag"
TestMinGhcVersion711 -> "MinGhcVersion711"
TestMinGhcVersion801 -> "MinGhcVersion801"
+ TestLeadingUnderscore -> "LeadingUnderscore"
+ TestGhcPackageDb -> "GhcGlobalPackageDb"
+ TestGhcLibDir -> "GhcLibdir"
-- | Get the RTS ways of the test compiler
testRTSSettings :: Action [String]
@@ -92,7 +101,7 @@ getBinaryDirectory compiler = pure $ takeDirectory compiler
-- | Get the path to the given @--test-compiler@.
getCompilerPath :: String -> Action FilePath
getCompilerPath "stage0" = setting SystemGhc
-getCompilerPath "stage1" = liftM2 (-/-) absoluteBuildRoot (pure "stage1-test/bin/ghc")
+getCompilerPath "stage1" = liftM2 (-/-) absoluteBuildRoot (pure ("stage1-test/bin/ghc" <.> exe))
getCompilerPath "stage2" = liftM2 (-/-) topDirectory (fullPath Stage1 ghc)
getCompilerPath "stage3" = liftM2 (-/-) topDirectory (fullPath Stage2 ghc)
getCompilerPath compiler = pure compiler
@@ -103,3 +112,12 @@ isInTreeCompiler c = c `elem` ["stage1","stage2","stage3"]
-- | Get the full path to the given program.
fullPath :: Stage -> Package -> Action FilePath
fullPath stage pkg = programPath =<< programContext stage pkg
+
+-- stage 1 ghc lives under stage0/bin,
+-- stage 2 ghc lives under stage1/bin, etc
+stageOfTestCompiler :: String -> Maybe Stage
+stageOfTestCompiler "stage1" = Just Stage0
+stageOfTestCompiler "stage2" = Just Stage1
+stageOfTestCompiler "stage3" = Just Stage2
+stageOfTestCompiler _ = Nothing
+
diff --git a/hadrian/src/Rules/Test.hs b/hadrian/src/Rules/Test.hs
index 5115b4d462..27e3cc9176 100644
--- a/hadrian/src/Rules/Test.hs
+++ b/hadrian/src/Rules/Test.hs
@@ -50,6 +50,15 @@ checkPrograms =
, ("test:count-deps",countDepsProgPath, countDepsSourcePath, countDepsExtra, countDeps)
]
+testsuiteDeps :: Rules ()
+testsuiteDeps =
+ "test:ghc" ~> do
+ args <- userSetting defaultTestArgs
+ let testCompilerArg = testCompiler args
+ case stageOf testCompilerArg of
+ Just stg -> needTestsuitePackages stg
+ Nothing -> return ()
+
ghcConfigPath :: FilePath
ghcConfigPath = "test/ghcconfig"
@@ -58,6 +67,8 @@ testRules :: Rules ()
testRules = do
root <- buildRootRules
+ testsuiteDeps
+
-- Using program shipped with testsuite to generate ghcconfig file.
root -/- ghcConfigProgPath %> \_ -> do
ghc0Path <- getCompilerPath "stage0"
@@ -135,15 +146,22 @@ testRules = do
root -/- timeoutPath %> \_ -> timeoutProgBuilder
"test" ~> do
- needTestBuilders
-
- -- TODO : Should we remove the previously generated config file?
- -- Prepare Ghc configuration file for input compiler.
- need [root -/- ghcConfigPath, root -/- timeoutPath]
args <- userSetting defaultTestArgs
-
let testCompilerArg = testCompiler args
+ let stg = fromMaybe Stage2 $ stageOf testCompilerArg
+ let test_target tt = target (vanillaContext stg compiler) (Testsuite tt) [] []
+
+ -- We need to ask the testsuite if it needs any extra hadrian dependencies for the
+ -- tests it is going to run,
+ -- for example "docs_haddock"
+ -- We then need to go and build these dependencies
+ extra_targets <- words <$> askWithResources [] (test_target GetExtraDeps)
+ need $ filter (isOkToBuild args) extra_targets
+
+ -- Prepare Ghc configuration file for input compiler.
+ need [root -/- timeoutPath]
+
ghcPath <- getCompilerPath testCompilerArg
@@ -184,15 +202,6 @@ testRules = do
-- which is in turn included by all test 'Makefile's.
setEnv "ghc_config_mk" (top -/- root -/- ghcConfigPath)
- let stg = fromMaybe Stage2 $ stageOf testCompilerArg
- let test_target tt = target (vanillaContext stg compiler) (Testsuite tt) [] []
-
- -- We need to ask the testsuite if it needs any extra hadrian dependencies for the
- -- tests it is going to run,
- -- for example "docs_haddock"
- -- We then need to go and build these dependencies
- extra_targets <- words <$> askWithResources [] (test_target GetExtraDeps)
- need $ filter (isOkToBuild args) extra_targets
-- Execute the test target.
-- We override the verbosity setting to make sure the user can see
@@ -234,12 +243,6 @@ timeoutProgBuilder = do
writeFile' (root -/- timeoutPath) script
makeExecutable (root -/- timeoutPath)
-needTestBuilders :: Action ()
-needTestBuilders = do
- testGhc <- testCompiler <$> userSetting defaultTestArgs
- whenJust (stageOf testGhc)
- needTestsuitePackages
-
-- | Build extra programs and libraries required by testsuite
needTestsuitePackages :: Stage -> Action ()
needTestsuitePackages stg = do
diff --git a/hadrian/src/Settings/Builders/RunTest.hs b/hadrian/src/Settings/Builders/RunTest.hs
index 168e64e217..86bd6c7b6f 100644
--- a/hadrian/src/Settings/Builders/RunTest.hs
+++ b/hadrian/src/Settings/Builders/RunTest.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE TypeApplications #-}
module Settings.Builders.RunTest (runTestBuilderArgs, runTestGhcFlags) where
import Hadrian.Utilities
@@ -10,6 +11,7 @@ import Settings.Builders.Common
import qualified Data.Set as Set
import Flavour
import qualified Context.Type as C
+import System.Directory (findExecutable)
getTestSetting :: TestSetting -> Expr String
getTestSetting key = expr $ testSetting key
@@ -51,6 +53,106 @@ runTestGhcFlags = do
, pure "-dno-debug-output"
]
+
+data TestCompilerArgs = TestCompilerArgs{
+ hasDynamicRts, hasThreadedRts :: Bool
+ , libWays :: [Way]
+ , hasDynamic :: Bool
+ , leadingUnderscore :: Bool
+ , withNativeCodeGen :: Bool
+ , withInterpreter :: Bool
+ , unregisterised :: Bool
+ , withSMP :: Bool
+ , debugged :: Bool
+ , profiled :: Bool
+ , os,arch, platform, wordsize :: String
+ , libdir :: FilePath
+ , have_llvm :: Bool
+ , rtsLinker :: Bool
+ , pkgConfCacheFile :: FilePath }
+
+
+-- | If the tree is in-compiler then we already know how we will build it so
+-- don't build anything in order to work out what we will build.
+--
+inTreeCompilerArgs :: Stage -> Expr TestCompilerArgs
+inTreeCompilerArgs stg = expr $ do
+
+
+ (hasDynamicRts, hasThreadedRts) <- do
+ ways <- interpretInContext (Context stg rts vanilla) getRtsWays
+ return (dynamic `elem` ways, threaded `elem` ways)
+ libWays <- interpretInContext (Context stg compiler vanilla) getLibraryWays
+ -- MP: We should be able to vary if stage1/stage2 is dynamic, ie a dynamic stage1
+ -- should be able to built a static stage2?
+ hasDynamic <- flavour >>= dynamicGhcPrograms
+ -- LeadingUnderscore is a property of the system so if cross-compiling stage1/stage2 could
+ -- have different values? Currently not possible to express.
+ leadingUnderscore <- flag LeadingUnderscore
+ -- MP: This setting seems to only dictate whether we turn on optasm as a compiler
+ -- way, but a lot of tests which use only_ways(optasm) seem to not test the NCG?
+ withNativeCodeGen <- return True
+ withInterpreter <- ghcWithInterpreter
+ unregisterised <- flag GhcUnregisterised
+ withSMP <- targetSupportsSMP
+ debugged <- ghcDebugged <$> flavour
+ profiled <- ghcProfiled <$> flavour
+
+ os <- setting HostOs
+ arch <- setting TargetArch
+ platform <- setting TargetPlatform
+ wordsize <- (show @Int . (*8) . read) <$> setting TargetWordSize
+
+ llc_cmd <- settingsFileSetting SettingsFileSetting_LlcCommand
+ have_llvm <- liftIO (isJust <$> findExecutable llc_cmd)
+
+ pkgConfCacheFile <- packageDbPath stg <&> (-/- "package.cache")
+ libdir <- stageLibPath stg
+
+ rtsLinker <- (== "YES") <$> setting TargetHasRtsLinker
+
+ return TestCompilerArgs{..}
+
+ghcConfigPath :: FilePath
+ghcConfigPath = "test/ghcconfig"
+
+-- | If the compiler is out-of-tree then we have to query the compiler to work out
+-- facts about it.
+outOfTreeCompilerArgs :: String -> Expr TestCompilerArgs
+outOfTreeCompilerArgs testGhc = do
+
+ expr (do
+ root <- buildRoot
+ need [root -/- ghcConfigPath])
+ (hasDynamicRts, hasThreadedRts) <- do
+ ways <- expr testRTSSettings
+ return ("dyn" `elem` ways, "thr" `elem` ways)
+ libWays <- expr (inferLibraryWays testGhc)
+ hasDynamic <- getBooleanSetting TestGhcDynamic
+ leadingUnderscore <- getBooleanSetting TestLeadingUnderscore
+ withNativeCodeGen <- getBooleanSetting TestGhcWithNativeCodeGen
+ withInterpreter <- getBooleanSetting TestGhcWithInterpreter
+ unregisterised <- getBooleanSetting TestGhcUnregisterised
+ withSMP <- getBooleanSetting TestGhcWithSMP
+ debugged <- getBooleanSetting TestGhcDebugged
+
+
+ os <- getTestSetting TestHostOS
+ arch <- getTestSetting TestTargetARCH_CPP
+ platform <- getTestSetting TestTARGETPLATFORM
+ wordsize <- getTestSetting TestWORDSIZE
+
+ llc_cmd <- getTestSetting TestLLC
+ have_llvm <- expr (liftIO (isJust <$> findExecutable llc_cmd))
+ profiled <- getBooleanSetting TestGhcProfiled
+
+ pkgConfCacheFile <- getTestSetting TestGhcPackageDb <&> (-/- "package.cache")
+ libdir <- getTestSetting TestGhcLibDir
+
+ rtsLinker <- getBooleanSetting TestGhcWithRtsLinker
+ return TestCompilerArgs{..}
+
+
-- Command line arguments for invoking the @runtest.py@ script. A lot of this
-- mirrors @testsuite/mk/test.mk@.
runTestBuilderArgs :: Args
@@ -62,17 +164,16 @@ runTestBuilderArgs = builder Testsuite ? do
| pkg <- pkgs, isLibrary pkg, pkg /= rts, pkg /= libffi ]
testGhc <- expr (testCompiler <$> userSetting defaultTestArgs)
- rtsWays <- expr testRTSSettings
- libWays <- expr (inferLibraryWays testGhc)
- let hasRtsWay w = elem w rtsWays
- hasLibWay w = elem w libWays
- hasDynamic <- getBooleanSetting TestGhcDynamic
- leadingUnderscore <- getFlag LeadingUnderscore
- withNativeCodeGen <- getBooleanSetting TestGhcWithNativeCodeGen
- withInterpreter <- getBooleanSetting TestGhcWithInterpreter
- unregisterised <- getBooleanSetting TestGhcUnregisterised
- withSMP <- getBooleanSetting TestGhcWithSMP
- debugged <- getBooleanSetting TestGhcDebugged
+
+ TestCompilerArgs{..} <-
+ case stageOfTestCompiler testGhc of
+ Just stg -> inTreeCompilerArgs stg
+ Nothing -> outOfTreeCompilerArgs testGhc
+
+ -- MP: TODO, these should be queried from the test compiler?
+ bignumBackend <- getBignumBackend
+ bignumCheck <- getBignumCheck
+
keepFiles <- expr (testKeepFiles <$> userSetting defaultTestArgs)
accept <- expr (testAccept <$> userSetting defaultTestArgs)
@@ -84,15 +185,9 @@ runTestBuilderArgs = builder Testsuite ? do
perfBaseline <- expr . liftIO $ lookupEnv "PERF_BASELINE_COMMIT"
threads <- shakeThreads <$> expr getShakeOptions
- os <- getTestSetting TestHostOS
- arch <- getTestSetting TestTargetARCH_CPP
- platform <- getTestSetting TestTARGETPLATFORM
- wordsize <- getTestSetting TestWORDSIZE
top <- expr $ topDirectory
ghcFlags <- expr runTestGhcFlags
cmdrootdirs <- expr (testRootDirs <$> userSetting defaultTestArgs)
- bignumBackend <- getBignumBackend
- bignumCheck <- getBignumCheck
let defaultRootdirs = ("testsuite" -/- "tests") : libTests
rootdirs | null cmdrootdirs = defaultRootdirs
| otherwise = cmdrootdirs
@@ -103,6 +198,8 @@ runTestBuilderArgs = builder Testsuite ? do
let asBool :: String -> Bool -> String
asBool s b = s ++ show b
+ hasLibWay w = elem w libWays
+
-- TODO: set CABAL_MINIMAL_BUILD/CABAL_PLUGIN_BUILD
mconcat [ arg $ "testsuite/driver/runtests.py"
, pure [ "--rootdir=" ++ testdir | testdir <- rootdirs ]
@@ -117,14 +214,26 @@ runTestBuilderArgs = builder Testsuite ? do
, arg "-e", arg $ "config.exeext=" ++ quote (if null exe then "" else "."<>exe)
, arg "-e", arg $ "config.compiler_debugged=" ++
show debugged
+ -- MP: TODO, we do not need both, they get aliased to the same thing.
, arg "-e", arg $ asBool "ghc_with_native_codegen=" withNativeCodeGen
+ , arg "-e", arg $ asBool "config.have_ncg=" withNativeCodeGen
+ , arg "-e", arg $ asBool "config.have_llvm=" have_llvm
+
+ , arg "-e", arg $ asBool "config.compiler_profiled=" profiled
+
+ , arg "-e", arg $ asBool "config.have_RTS_linker=" rtsLinker
+
+ , arg "-e", arg $ "config.package_conf_cache_file=" ++ show pkgConfCacheFile
+
+ , arg "-e", arg $ "config.libdir=" ++ show libdir
+
, arg "-e", arg $ "config.have_interp=" ++ show withInterpreter
, arg "-e", arg $ "config.unregisterised=" ++ show unregisterised
, arg "-e", arg $ "ghc_compiler_always_flags=" ++ quote ghcFlags
- , arg "-e", arg $ asBool "ghc_with_dynamic_rts=" (hasRtsWay "dyn")
- , arg "-e", arg $ asBool "ghc_with_threaded_rts=" (hasRtsWay "thr")
+ , arg "-e", arg $ asBool "ghc_with_dynamic_rts=" (hasDynamicRts)
+ , arg "-e", arg $ asBool "ghc_with_threaded_rts=" (hasThreadedRts)
, arg "-e", arg $ asBool "config.have_vanilla=" (hasLibWay vanilla)
, arg "-e", arg $ asBool "config.have_dynamic=" (hasLibWay dynamic)
, arg "-e", arg $ asBool "config.have_profiling=" (hasLibWay profiling)
diff --git a/testsuite/config/ghc b/testsuite/config/ghc
index aed4c22fb0..1a73e3a547 100644
--- a/testsuite/config/ghc
+++ b/testsuite/config/ghc
@@ -183,18 +183,6 @@ llvm_ways = [x[0] for x in config.way_flags.items()
def get_compiler_info():
- s = getStdout([config.compiler, '--info'])
- s = re.sub('[\r\n]', '', s)
- compilerInfoDict = dict(eval(s))
- s = getStdout([config.compiler, '+RTS', '--info'])
- s = re.sub('[\r\n]', '', s)
- rtsInfoDict = dict(eval(s))
-
- config.have_ncg = compilerInfoDict.get("Have native code generator", "NO") == "YES"
-
- # Detect whether an LLVM toolhain is available
- llc_path = compilerInfoDict.get("LLVM llc command")
- config.have_llvm = shutil.which(llc_path) is not None
if config.unregisterised:
print("Unregisterised build; skipping LLVM ways...")
elif config.have_llvm:
@@ -212,25 +200,14 @@ def get_compiler_info():
# backend by default.
config.ghc_built_by_llvm = not config.have_ncg and not config.unregisterised
- config.have_RTS_linker = compilerInfoDict.get("target has RTS linker", "NO") == "YES"
# external interpreter needs RTS linker support
# If the field is not present (GHC 8.0 and earlier), assume we don't
# have -fexternal-interpreter (though GHC 8.0 actually does)
# so we can still run most tests.
- config.have_ext_interp = compilerInfoDict.get("target has RTS linker", "NO") == "YES"
+ config.have_ext_interp = config.have_RTS_linker
# See Note [Replacing backward slashes in config.libdir].
- config.libdir = compilerInfoDict['LibDir'].replace('\\', '/')
-
- if re.match(".*_p(_.*|$)", rtsInfoDict["RTS way"]):
- config.compiler_profiled = True
- else:
- config.compiler_profiled = False
-
- try:
- config.package_conf_cache_file = compilerInfoDict["Global Package DB"] + '/package.cache'
- except:
- config.package_conf_cache_file = ''
+ config.libdir = config.libdir.replace('\\', '/')
# See Note [WayFlags]
if config.ghc_dynamic:
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 6858715c7a..d2e25eaa19 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -275,12 +275,18 @@ def format_path(path):
# On Windows we need to set $PATH to include the paths to all the DLLs
# in order for the dynamic library tests to work.
if windows:
- pkginfo = getStdout([config.ghc_pkg, 'dump'])
+ try:
+ pkginfo = getStdout([config.ghc_pkg, 'dump'])
+ except FileNotFoundError as err:
+ # This can happen when we are only running tests which don't depend on ghc (ie linters)
+ # In that case we probably haven't built ghc-pkg yet so this query will fail.
+ print (err)
+ print ("Failed to call ghc-pkg for windows path modification... some tests might fail")
+ pkginfo = ""
topdir = config.libdir
- if windows:
- mingw = os.path.abspath(os.path.join(topdir, '../mingw/bin'))
- mingw = format_path(mingw)
- ghc_env['PATH'] = os.pathsep.join([ghc_env.get("PATH", ""), mingw])
+ mingw = os.path.abspath(os.path.join(topdir, '../mingw/bin'))
+ mingw = format_path(mingw)
+ ghc_env['PATH'] = os.pathsep.join([ghc_env.get("PATH", ""), mingw])
for line in pkginfo.split('\n'):
if line.startswith('library-dirs:'):
path = line.rstrip()
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index 423cd99313..74ba9909f1 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -125,6 +125,12 @@ def setTestOpts( f ):
# type TestOpt = (name :: String, opts :: Object) -> IO ()
def normal( name, opts ):
+ opts.hadrian_deps.update(["test:ghc"])
+ return;
+
+# A test with no hadrian built dependencies, including the test compiler
+# This is used for linters.
+def no_deps( name, opts):
return;
def skip( name, opts ):
diff --git a/testsuite/mk/ghc-config.hs b/testsuite/mk/ghc-config.hs
index e4631f13ff..a22d9b46d1 100644
--- a/testsuite/mk/ghc-config.hs
+++ b/testsuite/mk/ghc-config.hs
@@ -20,12 +20,15 @@ main = do
getGhcFieldOrFail fields "GhcDebugged" "Debug on"
getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator"
getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter"
+ getGhcFieldOrFail fields "GhcWithRtsLinker" "target has RTS linker"
getGhcFieldOrFail fields "GhcUnregisterised" "Unregisterised"
getGhcFieldOrFail fields "GhcWithSMP" "Support SMP"
getGhcFieldOrFail fields "GhcRTSWays" "RTS ways"
- getGhcFieldOrFail fields "GhcLeadingUnderscore" "Leading underscore"
+ getGhcFieldOrFail fields "GhcLibdir" "LibDir"
+ getGhcFieldOrFail fields "GhcGlobalPackageDb" "Global Package DB"
getGhcFieldOrDefault fields "GhcDynamic" "GHC Dynamic" "NO"
getGhcFieldOrDefault fields "GhcProfiled" "GHC Profiled" "NO"
+ getGhcFieldOrDefault fields "LeadingUnderscore" "Leading underscore" "NO"
getGhcFieldProgWithDefault fields "AR" "ar command" "ar"
getGhcFieldProgWithDefault fields "CLANG" "LLVM clang command" "clang"
getGhcFieldProgWithDefault fields "LLC" "LLVM llc command" "llc"
diff --git a/testsuite/mk/test.mk b/testsuite/mk/test.mk
index e01a76eb29..56c720f0fd 100644
--- a/testsuite/mk/test.mk
+++ b/testsuite/mk/test.mk
@@ -189,6 +189,14 @@ else
RUNTEST_OPTS += -e ghc_with_smp=False
endif
+ifeq "$(GhcWithRtsLinker)" "YES"
+RUNTEST_OPTS += -e config.have_RTS_linker=True
+else
+RUNTEST_OPTS += -e config.have_RTS_linker=False
+endif
+
+RUNTEST_OPTS += -e config.libdir="\"$(GhcLibdir)\""
+
ifeq "$(WINDOWS)" "YES"
RUNTEST_OPTS += -e windows=True
else
diff --git a/testsuite/tests/linters/Makefile b/testsuite/tests/linters/Makefile
new file mode 100644
index 0000000000..aeaef050e1
--- /dev/null
+++ b/testsuite/tests/linters/Makefile
@@ -0,0 +1,4 @@
+TOP=../..
+
+uniques:
+ python3 checkUniques/check-uniques.py $(TOP)/..
diff --git a/testsuite/tests/linters/all.T b/testsuite/tests/linters/all.T
new file mode 100644
index 0000000000..b4cc4bb8b3
--- /dev/null
+++ b/testsuite/tests/linters/all.T
@@ -0,0 +1 @@
+test('uniques', [no_deps, extra_files(["checkUniques"])], makefile_test, ['uniques'])
diff --git a/utils/checkUniques/check-uniques.py b/testsuite/tests/linters/checkUniques/check-uniques.py
index dd5891b0d8..dd5891b0d8 100755
--- a/utils/checkUniques/check-uniques.py
+++ b/testsuite/tests/linters/checkUniques/check-uniques.py
diff --git a/utils/checkUniques/Makefile b/utils/checkUniques/Makefile
deleted file mode 100644
index b53759c734..0000000000
--- a/utils/checkUniques/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-TOP = ../..
-
-GHC = ghc
-
-.PHONY: check
-
-check:
- ./check-uniques.py $(TOP)