1 -----------------------------------------------------------------------------
2 -- $Id: DriverMkDepend.hs,v 1.6 2000/11/21 14:34:47 simonmar Exp $
6 -- (c) Simon Marlow 2000
8 -----------------------------------------------------------------------------
10 module DriverMkDepend where
12 #include "HsVersions.h"
30 -------------------------------------------------------------------------------
34 GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
35 GLOBAL_VAR(v_Dep_include_prelude, False, Bool);
36 GLOBAL_VAR(v_Dep_ignore_dirs, [], [String]);
37 GLOBAL_VAR(v_Dep_suffixes, [], [String]);
38 GLOBAL_VAR(v_Dep_warnings, True, Bool);
41 GLOBAL_VAR(v_Dep_makefile_hdl, error "dep_makefile_hdl", Maybe Handle);
42 GLOBAL_VAR(v_Dep_tmp_file, error "dep_tmp_file", String);
43 GLOBAL_VAR(v_Dep_tmp_hdl, error "dep_tmp_hdl", Handle);
44 GLOBAL_VAR(v_Dep_dir_contents, error "dep_dir_contents", [(String,[String])]);
46 depStartMarker = "# DO NOT DELETE: Beginning of Haskell dependencies"
47 depEndMarker = "# DO NOT DELETE: End of Haskell dependencies"
49 -- for compatibility with the old mkDependHS, we accept options of the form
50 -- -optdep-f -optdep.depend, etc.
52 ( "s", SepArg (add v_Dep_suffixes) ),
53 ( "f", SepArg (writeIORef v_Dep_makefile) ),
54 ( "w", NoArg (writeIORef v_Dep_warnings False) ),
55 ( "-include-prelude", NoArg (writeIORef v_Dep_include_prelude True) ),
56 ( "X", Prefix (addToDirList v_Dep_ignore_dirs) ),
57 ( "-exclude-directory=", Prefix (addToDirList v_Dep_ignore_dirs) )
60 beginMkDependHS :: IO ()
63 -- slurp in the mkdependHS-style options
64 flags <- getStaticOpts v_Opt_dep
65 _ <- processArgs dep_opts flags []
67 -- open a new temp file in which to stuff the dependency info
69 dep_file <- newTempName "dep"
70 writeIORef v_Dep_tmp_file dep_file
71 tmp_hdl <- openFile dep_file WriteMode
72 writeIORef v_Dep_tmp_hdl tmp_hdl
75 makefile <- readIORef v_Dep_makefile
76 exists <- doesFileExist makefile
79 writeIORef v_Dep_makefile_hdl Nothing
83 makefile_hdl <- openFile makefile ReadMode
84 writeIORef v_Dep_makefile_hdl (Just makefile_hdl)
86 -- slurp through until we get the magic start string,
87 -- copying the contents into dep_makefile
89 l <- hGetLine makefile_hdl
90 if (l == depStartMarker)
92 else do hPutStrLn tmp_hdl l; slurp
94 -- slurp through until we get the magic end marker,
95 -- throwing away the contents
97 l <- hGetLine makefile_hdl
98 if (l == depEndMarker)
102 catchJust ioErrors slurp
103 (\e -> if isEOFError e then return () else ioError e)
104 catchJust ioErrors chuck
105 (\e -> if isEOFError e then return () else ioError e)
108 -- write the magic marker into the tmp file
109 hPutStrLn tmp_hdl depStartMarker
111 -- cache the contents of all the import directories, for future
113 import_dirs <- readIORef v_Import_paths
114 pkg_import_dirs <- getPackageImportPath
115 import_dir_contents <- mapM getDirectoryContents import_dirs
116 pkg_import_dir_contents <- mapM getDirectoryContents pkg_import_dirs
117 writeIORef v_Dep_dir_contents
118 (zip import_dirs import_dir_contents ++
119 zip pkg_import_dirs pkg_import_dir_contents)
121 -- ignore packages unless --include-prelude is on
122 include_prelude <- readIORef v_Dep_include_prelude
123 when (not include_prelude) $
124 mapM_ (add v_Dep_ignore_dirs) pkg_import_dirs
129 endMkDependHS :: IO ()
131 makefile <- readIORef v_Dep_makefile
132 makefile_hdl <- readIORef v_Dep_makefile_hdl
133 tmp_file <- readIORef v_Dep_tmp_file
134 tmp_hdl <- readIORef v_Dep_tmp_hdl
136 -- write the magic marker into the tmp file
137 hPutStrLn tmp_hdl depEndMarker
143 -- slurp the rest of the orignal makefile and copy it into the output
149 catchJust ioErrors slurp
150 (\e -> if isEOFError e then return () else ioError e)
154 hClose tmp_hdl -- make sure it's flushed
156 -- create a backup of the original makefile
157 when (isJust makefile_hdl) $
158 runSomething ("Backing up " ++ makefile)
159 (unwords [ "cp", makefile, makefile++".bak" ])
161 -- copy the new makefile in place
162 runSomething "Installing new makefile"
163 (unwords [ "cp", tmp_file, makefile ])
166 findDependency :: Bool -> String -> ModuleName -> IO (Maybe (String, Bool))
167 findDependency is_source mod imp = do
168 dir_contents <- readIORef v_Dep_dir_contents
169 ignore_dirs <- readIORef v_Dep_ignore_dirs
170 hisuf <- readIORef v_Hi_suf
173 imp_mod = moduleNameUserString imp
174 imp_hi = imp_mod ++ '.':hisuf
175 imp_hiboot = imp_mod ++ ".hi-boot"
176 imp_hiboot_v = imp_mod ++ ".hi-boot-" ++ cHscIfaceFileVersion
177 imp_hs = imp_mod ++ ".hs"
178 imp_lhs = imp_mod ++ ".lhs"
180 deps | is_source = [ imp_hiboot_v, imp_hiboot, imp_hs, imp_lhs ]
181 | otherwise = [ imp_hi, imp_hs, imp_lhs ]
183 search [] = throwDyn (OtherError ("can't find one of the following: " ++
184 unwords (map (\d -> '`': d ++ "'") deps) ++
185 " (imported from `" ++ mod ++ "')"))
186 search ((dir, contents) : dirs)
187 | null present = search dirs
189 if dir `elem` ignore_dirs
192 then if dep /= imp_hiboot_v
193 then return (Just (dir++'/':imp_hiboot, False))
194 else return (Just (dir++'/':dep, False))
195 else return (Just (dir++'/':imp_hi, not is_source))
197 present = filter (`elem` contents) deps