diff options
author | David Eichmann <EichmannD@gmail.com> | 2019-05-14 11:44:00 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-05-25 17:55:05 -0400 |
commit | 9be1749d24211c1a78334692d34be10dbc650371 (patch) | |
tree | 21e4fc10368aaaa6aea10de3e7d28e0524f75bf6 | |
parent | 70c244710258b8ef9cc61cebcbc0d26799e2fd0a (diff) | |
download | haskell-9be1749d24211c1a78334692d34be10dbc650371.tar.gz |
Hadrian: Add Mising Libffi Dependencies #16653
Libffi is ultimately built from a single archive file (e.g.
libffi-tarballs/libffi-3.99999+git20171002+77e130c.tar.gz).
The file can be seen as the shallow dependency for the whole
libffi build. Hence, in all libffi rules, the archive is
`need`ed and the build directory is `trackAllow`ed.
-rw-r--r-- | hadrian/src/Rules/Libffi.hs | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/hadrian/src/Rules/Libffi.hs b/hadrian/src/Rules/Libffi.hs index b185d9a601..44d6154fc2 100644 --- a/hadrian/src/Rules/Libffi.hs +++ b/hadrian/src/Rules/Libffi.hs @@ -24,6 +24,7 @@ askLibffilDynLibs stage = askOracle (LibffiDynLibs stage) -- | The path to the dynamic library manifest file. The file contains all file -- paths to libffi dynamic library file paths. +-- The path is calculated but not `need`ed. dynLibManifest' :: Monad m => m FilePath -> Stage -> m FilePath dynLibManifest' getRoot stage = do root <- getRoot @@ -103,6 +104,24 @@ configureEnvironment stage = do , return . AddEnv "CFLAGS" $ unwords cFlags ++ " -w" , return . AddEnv "LDFLAGS" $ unwords ldFlags ++ " -w" ] +-- Need the libffi archive and `trackAllow` all files in the build directory. +-- As all libffi build files are derived from this archive, we can safely +-- `trackAllow` the libffi build dir. I.e the archive file can be seen as a +-- shallow dependency of the libffi build. This is much simpler than working out +-- the dependencies of each rule (within the build dir). +-- This means changing the archive file forces a clean build of libffi. This +-- seems like a performance issue, but is justified as building libffi is fast +-- and the archive file is rarely changed. +needLibfffiArchive :: FilePath -> Action FilePath +needLibfffiArchive buildPath = do + top <- topDirectory + tarball <- unifyPath + . fromSingleton "Exactly one LibFFI tarball is expected" + <$> getDirectoryFiles top ["libffi-tarballs/libffi*.tar.gz"] + need [top -/- tarball] + trackAllow [buildPath -/- "//*"] + return tarball + libffiRules :: Rules () libffiRules = do _ <- addOracleCache $ \ (LibffiDynLibs stage) @@ -119,6 +138,7 @@ libffiRules = do , dynLibMan ] priority 2 $ topLevelTargets &%> \_ -> do + _ <- needLibfffiArchive libffiPath context <- libffiContext stage -- Note this build needs the Makefile, triggering the rules bellow. @@ -149,11 +169,7 @@ libffiRules = do -- Extract libffi tar file context <- libffiContext stage removeDirectory libffiPath - top <- topDirectory - tarball <- unifyPath . fromSingleton "Exactly one LibFFI tarball is expected" - <$> getDirectoryFiles top ["libffi-tarballs/libffi*.tar.gz"] - - need [top -/- tarball] + tarball <- needLibfffiArchive libffiPath -- Go from 'libffi-3.99999+git20171002+77e130c.tar.gz' to 'libffi-3.99999' let libname = takeWhile (/= '+') $ takeFileName tarball @@ -166,12 +182,14 @@ libffiRules = do -- And finally: removeFiles (path) [libname <//> "*"] + top <- topDirectory fixFile mkIn (fixLibffiMakefile top) files <- liftIO $ getDirectoryFilesIO "." [libffiPath <//> "*"] produces files fmap (libffiPath -/-) ["Makefile", "config.guess", "config.sub"] &%> \[mk, _, _] -> do + _ <- needLibfffiArchive libffiPath context <- libffiContext stage -- This need rule extracts the libffi tar file to libffiPath. |