1import Distribution.Simple
2import Distribution.Simple.LocalBuildInfo
3import Distribution.Simple.Setup
4import Distribution.PackageDescription
13import qualified Data.Binary as Binary
18-- We need to build elm-doc and run it because that generates the file "docs.json"
19-- needs by Libraries.hs which is part of the elm library and executable
20-- Unfort. there seems to be no way to tell cabal that:
21-- (a) elm-doc generates docs.json, and
22-- (b) elm (library) depends on docs.json
23-- Therefore, we either use make instead (or a script), or hack around in cabal
27-- Add a post-build callout.
28-- We need to build the runtime.js after we've built elm (because we use elm to generate some of the JavaScript),
29-- but before cabal does the install file copy step
32-- Elm.cabal expects the generated files to end up in dist/data
33-- git won't look in dist + cabal will clean it
34rtsDir :: LocalBuildInfo -> FilePath
35rtsDir lbi = buildDir lbi </> ".." </> "data"
37tempDir :: LocalBuildInfo -> FilePath
38tempDir lbi = buildDir lbi </> ".." </> "temp"
40-- The runtime is called:
41rts :: LocalBuildInfo -> FilePath
42rts lbi = rtsDir lbi </> "elm-runtime.js"
44-- The interfaces for the Standard Libraries live in:
45interfaces :: LocalBuildInfo -> FilePath
46interfaces lbi = rtsDir lbi </> "interfaces.data"
48-- buildDir with LocalBuildInfo points to "dist/build" (usually)
49elm lbi = buildDir lbi </> "elm" </> "elm"
51-- Care! This appears to be based on an unstable API
52-- See: http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#2
56main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
61-- note(1): We use to include docs.json directly into LoadLibraries at compile time
62-- If docs.json is used in other (template) haskell files, they should be copied
63-- and compiled in a separate directory (eg, dist/copiedSrc).
64-- This is to make sure they are re-compiled on docs.json changes.
65-- Copying is a better solution than 'touch'ing the source files
66-- (touch is non-portable and confusing wrt RCS).
68-- In the PackageDescription, the list of stuff to build is held in library
69-- (in a Maybe) and the executables list. We want a PackageDescription that
70-- only mentions the executable 'name'
71filterExe :: String -> PackageDescription -> PackageDescription
72filterExe name pd = pd {
74 executables = filter (\x -> (exeName x == name)) (executables pd)
77-- It's not enough to fix the PackageDescription, we also have to fix the
78-- LocalBuildInfo. This includes the component build order (data ComponentName)
79-- which is horribly internal.
80filterLBI :: String -> LocalBuildInfo -> LocalBuildInfo
81filterLBI name lbi = lbi {
82 libraryConfig = Nothing,
83 compBuildOrder = [CExeName name],
84 executableConfigs = filter (\a -> (fst a == name)) (executableConfigs lbi)
90myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
91myPostBuild as bfs pd lbi = do
92 putStrLn "Custom build step: compiling standard libraries"
93 (elmos, elmis) <- compileLibraries lbi
94 putStrLn "Custom build step: build interfaces.data"
95 buildInterfaces lbi elmis
96 putStrLn "Custom build step: build elm-runtime.js"
97 buildRuntime lbi elmos
98 removeDirectoryRecursive ("dist" </> "temp")
99 postBuild simpleUserHooks as bfs pd lbi
102compileLibraries lbi = do
103 let temp = tempDir lbi -- dist/temp
104 createDirectoryIfMissing True temp
105 out_c <- canonicalizePath temp -- dist/temp (root folder)
106 elm_c <- canonicalizePath (elm lbi) -- dist/build/elm/elm
107 rtd_c <- canonicalizePath (rtsDir lbi) -- dist/data (for docs.json)
110 -- replace 'system' call with 'runProcess' which handles args better
111 -- and allows env variable "Elm_datadir" which is used by LoadLibraries
113 let args = ["--only-js","--make","--no-prelude","--output-directory="++out_c,file]
114 arg = Just [("Elm_datadir", rtd_c)]
115 handle <- runProcess elm_c args Nothing arg Nothing Nothing Nothing
116 exitCode <- waitForProcess handle
117 return ( out_c </> replaceExtension file "elmo"
118 , out_c </> replaceExtension file "elmi")
120 setCurrentDirectory "libraries"
121 print =<< getCurrentDirectory
122 files <- getFiles ".elm" "."
123 files <- unzip `fmap` mapM make files
124 setCurrentDirectory ".."
127buildInterfaces :: LocalBuildInfo -> [FilePath] -> IO ()
128buildInterfaces lbi elmis = do
129 createDirectoryIfMissing True (rtsDir lbi)
130 let ifaces = interfaces lbi
131 Binary.encodeFile ifaces (length elmis)
132 mapM_ (\elmi -> readFile elmi >>= appendFile ifaces) elmis
134buildRuntime :: LocalBuildInfo -> [FilePath] -> IO ()
135buildRuntime lbi elmos = do
136 createDirectoryIfMissing True (rtsDir lbi)
137 writeFile (rts lbi) "Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
138 \Elm.Graphics = {}; ElmRuntime = {}; ElmRuntime.Render = {};\n"
139 mapM_ (appendJS lbi) =<< getFiles ".js" "libraries"
140 mapM_ (appendJS lbi) elmos
141 mapM_ (appendJS lbi) =<< getFiles ".js" "runtime"
144 contents <- map (dir </>) `fmap` getDirectoryContents dir
145 let files = filter (\f -> takeExtension f == ext) contents
146 dirs = filter (not . hasExtension) contents
147 filess <- mapM (getFiles ext) dirs
148 return (files ++ concat filess)
150appendJS lbi file = do
151 putStrLn (dropExtension file)
153 length str `seq` return ()
154 appendFile (rts lbi) str
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list