1 -----------------------------------------------------------------------------
2 -- $Id: DriverMkDepend.hs,v 1.3 2000/10/26 16:21:02 sewardj Exp $
6 -- (c) Simon Marlow 2000
8 -----------------------------------------------------------------------------
10 module DriverMkDepend where
12 #include "HsVersions.h"
14 import CmSummarise -- for mkdependHS stuff
31 -------------------------------------------------------------------------------
35 GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
36 GLOBAL_VAR(v_Dep_include_prelude, False, Bool);
37 GLOBAL_VAR(v_Dep_ignore_dirs, [], [String]);
38 GLOBAL_VAR(v_Dep_suffixes, [], [String]);
39 GLOBAL_VAR(v_Dep_warnings, True, Bool);
42 GLOBAL_VAR(v_Dep_makefile_hdl, error "dep_makefile_hdl", Maybe Handle);
43 GLOBAL_VAR(v_Dep_tmp_file, error "dep_tmp_file", String);
44 GLOBAL_VAR(v_Dep_tmp_hdl, error "dep_tmp_hdl", Handle);
45 GLOBAL_VAR(v_Dep_dir_contents, error "dep_dir_contents", [(String,[String])]);
47 depStartMarker = "# DO NOT DELETE: Beginning of Haskell dependencies"
48 depEndMarker = "# DO NOT DELETE: End of Haskell dependencies"
50 -- for compatibility with the old mkDependHS, we accept options of the form
51 -- -optdep-f -optdep.depend, etc.
53 ( "s", SepArg (add v_Dep_suffixes) ),
54 ( "f", SepArg (writeIORef v_Dep_makefile) ),
55 ( "w", NoArg (writeIORef v_Dep_warnings False) ),
56 ( "-include-prelude", NoArg (writeIORef v_Dep_include_prelude True) ),
57 ( "X", Prefix (addToDirList v_Dep_ignore_dirs) ),
58 ( "-exclude-directory=", Prefix (addToDirList v_Dep_ignore_dirs) )
61 beginMkDependHS :: IO ()
64 -- slurp in the mkdependHS-style options
65 flags <- getStaticOpts v_Opt_dep
66 _ <- processArgs dep_opts flags []
68 -- open a new temp file in which to stuff the dependency info
70 dep_file <- newTempName "dep"
71 writeIORef v_Dep_tmp_file dep_file
72 tmp_hdl <- openFile dep_file WriteMode
73 writeIORef v_Dep_tmp_hdl tmp_hdl
76 makefile <- readIORef v_Dep_makefile
77 exists <- doesFileExist makefile
80 writeIORef v_Dep_makefile_hdl Nothing
84 makefile_hdl <- openFile makefile ReadMode
85 writeIORef v_Dep_makefile_hdl (Just makefile_hdl)
87 -- slurp through until we get the magic start string,
88 -- copying the contents into dep_makefile
90 l <- hGetLine makefile_hdl
91 if (l == depStartMarker)
93 else do hPutStrLn tmp_hdl l; slurp
95 -- slurp through until we get the magic end marker,
96 -- throwing away the contents
98 l <- hGetLine makefile_hdl
99 if (l == depEndMarker)
103 catchJust ioErrors slurp
104 (\e -> if isEOFError e then return () else ioError e)
105 catchJust ioErrors chuck
106 (\e -> if isEOFError e then return () else ioError e)
109 -- write the magic marker into the tmp file
110 hPutStrLn tmp_hdl depStartMarker
112 -- cache the contents of all the import directories, for future
114 import_dirs <- readIORef v_Import_paths
115 pkg_import_dirs <- getPackageImportPath
116 import_dir_contents <- mapM getDirectoryContents import_dirs
117 pkg_import_dir_contents <- mapM getDirectoryContents pkg_import_dirs
118 writeIORef v_Dep_dir_contents
119 (zip import_dirs import_dir_contents ++
120 zip pkg_import_dirs pkg_import_dir_contents)
122 -- ignore packages unless --include-prelude is on
123 include_prelude <- readIORef v_Dep_include_prelude
124 when (not include_prelude) $
125 mapM_ (add v_Dep_ignore_dirs) pkg_import_dirs
130 endMkDependHS :: IO ()
132 makefile <- readIORef v_Dep_makefile
133 makefile_hdl <- readIORef v_Dep_makefile_hdl
134 tmp_file <- readIORef v_Dep_tmp_file
135 tmp_hdl <- readIORef v_Dep_tmp_hdl
137 -- write the magic marker into the tmp file
138 hPutStrLn tmp_hdl depEndMarker
144 -- slurp the rest of the orignal makefile and copy it into the output
150 catchJust ioErrors slurp
151 (\e -> if isEOFError e then return () else ioError e)
155 hClose tmp_hdl -- make sure it's flushed
157 -- create a backup of the original makefile
158 when (isJust makefile_hdl) $
159 run_something ("Backing up " ++ makefile)
160 (unwords [ "cp", makefile, makefile++".bak" ])
162 -- copy the new makefile in place
163 run_something "Installing new makefile"
164 (unwords [ "cp", tmp_file, makefile ])
167 findDependency :: String -> ModImport -> IO (Maybe (String, Bool))
168 findDependency mod imp = do
169 dir_contents <- readIORef v_Dep_dir_contents
170 ignore_dirs <- readIORef v_Dep_ignore_dirs
171 hisuf <- readIORef v_Hi_suf
174 (imp_mod, is_source) =
176 MINormal str -> (moduleNameString str, False)
177 MISource str -> (moduleNameString str, True )
179 imp_hi = imp_mod ++ '.':hisuf
180 imp_hiboot = imp_mod ++ ".hi-boot"
181 imp_hiboot_v = imp_mod ++ ".hi-boot-" ++ cHscIfaceFileVersion
182 imp_hs = imp_mod ++ ".hs"
183 imp_lhs = imp_mod ++ ".lhs"
185 deps | is_source = [ imp_hiboot_v, imp_hiboot, imp_hs, imp_lhs ]
186 | otherwise = [ imp_hi, imp_hs, imp_lhs ]
188 search [] = throwDyn (OtherError ("can't find one of the following: " ++
189 unwords (map (\d -> '`': d ++ "'") deps) ++
190 " (imported from `" ++ mod ++ "')"))
191 search ((dir, contents) : dirs)
192 | null present = search dirs
194 if dir `elem` ignore_dirs
197 then if dep /= imp_hiboot_v
198 then return (Just (dir++'/':imp_hiboot, False))
199 else return (Just (dir++'/':dep, False))
200 else return (Just (dir++'/':imp_hi, not is_source))
202 present = filter (`elem` contents) deps