1 -----------------------------------------------------------------------------
2 -- $Id: DriverMkDepend.hs,v 1.13 2001/06/26 16:30:50 rrt Exp $
6 -- (c) Simon Marlow 2000
8 -----------------------------------------------------------------------------
10 module DriverMkDepend where
12 #include "HsVersions.h"
17 import SysTools ( newTempName )
18 import qualified SysTools
32 -------------------------------------------------------------------------------
36 GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
37 GLOBAL_VAR(v_Dep_include_prelude, False, Bool);
38 GLOBAL_VAR(v_Dep_ignore_dirs, [], [String]);
39 GLOBAL_VAR(v_Dep_exclude_mods, [], [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 ( "X", Prefix (addToDirList v_Dep_ignore_dirs) ),
60 ( "-exclude-directory=", Prefix (addToDirList v_Dep_ignore_dirs) )
61 -- ( "-exclude-module=", Prefix (add v_Dep_exclude_mods) )
62 -- ( "x", Prefix (add v_Dep_exclude_mods) )
66 beginMkDependHS :: IO ()
69 -- slurp in the mkdependHS-style options
70 flags <- getStaticOpts v_Opt_dep
71 _ <- processArgs dep_opts flags []
73 -- open a new temp file in which to stuff the dependency info
75 dep_file <- newTempName "dep"
76 writeIORef v_Dep_tmp_file dep_file
77 tmp_hdl <- openFile dep_file WriteMode
78 writeIORef v_Dep_tmp_hdl tmp_hdl
81 makefile <- readIORef v_Dep_makefile
82 exists <- doesFileExist makefile
85 writeIORef v_Dep_makefile_hdl Nothing
89 makefile_hdl <- openFile makefile ReadMode
90 writeIORef v_Dep_makefile_hdl (Just makefile_hdl)
92 -- slurp through until we get the magic start string,
93 -- copying the contents into dep_makefile
95 l <- hGetLine makefile_hdl
96 if (l == depStartMarker)
98 else do hPutStrLn tmp_hdl l; slurp
100 -- slurp through until we get the magic end marker,
101 -- throwing away the contents
103 l <- hGetLine makefile_hdl
104 if (l == depEndMarker)
108 catchJust ioErrors slurp
109 (\e -> if isEOFError e then return () else ioError e)
110 catchJust ioErrors chuck
111 (\e -> if isEOFError e then return () else ioError e)
114 -- write the magic marker into the tmp file
115 hPutStrLn tmp_hdl depStartMarker
117 -- cache the contents of all the import directories, for future
119 import_dirs <- readIORef v_Import_paths
120 pkg_import_dirs <- getPackageImportPath
121 import_dir_contents <- mapM softGetDirectoryContents import_dirs
122 pkg_import_dir_contents <- mapM softGetDirectoryContents pkg_import_dirs
123 writeIORef v_Dep_dir_contents
124 (zip import_dirs import_dir_contents ++
125 zip pkg_import_dirs pkg_import_dir_contents)
127 -- ignore packages unless --include-prelude is on
128 include_prelude <- readIORef v_Dep_include_prelude
129 when (not include_prelude) $
130 mapM_ (add v_Dep_ignore_dirs) pkg_import_dirs
135 endMkDependHS :: IO ()
137 makefile <- readIORef v_Dep_makefile
138 makefile_hdl <- readIORef v_Dep_makefile_hdl
139 tmp_file <- readIORef v_Dep_tmp_file
140 tmp_hdl <- readIORef v_Dep_tmp_hdl
142 -- write the magic marker into the tmp file
143 hPutStrLn tmp_hdl depEndMarker
149 -- slurp the rest of the original makefile and copy it into the output
155 catchJust ioErrors slurp
156 (\e -> if isEOFError e then return () else ioError e)
160 hClose tmp_hdl -- make sure it's flushed
162 -- Create a backup of the original makefile
163 when (isJust makefile_hdl)
164 (SysTools.copy ("Backing up " ++ makefile) makefile (makefile++".bak"))
166 -- Copy the new makefile in place
167 SysTools.copy "Installing new makefile" tmp_file makefile
170 findDependency :: Bool -> FilePath -> ModuleName -> IO (Maybe (String, Bool))
171 findDependency is_source src imp = do
172 dir_contents <- readIORef v_Dep_dir_contents
173 ignore_dirs <- readIORef v_Dep_ignore_dirs
174 excl_mods <- readIORef v_Dep_exclude_mods
175 hisuf <- readIORef v_Hi_suf
178 imp_mod = moduleNameUserString imp
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 (ProgramError (src ++ ": " ++ "can't find one of the following: " ++
189 unwords (map (\d -> '`': d ++ "'") deps)))
190 search ((dir, contents) : dirs)
191 | null present = search dirs
193 if dir `elem` ignore_dirs
196 then if dep /= imp_hiboot_v
197 then return (Just (dir++'/':imp_hiboot, False))
198 else return (Just (dir++'/':dep, False))
199 else return (Just (dir++'/':imp_hi, not is_source))
201 present = filter (`elem` contents) deps
205 if imp_mod `elem` excl_mods then