summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-01-22 18:20:15 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-01-29 04:04:12 -0500
commit18e106a8dfdae50c3078558382209f53794a8c97 (patch)
tree6f9e10dbfc50a977bbb82ecf31a75e1a12aa8d1c
parent6fc920847f65e9b9f347bde42b2f9ec624468cfd (diff)
downloadhaskell-18e106a8dfdae50c3078558382209f53794a8c97.tar.gz
Add missing .hi-boot dependencies with ghc -M (#14482)
-rw-r--r--compiler/GHC/Driver/MakeFile.hs12
-rw-r--r--compiler/GHC/Unit/Module/Location.hs8
-rw-r--r--hadrian/src/Hadrian/Oracles/TextFile.hs10
-rw-r--r--testsuite/tests/driver/T14482/A.hs5
-rw-r--r--testsuite/tests/driver/T14482/B.hs3
-rw-r--r--testsuite/tests/driver/T14482/B.hs-boot3
-rw-r--r--testsuite/tests/driver/T14482/C.hs10
-rw-r--r--testsuite/tests/driver/T14482/Makefile8
-rw-r--r--testsuite/tests/driver/T14482/T14482.stdout14
-rw-r--r--testsuite/tests/driver/T14482/all.T1
10 files changed, 72 insertions, 2 deletions
diff --git a/compiler/GHC/Driver/MakeFile.hs b/compiler/GHC/Driver/MakeFile.hs
index 2328a32ec5..d513728036 100644
--- a/compiler/GHC/Driver/MakeFile.hs
+++ b/compiler/GHC/Driver/MakeFile.hs
@@ -47,7 +47,7 @@ import System.Directory
import System.FilePath
import System.IO
import System.IO.Error ( isEOFError )
-import Control.Monad ( when )
+import Control.Monad ( when, forM_ )
import Data.Maybe ( isJust )
import Data.IORef
import qualified Data.Set as Set
@@ -241,6 +241,16 @@ processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode (ExtendedM
-- Something like A.o : A.hs
; writeDependency root hdl obj_files src_file
+ -- add dependency between objects and their corresponding .hi-boot
+ -- files if the module has a corresponding .hs-boot file (#14482)
+ ; when (isBootSummary node == IsBoot) $ do
+ let hi_boot = msHiFilePath node
+ let obj = removeBootSuffix (msObjFilePath node)
+ forM_ extra_suffixes $ \suff -> do
+ let way_obj = insertSuffixes obj [suff]
+ let way_hi_boot = insertSuffixes hi_boot [suff]
+ mapM_ (writeDependency root hdl way_obj) way_hi_boot
+
-- Emit a dependency for each CPP import
; when (depIncludeCppDeps dflags) $ do
-- CPP deps are descovered in the module parsing phase by parsing
diff --git a/compiler/GHC/Unit/Module/Location.hs b/compiler/GHC/Unit/Module/Location.hs
index 6f239227f0..ff5354bfdb 100644
--- a/compiler/GHC/Unit/Module/Location.hs
+++ b/compiler/GHC/Unit/Module/Location.hs
@@ -5,6 +5,7 @@ module GHC.Unit.Module.Location
, addBootSuffix_maybe
, addBootSuffixLocn
, addBootSuffixLocnOut
+ , removeBootSuffix
)
where
@@ -54,6 +55,13 @@ instance Outputable ModLocation where
addBootSuffix :: FilePath -> FilePath
addBootSuffix path = path ++ "-boot"
+-- | Remove the @-boot@ suffix to .hs, .hi and .o files
+removeBootSuffix :: FilePath -> FilePath
+removeBootSuffix "-boot" = []
+removeBootSuffix (x:xs) = x : removeBootSuffix xs
+removeBootSuffix [] = error "removeBootSuffix: no -boot suffix"
+
+
-- | Add the @-boot@ suffix if the @Bool@ argument is @True@
addBootSuffix_maybe :: IsBootInterface -> FilePath -> FilePath
addBootSuffix_maybe is_boot path = case is_boot of
diff --git a/hadrian/src/Hadrian/Oracles/TextFile.hs b/hadrian/src/Hadrian/Oracles/TextFile.hs
index d6fb78cc2f..ae8182e0dd 100644
--- a/hadrian/src/Hadrian/Oracles/TextFile.hs
+++ b/hadrian/src/Hadrian/Oracles/TextFile.hs
@@ -18,6 +18,7 @@ module Hadrian.Oracles.TextFile (
import Control.Monad
import qualified Data.HashMap.Strict as Map
import Data.Maybe
+import Data.List
import Development.Shake
import Development.Shake.Classes
import Development.Shake.Config
@@ -60,7 +61,14 @@ lookupValuesOrError file key = fromMaybe (error msg) <$> lookupValues file key
-- compiling @source@, which in turn also depends on a number of other @files@.
lookupDependencies :: FilePath -> FilePath -> Action (FilePath, [FilePath])
lookupDependencies depFile file = do
- deps <- lookupValues depFile file
+ let -- .hs needs to come before .hi-boot deps added to fix #14482.
+ -- This is still a bit fragile: we have no order guaranty from the input
+ -- file. Let's hope we don't have two different .hs source files (e.g.
+ -- one included into the other)...
+ weigh p
+ | ".hs" `isSuffixOf` p = 0 :: Int
+ | otherwise = 1
+ deps <- fmap (sortOn weigh) <$> lookupValues depFile file
case deps of
Nothing -> error $ "No dependencies found for file " ++ quote file
Just [] -> error $ "No source file found for file " ++ quote file
diff --git a/testsuite/tests/driver/T14482/A.hs b/testsuite/tests/driver/T14482/A.hs
new file mode 100644
index 0000000000..fc453a5094
--- /dev/null
+++ b/testsuite/tests/driver/T14482/A.hs
@@ -0,0 +1,5 @@
+module A where
+
+import {-# SOURCE #-} B
+
+data A = A B
diff --git a/testsuite/tests/driver/T14482/B.hs b/testsuite/tests/driver/T14482/B.hs
new file mode 100644
index 0000000000..64e74c695a
--- /dev/null
+++ b/testsuite/tests/driver/T14482/B.hs
@@ -0,0 +1,3 @@
+module B where
+
+data B = B
diff --git a/testsuite/tests/driver/T14482/B.hs-boot b/testsuite/tests/driver/T14482/B.hs-boot
new file mode 100644
index 0000000000..66fadef083
--- /dev/null
+++ b/testsuite/tests/driver/T14482/B.hs-boot
@@ -0,0 +1,3 @@
+module B where
+
+data B
diff --git a/testsuite/tests/driver/T14482/C.hs b/testsuite/tests/driver/T14482/C.hs
new file mode 100644
index 0000000000..5cb3a6aea6
--- /dev/null
+++ b/testsuite/tests/driver/T14482/C.hs
@@ -0,0 +1,10 @@
+module Main where
+
+import A
+import B
+
+data C = C A
+data D = D B
+
+main :: IO ()
+main = putStrLn ""
diff --git a/testsuite/tests/driver/T14482/Makefile b/testsuite/tests/driver/T14482/Makefile
new file mode 100644
index 0000000000..e8b1fd84cc
--- /dev/null
+++ b/testsuite/tests/driver/T14482/Makefile
@@ -0,0 +1,8 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T14482:
+ rm -f *.o *.hi *.o-boot *.hi-boot C result
+ '$(TEST_HC)' -M C.hs -dep-suffix "p_" -dep-suffix "q_" -dep-makefile result
+ cat result
diff --git a/testsuite/tests/driver/T14482/T14482.stdout b/testsuite/tests/driver/T14482/T14482.stdout
new file mode 100644
index 0000000000..a67407ae37
--- /dev/null
+++ b/testsuite/tests/driver/T14482/T14482.stdout
@@ -0,0 +1,14 @@
+# DO NOT DELETE: Beginning of Haskell dependencies
+B.q_o-boot B.p_o-boot : B.hs-boot
+B.q_o : B.q_hi-boot
+B.p_o : B.p_hi-boot
+B.q_o B.p_o : B.hs
+A.q_o A.p_o : A.hs
+A.q_o : B.q_hi-boot
+A.p_o : B.p_hi-boot
+C.q_o C.p_o : C.hs
+C.q_o : B.q_hi
+C.p_o : B.p_hi
+C.q_o : A.q_hi
+C.p_o : A.p_hi
+# DO NOT DELETE: End of Haskell dependencies
diff --git a/testsuite/tests/driver/T14482/all.T b/testsuite/tests/driver/T14482/all.T
new file mode 100644
index 0000000000..0337fa8abd
--- /dev/null
+++ b/testsuite/tests/driver/T14482/all.T
@@ -0,0 +1 @@
+test('T14482', [extra_files(['A.hs', 'B.hs', 'B.hs-boot', 'C.hs'])], makefile_test, [])