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
|
module GenerateMakeFile where
import Directory ( doesFileExist, getCurrentDirectory, renameFile )
import Distribution ( installDir )
import FilePath ( (</>), searchPathSeparator, splitSearchPath )
import FlatCurry.Types ( Prog(..) )
import FlatCurry.Read ( readFlatCurryIntWithImports )
import List ( intercalate, isPrefixOf, union )
import Sort ( sort )
import System ( getEnviron )
import System.CurryPath ( lookupModuleSourceInLoadPath )
import MakeFile
generateMakeForApplication :: Int -> String -> String -> String -> String
-> String -> IO ()
generateMakeForApplication verb args mainmod target root tool = do
makefile <- generateMakeFile args root tool mainmod
let makefiletext = showMakeFile makefile
when (null target || verb>1) $ putStr makefiletext
when (not (null target)) $ do
texists <- doesFileExist target
when texists $ do
let tbak = target ++ ".bak"
renameFile target tbak
putStrLn $ "Existing makefile saved to `" ++ tbak ++ "'"
writeFile target makefiletext
when (verb>0) $ putStrLn $ "Makefile written to `" ++ target ++ "'"
generateMakeFile :: String -> String -> String -> String -> IO MakeFile
generateMakeFile args root tool mainmod = do
allints <- readFlatCurryIntWithImports mainmod
let allmods = (foldl union [mainmod]
(map (\ (Prog _ imps _ _ _) -> imps) allints))
allsources <- mapIO findSourceFileInLoadPath (filter (/="Prelude") allmods)
currypath <- getEnviron "CURRYPATH"
curdir <- getCurrentDirectory
let simpcurrypath = if null currypath
then ""
else intercalate [searchPathSeparator]
(map (simplifyPath curdir)
(splitSearchPath currypath))
return $ modToMakeFile args root tool mainmod
(sort (map (simplifyPath curdir) allsources))
simpcurrypath
modToMakeFile :: String -> String -> String -> String -> [String] -> String
-> MakeFile
modToMakeFile args root tool mainmod sourcefiles currypath =
[ Comment $ "Makefile for main module \""++mainmod++"\""
, Comment $ "Created by: curry-genmake " ++ args
, Empty
, Comment "The root directory of the Curry system:"
, DefineVariable "CURRYHOME" [root]
, Empty
, Comment "The executable of the Curry system:"
, DefineVariable "REPL" ["$(CURRYHOME)/bin/curry"]
, Empty
, Comment "Default options for the Curry system:"
, DefineVariable "REPL_OPTS" [":set -time"]
, Empty
, Comment "The directory of the Curry system libraries:"
, DefineVariable "CURRYLIB" ["$(CURRYHOME)/lib"]
, Empty ] ++
ifNotNull tool
[ Comment "The tool name of the application:"
, DefineVariable "TOOL" [tool], Empty] ++
ifNotNull currypath
[ Comment "The load path of the application:"
, DefineVariable "LOADPATH" [currypath], Empty] ++
[ Comment "Source modules:"
, DefineVariable "DEPS" sourcefiles
, Empty
, Rule [PHONY] "all" ["install"] []
, Rule [PHONY] "install" ["compile"]
(ifNotNull tool
[ "mkdir -p $(dir $(TOOL))", "rm -f $(TOOL)"
, "cd $(dir $(TOOL)) && ln -s $(CURDIR)/"++mainmod++" $(notdir $(TOOL))"
, "@echo Tool installed into: $(TOOL)"])
, Rule [PHONY] "compile" [mainmod] []
, Comment "Load the application into the interactive Curry system:"
, Rule [PHONY] "load" []
["$(REPL) $(REPL_OPTS) " ++ setpath ++ ":l "++mainmod]
, Comment "Compile and create an executable of the application:"
, Rule [] mainmod ["$(DEPS)"]
["# create executable for top-level function \"main\":"
,"$(REPL) $(REPL_OPTS) " ++ setpath ++ ":l "++mainmod++" :save :q"]
, Comment "Clean intermediate files:"
, Rule [PHONY] "clean" [] ["$(CURRYHOME)/bin/cleancurry"]
, Rule [PHONY] "uninstall" ["clean"]
["rm -f " ++ mainmod ++ if null tool then "" else " $(TOOL)"]
]
where
setpath = if null currypath then "" else ":set path $(LOADPATH) "
ifNotNull s xs = if null s then [] else xs
findSourceFileInLoadPath :: String -> IO String
findSourceFileInLoadPath modname =
lookupModuleSourceInLoadPath modname >>=
maybe (error ("Curry file for module \""++modname++"\" not found!"))
(return . dropLocal . snd)
where
dropLocal f = if take 2 f == "./" then drop 2 f else f
simplifyPath :: String -> String -> String
simplifyPath curdir filename
| pakcslib `isPrefixOf` filename
= "$(CURRYLIB)" ++ drop (length pakcslib) filename
| curdir `isPrefixOf` filename
= drop (length curdir + 1) filename
| otherwise
= filename
where
pakcslib = installDir </> "lib"
|