1 -----------------------------------------------------------------------------
2 -- $Id: DriverMkDepend.hs,v 1.19 2002/03/20 20:20:26 sof Exp $
6 -- (c) Simon Marlow 2000
8 -----------------------------------------------------------------------------
10 module DriverMkDepend where
12 #include "HsVersions.h"
15 import DriverUtil ( add, softGetDirectoryContents )
17 import SysTools ( newTempName )
18 import qualified SysTools
19 import Module ( ModuleName, moduleNameUserString, isHomeModule )
20 import Finder ( findModuleDep )
21 import HscTypes ( ModuleLocation(..) )
22 import Util ( global )
31 import Maybe ( isJust )
33 -------------------------------------------------------------------------------
37 GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
38 GLOBAL_VAR(v_Dep_include_prelude, False, Bool);
39 GLOBAL_VAR(v_Dep_exclude_mods, ["GHC.Prim"], [String]);
40 GLOBAL_VAR(v_Dep_suffixes, [], [String]);
41 GLOBAL_VAR(v_Dep_warnings, True, Bool);
44 GLOBAL_VAR(v_Dep_makefile_hdl, error "dep_makefile_hdl", Maybe Handle);
45 GLOBAL_VAR(v_Dep_tmp_file, error "dep_tmp_file", String);
46 GLOBAL_VAR(v_Dep_tmp_hdl, error "dep_tmp_hdl", Handle);
47 GLOBAL_VAR(v_Dep_dir_contents, error "dep_dir_contents", [(String,[String])]);
49 depStartMarker = "# DO NOT DELETE: Beginning of Haskell dependencies"
50 depEndMarker = "# DO NOT DELETE: End of Haskell dependencies"
52 -- for compatibility with the old mkDependHS, we accept options of the form
53 -- -optdep-f -optdep.depend, etc.
55 [ ( "s", SepArg (add v_Dep_suffixes) )
56 , ( "f", SepArg (writeIORef v_Dep_makefile) )
57 , ( "w", NoArg (writeIORef v_Dep_warnings False) )
58 , ( "-include-prelude", NoArg (writeIORef v_Dep_include_prelude True) )
59 , ( "-exclude-module=", Prefix (add v_Dep_exclude_mods) )
60 , ( "x", Prefix (add v_Dep_exclude_mods) )
63 beginMkDependHS :: IO ()
66 -- slurp in the mkdependHS-style options
67 flags <- getStaticOpts v_Opt_dep
68 _ <- processArgs dep_opts flags []
70 -- open a new temp file in which to stuff the dependency info
72 dep_file <- newTempName "dep"
73 writeIORef v_Dep_tmp_file dep_file
74 tmp_hdl <- openFile dep_file WriteMode
75 writeIORef v_Dep_tmp_hdl tmp_hdl
78 makefile <- readIORef v_Dep_makefile
79 exists <- doesFileExist makefile
82 writeIORef v_Dep_makefile_hdl Nothing
86 makefile_hdl <- openFile makefile ReadMode
87 writeIORef v_Dep_makefile_hdl (Just makefile_hdl)
89 -- slurp through until we get the magic start string,
90 -- copying the contents into dep_makefile
92 l <- hGetLine makefile_hdl
93 if (l == depStartMarker)
95 else do hPutStrLn tmp_hdl l; slurp
97 -- slurp through until we get the magic end marker,
98 -- throwing away the contents
100 l <- hGetLine makefile_hdl
101 if (l == depEndMarker)
105 catchJust ioErrors slurp
106 (\e -> if isEOFError e then return () else ioError e)
107 catchJust ioErrors chuck
108 (\e -> if isEOFError e then return () else ioError e)
111 -- write the magic marker into the tmp file
112 hPutStrLn tmp_hdl depStartMarker
114 -- cache the contents of all the import directories, for future
116 import_dirs <- readIORef v_Import_paths
117 pkg_import_dirs <- getPackageImportPath
118 import_dir_contents <- mapM softGetDirectoryContents import_dirs
119 pkg_import_dir_contents <- mapM softGetDirectoryContents pkg_import_dirs
120 writeIORef v_Dep_dir_contents
121 (zip import_dirs import_dir_contents ++
122 zip pkg_import_dirs pkg_import_dir_contents)
127 endMkDependHS :: IO ()
129 makefile <- readIORef v_Dep_makefile
130 makefile_hdl <- readIORef v_Dep_makefile_hdl
131 tmp_file <- readIORef v_Dep_tmp_file
132 tmp_hdl <- readIORef v_Dep_tmp_hdl
134 -- write the magic marker into the tmp file
135 hPutStrLn tmp_hdl depEndMarker
141 -- slurp the rest of the original makefile and copy it into the output
147 catchJust ioErrors slurp
148 (\e -> if isEOFError e then return () else ioError e)
152 hClose tmp_hdl -- make sure it's flushed
154 -- Create a backup of the original makefile
155 when (isJust makefile_hdl)
156 (SysTools.copy ("Backing up " ++ makefile) makefile (makefile++".bak"))
158 -- Copy the new makefile in place
159 SysTools.copy "Installing new makefile" tmp_file makefile
162 findDependency :: Bool -> FilePath -> ModuleName -> IO (Maybe (String, Bool))
163 findDependency is_source src imp = do
164 excl_mods <- readIORef v_Dep_exclude_mods
165 include_prelude <- readIORef v_Dep_include_prelude
166 let imp_mod = moduleNameUserString imp
167 if imp_mod `elem` excl_mods
170 r <- findModuleDep imp is_source
173 | isHomeModule mod || include_prelude
174 -> return (Just (ml_hi_file loc, not is_source))
177 Nothing -> throwDyn (ProgramError
178 (src ++ ": " ++ "can't locate import `" ++ imp_mod ++ "'" ++
179 if is_source then " (SOURCE import)" else ""))