1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
-----------------------------------------------------------------------------
-- $Id: DriverMkDepend.hs,v 1.15 2001/08/03 07:44:47 sof Exp $
--
-- GHC Driver
--
-- (c) Simon Marlow 2000
--
-----------------------------------------------------------------------------
module DriverMkDepend where
#include "HsVersions.h"
import DriverState
import DriverUtil
import DriverFlags
import SysTools ( newTempName )
import qualified SysTools
import Module
import Config
import Module ( isHomeModule )
import Finder ( findModuleDep )
import HscTypes ( ModuleLocation(..) )
import Util
import Panic
import IOExts
import Exception
import Directory
import IO
import Monad
import Maybe
-------------------------------------------------------------------------------
-- mkdependHS
-- flags
GLOBAL_VAR(v_Dep_makefile, "Makefile", String);
GLOBAL_VAR(v_Dep_include_prelude, False, Bool);
GLOBAL_VAR(v_Dep_exclude_mods, [], [String]);
GLOBAL_VAR(v_Dep_suffixes, [], [String]);
GLOBAL_VAR(v_Dep_warnings, True, Bool);
-- global vars
GLOBAL_VAR(v_Dep_makefile_hdl, error "dep_makefile_hdl", Maybe Handle);
GLOBAL_VAR(v_Dep_tmp_file, error "dep_tmp_file", String);
GLOBAL_VAR(v_Dep_tmp_hdl, error "dep_tmp_hdl", Handle);
GLOBAL_VAR(v_Dep_dir_contents, error "dep_dir_contents", [(String,[String])]);
depStartMarker = "# DO NOT DELETE: Beginning of Haskell dependencies"
depEndMarker = "# DO NOT DELETE: End of Haskell dependencies"
-- for compatibility with the old mkDependHS, we accept options of the form
-- -optdep-f -optdep.depend, etc.
dep_opts = [
( "s", SepArg (add v_Dep_suffixes) ),
( "f", SepArg (writeIORef v_Dep_makefile) ),
( "w", NoArg (writeIORef v_Dep_warnings False) ),
( "-include-prelude", NoArg (writeIORef v_Dep_include_prelude True) )
-- ( "-exclude-module=", Prefix (add v_Dep_exclude_mods) )
-- ( "x", Prefix (add v_Dep_exclude_mods) )
]
beginMkDependHS :: IO ()
beginMkDependHS = do
-- slurp in the mkdependHS-style options
flags <- getStaticOpts v_Opt_dep
_ <- processArgs dep_opts flags []
-- open a new temp file in which to stuff the dependency info
-- as we go along.
dep_file <- newTempName "dep"
writeIORef v_Dep_tmp_file dep_file
tmp_hdl <- openFile dep_file WriteMode
writeIORef v_Dep_tmp_hdl tmp_hdl
-- open the makefile
makefile <- readIORef v_Dep_makefile
exists <- doesFileExist makefile
if not exists
then do
writeIORef v_Dep_makefile_hdl Nothing
return ()
else do
makefile_hdl <- openFile makefile ReadMode
writeIORef v_Dep_makefile_hdl (Just makefile_hdl)
-- slurp through until we get the magic start string,
-- copying the contents into dep_makefile
let slurp = do
l <- hGetLine makefile_hdl
if (l == depStartMarker)
then return ()
else do hPutStrLn tmp_hdl l; slurp
-- slurp through until we get the magic end marker,
-- throwing away the contents
let chuck = do
l <- hGetLine makefile_hdl
if (l == depEndMarker)
then return ()
else chuck
catchJust ioErrors slurp
(\e -> if isEOFError e then return () else ioError e)
catchJust ioErrors chuck
(\e -> if isEOFError e then return () else ioError e)
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depStartMarker
-- cache the contents of all the import directories, for future
-- reference.
import_dirs <- readIORef v_Import_paths
pkg_import_dirs <- getPackageImportPath
import_dir_contents <- mapM softGetDirectoryContents import_dirs
pkg_import_dir_contents <- mapM softGetDirectoryContents pkg_import_dirs
writeIORef v_Dep_dir_contents
(zip import_dirs import_dir_contents ++
zip pkg_import_dirs pkg_import_dir_contents)
return ()
endMkDependHS :: IO ()
endMkDependHS = do
makefile <- readIORef v_Dep_makefile
makefile_hdl <- readIORef v_Dep_makefile_hdl
tmp_file <- readIORef v_Dep_tmp_file
tmp_hdl <- readIORef v_Dep_tmp_hdl
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depEndMarker
case makefile_hdl of
Nothing -> return ()
Just hdl -> do
-- slurp the rest of the original makefile and copy it into the output
let slurp = do
l <- hGetLine hdl
hPutStrLn tmp_hdl l
slurp
catchJust ioErrors slurp
(\e -> if isEOFError e then return () else ioError e)
hClose hdl
hClose tmp_hdl -- make sure it's flushed
-- Create a backup of the original makefile
when (isJust makefile_hdl)
(SysTools.copy ("Backing up " ++ makefile) makefile (makefile++".bak"))
-- Copy the new makefile in place
SysTools.copy "Installing new makefile" tmp_file makefile
findDependency :: Bool -> FilePath -> ModuleName -> IO (Maybe (String, Bool))
findDependency is_source src imp = do
excl_mods <- readIORef v_Dep_exclude_mods
include_prelude <- readIORef v_Dep_include_prelude
let imp_mod = moduleNameUserString imp
if imp_mod `elem` excl_mods
then return Nothing
else do
r <- findModuleDep imp is_source
case r of
Just (mod,loc)
| isHomeModule mod || include_prelude
-> return (Just (ml_hi_file loc, not is_source))
| otherwise
-> return Nothing
Nothing -> throwDyn (ProgramError
(src ++ ": " ++ "can't locate import `" ++ imp_mod ++ "'"))
|