diff options
author | Andrey Mokhov <andrey.mokhov@gmail.com> | 2017-11-06 22:59:38 +0000 |
---|---|---|
committer | Andrey Mokhov <andrey.mokhov@gmail.com> | 2017-11-06 22:59:38 +0000 |
commit | 5cee48036ed69ae298a599d43cf72e0fe73e3b4e (patch) | |
tree | 5fe732c738a769d02e732469f4ffecd4ac9e191a /hadrian/src/Rules/Compile.hs | |
parent | 275ac8ef0a0081f16abbfb8934e10cf271573768 (diff) | |
parent | 7b0b9f603bb1215e2b7af23c2404d637b95a4988 (diff) | |
download | haskell-5cee48036ed69ae298a599d43cf72e0fe73e3b4e.tar.gz |
Merge commit '7b0b9f603bb1215e2b7af23c2404d637b95a4988' as 'hadrian'
Diffstat (limited to 'hadrian/src/Rules/Compile.hs')
-rw-r--r-- | hadrian/src/Rules/Compile.hs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/hadrian/src/Rules/Compile.hs b/hadrian/src/Rules/Compile.hs new file mode 100644 index 0000000000..a4b1278660 --- /dev/null +++ b/hadrian/src/Rules/Compile.hs @@ -0,0 +1,83 @@ +module Rules.Compile (compilePackage) where + +import Hadrian.Oracles.TextFile + +import Base +import Context +import Expression +import Rules.Generate +import Target +import Utilities + +compilePackage :: [(Resource, Int)] -> Context -> Rules () +compilePackage rs context@Context {..} = do + let dir = "//" ++ contextDir context + nonHs extension = dir -/- extension <//> "*" <.> osuf way + compile compiler obj2src obj = do + src <- obj2src context obj + need [src] + needDependencies context src $ obj <.> "d" + buildWithResources rs $ target context (compiler stage) [src] [obj] + compileHs = \[obj, _hi] -> do + path <- buildPath context + (src, deps) <- lookupDependencies (path -/- ".dependencies") obj + need $ src : deps + when (isLibrary package) $ need =<< return <$> pkgConfFile context + needLibrary =<< contextDependencies context + buildWithResources rs $ target context (Ghc CompileHs stage) [src] [obj] + + priority 2.0 $ do + nonHs "c" %> compile (Ghc CompileCWithGhc) (obj2src "c" isGeneratedCFile ) + nonHs "cmm" %> compile (Ghc CompileHs) (obj2src "cmm" isGeneratedCmmFile) + nonHs "s" %> compile (Ghc CompileHs) (obj2src "S" $ const False ) + + -- TODO: Add dependencies for #include of .h and .hs-incl files (gcc -MM?). + [ dir <//> "*" <.> suf way | suf <- [ osuf, hisuf] ] &%> compileHs + [ dir <//> "*" <.> suf way | suf <- [obootsuf, hibootsuf] ] &%> compileHs + +-- | Discover dependencies of a given source file by iteratively calling @gcc@ +-- in the @-MM -MG@ mode and building generated dependencies if they are missing +-- until reaching a fixed point. +needDependencies :: Context -> FilePath -> FilePath -> Action () +needDependencies context@Context {..} src depFile = discover + where + discover = do + build $ target context (Cc FindCDependencies stage) [src] [depFile] + deps <- parseFile depFile + -- Generated dependencies, if not yet built, will not be found and hence + -- will be referred to simply by their file names. + let notFound = filter (\file -> file == takeFileName file) deps + -- We find the full paths to generated dependencies, so we can request + -- to build them by calling 'need'. + todo <- catMaybes <$> mapM (fullPathIfGenerated context) notFound + + if null todo + then need deps -- The list of dependencies is final, need all + else do + need todo -- Build newly discovered generated dependencies + discover -- Continue the discovery process + + parseFile :: FilePath -> Action [String] + parseFile file = do + input <- liftIO $ readFile file + case parseMakefile input of + [(_file, deps)] -> return deps + _ -> return [] + +-- | Find a given 'FilePath' in the list of generated files in the given +-- 'Context' and return its full path. +fullPathIfGenerated :: Context -> FilePath -> Action (Maybe FilePath) +fullPathIfGenerated context file = interpretInContext context $ do + generated <- generatedDependencies + return $ find ((== file) . takeFileName) generated + +obj2src :: String -> (FilePath -> Bool) -> Context -> FilePath -> Action FilePath +obj2src extension isGenerated context@Context {..} obj + | isGenerated src = return src + | otherwise = (pkgPath package ++) <$> suffix + where + src = obj -<.> extension + suffix = do + path <- buildPath context + return $ fromMaybe ("Cannot determine source for " ++ obj) + $ stripPrefix (path -/- extension) src |