@@ -36,7 +36,7 @@ import Data.Version (showVersion)
3636import qualified Data.Map as M
3737import qualified Data.ByteString.Char8 as B
3838
39−import System.Directory (doesDirectoryExist, doesFileExist, getModificationTime, createDirectoryIfMissing)
39+import System.Directory (copyFile, doesDirectoryExist, doesFileExist, getModificationTime, createDirectoryIfMissing)
4040import System.FilePath ((</>), takeDirectory, addExtension, dropExtension)
4141import System.IO.Error (tryIOError)
4242import System.IO.UTF8
@@ -54,11 +54,6 @@ makeIO f io = do
5454 e <- liftIO $ tryIOError io
5555 either (throwError . P.singleError . f) return e
5656
57−-- Traverse (Either e) instance (base 4.7)
58−traverseEither :: Applicative f => (a -> f b) -> Either e a -> f (Either e b)
59−traverseEither _ (Left x) = pure (Left x)
60−traverseEither f (Right y) = Right <$> f y
61−
6257buildMakeActions :: FilePath
6358 -> M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
6459 -> Bool
@@ -77,17 +72,23 @@ buildMakeActions outputDir filePathMap usePrefix =
7772 getInputTimestamp :: P.ModuleName -> Make (Either P.RebuildPolicy (Maybe UTCTime))
7873 getInputTimestamp mn = do
7974 let path = fromMaybe (error "Module has no filename in 'make'") $ M.lookup mn filePathMap
80− traverseEither getTimestamp path
75+ let filePath = either (const []) takeDirectory path
76+ fileBase = filePath </> (last . words . dotsTo ' ' $ P.runModuleName mn)
77+ sourceFFI = addExtension fileBase sourceExt
78+ headerFFI = addExtension fileBase headerExt
79+ e1 <- traverse getTimestamp path
80+ sffi <- getTimestamp sourceFFI
81+ hffi <- getTimestamp headerFFI
82+ return $ fmap (max (max sffi hffi)) e1
8183
8284 getOutputTimestamp :: P.ModuleName -> Make (Maybe UTCTime)
8385 getOutputTimestamp mn = do
84−
8586 let filePath = dotsTo '/' $ P.runModuleName mn
8687 fileBase = outputDir </> filePath </> (last . words . dotsTo ' ' $ P.runModuleName mn)
87− srcFile = addExtension fileBase "cc"
88−-- headerFile = addExtension fileBase "hh"
88+ sourceFile = addExtension fileBase sourceExt
89+ headerFile = addExtension fileBase headerExt
8990 externsFile = outputDir </> filePath </> "externs.purs"
90− min <$> getTimestamp srcFile <*> getTimestamp externsFile
91+ foldl min <$> getTimestamp externsFile <*> mapM getTimestamp [sourceFile, headerFile]
9192
9293 readExterns :: P.ModuleName -> Make (FilePath, P.Externs)
9394 readExterns mn = do
@@ -99,8 +100,8 @@ buildMakeActions outputDir filePathMap usePrefix =
99100 let mn = CF.moduleName m
100101 let filePath = dotsTo '/' $ P.runModuleName mn
101102 fileBase = outputDir </> filePath </> (last . words . dotsTo ' ' $ P.runModuleName mn)
102− srcFile = addExtension fileBase "cc"
103− headerFile = addExtension fileBase "hh"
103+ sourceFile = addExtension fileBase sourceExt
104+ headerFile = addExtension fileBase headerExt
104105 externsFile = outputDir </> filePath </> "externs.purs"
105106 prefix = ["Generated by pcc version " ++ showVersion Paths.version | usePrefix]
106107 cpps <- CPP.moduleToCpp env m
@@ -111,7 +112,7 @@ buildMakeActions outputDir filePathMap usePrefix =
111112 hdr = unlines $ map ("// " ++) prefix ++ [phdrs]
112113
113114 lift $ do
114− writeTextFile srcFile src
115+ writeTextFile sourceFile src
115116 writeTextFile headerFile hdr
116117 writeTextFile externsFile exts
117118
@@ -123,18 +124,17 @@ buildMakeActions outputDir filePathMap usePrefix =
123124 writeTextFile (supportDir </> "purescript_memory.hh") $ B.unpack $(embedFile "pcc/include/purescript_memory.hh")
124125
125126 let inputPath = dropExtension $ getInputFile mn
126− hfile = addExtension inputPath "hh"
127− sfile = addExtension inputPath "cc"
127+ hfile = addExtension inputPath headerExt
128+ sfile = addExtension inputPath sourceExt
128129 hfileExists <- textFileExists hfile
129130 when (hfileExists || requiresForeign m) $ do
130− text <- if hfileExists
131− then readTextFile hfile
132− else pure []
133− writeTextFile (addExtension (fileBase ++ "_ffi") "hh") text
131+ let dstFile = addExtension (fileBase ++ ffiMangle) headerExt
132+ if hfileExists
133+ then copyTextFile dstFile hfile
134+ else writeTextFile dstFile []
134135 sfileExists <- textFileExists sfile
135136 when (sfileExists) $ do
136− text' <- readTextFile sfile
137− writeTextFile (addExtension (fileBase ++ "_ffi") "cc") text'
137+ copyTextFile (addExtension (fileBase ++ ffiMangle) sourceExt) sfile
138138
139139 requiresForeign :: CF.Module a -> Bool
140140 requiresForeign = not . null . CF.moduleForeign
@@ -155,6 +155,11 @@ buildMakeActions outputDir filePathMap usePrefix =
155155 readTextFile :: FilePath -> Make String
156156 readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
157157
158+ copyTextFile :: FilePath -> FilePath -> Make ()
159+ copyTextFile to from = makeIO (const (ErrorMessage [] $ CannotWriteFile to)) $ do
160+ createDirectoryIfMissing True (takeDirectory to)
161+ copyFile from to
162+
158163 writeTextFile :: FilePath -> String -> Make ()
159164 writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
160165 createDirectoryIfMissing True (takeDirectory path)
@@ -170,3 +175,12 @@ buildMakeActions outputDir filePathMap usePrefix =
170175
171176dotsTo :: Char -> String -> String
172177dotsTo chr = map (\c -> if c == '.' then chr else c)
178+
179+headerExt :: String
180+headerExt = "hh"
181+
182+sourceExt :: String
183+sourceExt = "cc"
184+
185+ffiMangle :: String
186+ffiMangle = "_ffi"