on master help sign in
Simplify setup code, trim lots of extra stuff.
33d4934Evan Czaplicki
Setup.hs+61−94
@@ -1,55 +1,40 @@
1+{-# OPTIONS_GHC -W #-}
1import Distribution.Simple
2import Distribution.Simple
2import Distribution.Simple.LocalBuildInfo
3import Distribution.Simple.LocalBuildInfo
3import Distribution.Simple.Setup
4import Distribution.Simple.Setup
4import Distribution.PackageDescription
5import Distribution.PackageDescription
5
6
6−import System.Cmd
7import System.Directory
7import System.Directory
8import System.FilePath
8import System.FilePath
9import System.IO
9import System.IO
10import System.Process
10import System.Process
11
11
12−import Control.Monad
13import qualified Data.Binary as Binary
12import qualified Data.Binary as Binary
14import qualified Data.ByteString.Lazy as BS
13import qualified Data.ByteString.Lazy as BS
15import qualified Data.List as List
14import qualified Data.List as List
16
15
17−-- Part 1
16+-- OVERVIEW
18−-- ------
17+-- --------
19−-- Add a build callout
20−-- We need to build elm-doc and run it because that generates the file "docs.json"
21−-- needs by Libraries.hs which is part of the elm library and executable
22−-- Unfort. there seems to be no way to tell cabal that:
23−-- (a) elm-doc generates docs.json, and
24−-- (b) elm (library) depends on docs.json
25−-- Therefore, we either use make instead (or a script), or hack around in cabal
26−
27−-- Part 2
28−-- ------
29−-- Add a post-build callout.
18+-- Add a post-build callout that compiles the standard libraries with the new
30−-- We need to build the runtime.js after we've built elm (because we use elm to generate some of the JavaScript),
19+-- compiler before cabal copies static files to actually install things.
31−-- but before cabal does the install file copy step
20+
32−
21+assetsDir :: FilePath
33−-- Assumptions
22+assetsDir = "data"
34−-- Elm.cabal expects the generated files to end up in dist/data
23+
35−-- git won't look in dist + cabal will clean it
36−rtsDir :: LocalBuildInfo -> FilePath
37−rtsDir lbi = "data"
38−
39−tempDir :: LocalBuildInfo -> FilePath
24+tempDir :: FilePath
40−tempDir lbi = "temp"
25+tempDir = "temp"
41
26
42-- The runtime is called:
27-- The runtime is called:
43−rts :: LocalBuildInfo -> FilePath
28+runtime :: FilePath
44−rts lbi = rtsDir lbi </> "elm-runtime.js"
29+runtime = assetsDir </> "elm-runtime.js"
45
30
46-- The runtime is called:
31-- The runtime is called:
47−docs :: LocalBuildInfo -> FilePath
32+docs :: FilePath
48−docs lbi = rtsDir lbi </> "docs.json"
33+docs = assetsDir </> "docs.json"
49
34
50-- The interfaces for the Standard Libraries live in:
35-- The interfaces for the Standard Libraries live in:
51−interfaces :: LocalBuildInfo -> FilePath
36+interfaces :: FilePath
52−interfaces lbi = rtsDir lbi </> "interfaces.data"
37+interfaces = assetsDir </> "interfaces.data"
53
38
54elm :: LocalBuildInfo -> FilePath
39elm :: LocalBuildInfo -> FilePath
55elm lbi = buildDir lbi </> "elm" </> "elm"
40elm lbi = buildDir lbi </> "elm" </> "elm"
@@ -65,63 +50,47 @@ main :: IO ()
65main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
50main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
66
51
67
52
68−-- Build
69−
70−-- note(1): We use to include docs.json directly into LoadLibraries at compile time
71−-- If docs.json is used in other (template) haskell files, they should be copied
72−-- and compiled in a separate directory (eg, dist/copiedSrc).
73−-- This is to make sure they are re-compiled on docs.json changes.
74−-- Copying is a better solution than 'touch'ing the source files
75−-- (touch is non-portable and confusing wrt RCS).
76−
77−-- In the PackageDescription, the list of stuff to build is held in library
78−-- (in a Maybe) and the executables list. We want a PackageDescription that
79−-- only mentions the executable 'name'
80−filterExe :: String -> PackageDescription -> PackageDescription
81−filterExe name pd = pd {
82− library = Nothing,
83− executables = filter (\x -> (exeName x == name)) (executables pd)
84− }
85−
86
53
87-- Post Build
54-- Post Build
88
55
89myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
56myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
90−myPostBuild as bfs pd lbi = do
57+myPostBuild args flags packageDescription lbi = do
91 putStrLn "Custom build step: compiling standard libraries"
58 putStrLn "Custom build step: compiling standard libraries"
92 (elmos, elmis) <- compileLibraries lbi
59 (elmos, elmis) <- compileLibraries lbi
93 putStrLn "Custom build step: build interfaces.data"
60 putStrLn "Custom build step: build interfaces.data"
94− buildInterfaces lbi elmis
61+ buildInterfaces elmis
95 putStrLn "Custom build step: build elm-runtime.js"
62 putStrLn "Custom build step: build elm-runtime.js"
96− buildRuntime lbi elmos
63+ buildRuntime elmos
97 putStrLn "Custom build step: build docs.json"
64 putStrLn "Custom build step: build docs.json"
98− buildDocs lbi
65+ buildDocs
99− removeDirectoryRecursive (tempDir lbi)
66+ removeDirectoryRecursive tempDir
100 removeDirectoryRecursive ("libraries" </> "docs")
67 removeDirectoryRecursive ("libraries" </> "docs")
101− postBuild simpleUserHooks as bfs pd lbi
68+ postBuild simpleUserHooks args flags packageDescription lbi
102
69
103
70
104compileLibraries lbi = do
71compileLibraries lbi = do
105− let temp = tempDir lbi -- temp
106− rts = rtsDir lbi -- data
107− createDirectoryIfMissing True temp
72+ createDirectoryIfMissing True tempDir
108− createDirectoryIfMissing True rts
73+ createDirectoryIfMissing True assetsDir
109− out_c <- canonicalizePath temp -- temp (root folder)
74+ out_c <- canonicalizePath tempDir -- temp (root folder)
110 elm_c <- canonicalizePath (elm lbi) -- dist/build/elm/elm
75 elm_c <- canonicalizePath (elm lbi) -- dist/build/elm/elm
111 doc_c <- canonicalizePath (document lbi) -- dist/build/elm-doc/elm-doc
76 doc_c <- canonicalizePath (document lbi) -- dist/build/elm-doc/elm-doc
112− rtd_c <- canonicalizePath rts -- data
77+ rtd_c <- canonicalizePath assetsDir -- data
113
78
114 let make file = do
79 let make file = do
115− -- replace 'system' call with 'runProcess' which handles args better
80+ let args =
116− -- and allows env variable "Elm_datadir" which is used by LoadLibraries
81+ [ "--only-js"
117− -- to find docs.json
82+ , "--make"
118− let args = [ "--only-js", "--make", "--no-prelude"
83+ , "--no-prelude"
119− , "--cache-dir="++out_c, "--build-dir="++out_c, file ]
84+ , "--cache-dir=" ++ out_c
85+ , "--build-dir=" ++ out_c
86+ , file
87+ ]
120− arg = Just [("Elm_datadir", rtd_c)]
88+ let arg = Just [("Elm_datadir", rtd_c)]
121 handle <- runProcess elm_c args Nothing arg Nothing Nothing Nothing
89 handle <- runProcess elm_c args Nothing arg Nothing Nothing Nothing
122− exitCode <- waitForProcess handle
90+ _exitCode <- waitForProcess handle
123 return ( out_c </> replaceExtension file "elmo"
91 return ( out_c </> replaceExtension file "elmo"
124− , out_c </> replaceExtension file "elmi")
92+ , out_c </> replaceExtension file "elmi"
93+ )
125
94
126 setCurrentDirectory "libraries"
95 setCurrentDirectory "libraries"
127 paths <- getFiles ".elm" "."
96 paths <- getFiles ".elm" "."
@@ -130,11 +99,10 @@ compileLibraries lbi = do
130 setCurrentDirectory ".."
99 setCurrentDirectory ".."
131 return files
100 return files
132
101
133−buildInterfaces :: LocalBuildInfo -> [FilePath] -> IO ()
102+buildInterfaces :: [FilePath] -> IO ()
134−buildInterfaces lbi elmis = do
103+buildInterfaces elmis = do
135− createDirectoryIfMissing True (rtsDir lbi)
104+ createDirectoryIfMissing True assetsDir
136− let ifaces = interfaces lbi
137− ifaceHandle <- openBinaryFile ifaces WriteMode
105+ ifaceHandle <- openBinaryFile interfaces WriteMode
138 BS.hPut ifaceHandle (Binary.encode (length elmis))
106 BS.hPut ifaceHandle (Binary.encode (length elmis))
139 let append file = do
107 let append file = do
140 handle <- openBinaryFile file ReadMode
108 handle <- openBinaryFile file ReadMode
@@ -144,27 +112,26 @@ buildInterfaces lbi elmis = do
144 mapM_ append elmis
112 mapM_ append elmis
145 hClose ifaceHandle
113 hClose ifaceHandle
146
114
147−buildRuntime :: LocalBuildInfo -> [FilePath] -> IO ()
115+buildRuntime :: [FilePath] -> IO ()
148−buildRuntime lbi elmos = do
116+buildRuntime elmos = do
149− createDirectoryIfMissing True (rtsDir lbi)
117+ createDirectoryIfMissing True assetsDir
150− let rts' = rts lbi
118+ writeFile runtime
151− writeFile rts' "'use strict';\n\
119+ "'use strict';\n\
152− \var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
120+ \var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
153− \var ElmRuntime = {}; ElmRuntime.Render = {};\n"
121+ \var ElmRuntime = {}; ElmRuntime.Render = {};\n"
154− mapM_ (appendTo rts') =<< getFiles ".js" "libraries"
122+ mapM_ (appendTo runtime) =<< getFiles ".js" "libraries"
155− mapM_ (appendTo rts') elmos
123+ mapM_ (appendTo runtime) elmos
156− mapM_ (appendTo rts') =<< getFiles ".js" "runtime"
124+ mapM_ (appendTo runtime) =<< getFiles ".js" "runtime"
157−
125+
158−buildDocs :: LocalBuildInfo -> IO ()
126+buildDocs :: IO ()
159−buildDocs lbi = do
127+buildDocs = do
160− createDirectoryIfMissing True (rtsDir lbi)
128+ createDirectoryIfMissing True assetsDir
161− let docs' = docs lbi
162− writeFile docs' "[\n"
129+ writeFile docs "[\n"
163 json <- getFiles ".json" ("libraries" </> "docs")
130 json <- getFiles ".json" ("libraries" </> "docs")
164− let appends = map (appendTo docs') json
131+ let appends = map (appendTo docs) json
165− addCommas = List.intersperse (appendFile docs' ",\n")
132+ addCommas = List.intersperse (appendFile docs ",\n")
166 sequence_ (addCommas appends)
133 sequence_ (addCommas appends)
167− appendFile docs' "\n]"
134+ appendFile docs "\n]"
168
135
169getFiles ext dir = do
136getFiles ext dir = do
170 contents <- map (dir </>) `fmap` getDirectoryContents dir
137 contents <- map (dir </>) `fmap` getDirectoryContents dir