on master help sign in
Merge pull request #122 from ngunn/dev

Dev (fix cabal install as per issue 120)

commit29153a88fd45a5c727c74041ebe2bbdad6198416 authorEvan Czaplicki <info@elm-lang.org> dateThu 21 Mar 2013, 11:21 (14 years ago) parent82a5a6514e32ad
4 files changed+117−38
Elm.cabal+4 Setup.hs+88−27 compiler/Docs.hs+3−3 compiler/Model/LoadLibraries.hs+22−8
Elm.cabal+4
@@ -33,6 +33,8 @@ Library
3333 exposed-modules: Language.Elm,
3434 Language.Elm.Quasi
3535 Hs-Source-Dirs: compiler, compiler/Gen, compiler/Model, compiler/Transform
36+ extensions: CPP
37+ cpp-options: -DELM_COMPILEDATADIR="dist/data"
3638 other-modules: Ast,
3739 Context,
3840 CompileToJS,
@@ -87,6 +89,8 @@ Library
8789Executable elm
8890 Main-is: Compiler.hs
8991 Hs-Source-Dirs: compiler, compiler/Gen, compiler/Model, compiler/Transform
92+ extensions: CPP
93+ cpp-options: -DELM_COMPILEDATADIR="dist/data"
9094 other-modules: Ast,
9195 Context,
9296 CompileToJS,
Setup.hs+88−27
@@ -8,33 +8,99 @@ import System.Directory
88import System.FilePath
99import System.IO
1010
11+import Control.Monad
12+
13+-- Part 1
14+-- ------
15+-- Add a build callout
16+-- We need to build elm-doc and run it because that generates the file "docs.json" needs by Libraries.hs
17+-- which is part of the elm library and executable
18+-- Unfort. there seems to be no way to tell cabal that:
19+-- (a) elm-doc generates docs.json, and
20+-- (b) elm (library) depends on docs.json
21+-- Therefore, we either use make instead (or a script), or hack around in cabal
22+
23+-- Part 2
24+-- ------
1125-- Add a post-build callout.
12−-- We need to build the runtime.js after we've built elm,
26+-- We need to build the runtime.js after we've built elm (because we use elm to generate some of the JavaScript),
1327-- but before cabal does the install file copy step
1428
15−main :: IO ()
16−main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
29+-- Assumptions
30+-- Elm.cabal expects the generated files to end up in dist/data
31+rtsDir lbi = (buildDir lbi) </> ".." </> "data" -- git won't look in dist + cabal will clean it
32+
33+-- The runtime is called:
34+rts lbi = (rtsDir lbi) </> "elm-runtime.js"
35+
36+-- The json file is called:
37+
38+-- The elm-docs executable is called:
39+elmDoc = "elm-doc"
40+elm_doc lbi = (buildDir lbi) </> elmDoc </> elmDoc
41+
42+types lbi = (rtsDir lbi) </> "docs.json"
43+
44+-- buildDir with LocalBuildInfo points to "dist/build" (usually)
45+elm lbi = (buildDir lbi) </> "elm" </> "elm"
46+
47+-- "touch" is available as a system command.
48+-- There is no portable file touch (unix-compat might work but leads to cabal library dependency
49+-- issues: see: http://hackage.haskell.org/trac/summer-of-code/ticket/1602 )
50+-- Files that need recompilation after docs.json is updated
51+-- (Would be nice if this list was in the cabal file, but can't see any way to do that)
52+docTouches = ["compiler" </> "Model" </> "LoadLibraries.hs"]
1753
1854-- Care! This appears to be based on an unstable API
1955-- See: http://www.haskell.org/cabal/release/cabal-latest/doc/API/Cabal/Distribution-Simple.html#2
2056
21−myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
22−myPostBuild as bfs pd lbi = do
23− putStrLn "Custom build step started"
24− buildRuntime lbi
57+
58+main :: IO ()
59+main = defaultMainWithHooks simpleUserHooks { buildHook = myBuild, postBuild = myPostBuild }
60+
61+
62+-- Build
63+
64+myBuild :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
65+myBuild pd lbi uh bf = do
66+ putStrLn $ "Custom build step started: compile " ++ elmDoc
67+ withExe pd (\x -> putStrLn (exeName x))
68+ buildHook simpleUserHooks (filterExe elmDoc pd) (filterLBI elmDoc lbi) uh bf
69+ putStrLn "Custom build step started: build docs.json"
2570 buildTypes lbi
26− postBuild simpleUserHooks as bfs pd lbi
71+ forM_ docTouches (\s -> system ("touch " ++ s)) -- NB non-portable
72+ putStrLn "Custom build step started: compile everything"
73+ buildHook simpleUserHooks pd lbi uh bf
2774
28−-- put js file in dist folder so git doesn't notice
29−rtsDir = "dist" </> "data"
75+-- In the PackageDescription, the list of stuff to build is held in library (in a Maybe)
76+-- and the executables list. We want a PackageDescription that only mentions the executable 'name'
77+filterExe name pd = pd {
78+ library = Nothing,
79+ executables = filter (\x -> (exeName x == name)) (executables pd)
80+ }
3081
31−rts = rtsDir </> "elm-runtime.js"
32−types = rtsDir </> "docs.json"
82+-- It's not enough to fix the PackageDescription, we also have to fix the LocalBuildInfo.
83+-- This includes the component build order (data ComponentName) which is horribly internal.
84+filterLBI name lbi = lbi {
85+ libraryConfig = Nothing,
86+ compBuildOrder = [CExeName name],
87+ executableConfigs = filter (\a -> (fst a == name)) (executableConfigs lbi)
88+ }
89+
90+buildTypes lbi = do
91+ createDirectoryIfMissing False (rtsDir lbi) -- dist should already exist
92+ files <- getFiles ".elm" "libraries"
93+ system (elm_doc lbi ++ " " ++ unwords files ++ " > " ++ (types lbi))
94+ putStrLn $ "Custom build step completed: " ++ elmDoc
3395
34−-- buildDir with LocalBuildInfo points to "dist/build" (usually)
35−elm lbi = (buildDir lbi) </> "elm" </> "elm"
36−elm_doc lbi = (buildDir lbi) </> "elm-doc" </> "elm-doc"
3796
97+-- Post Build
98+
99+myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
100+myPostBuild as bfs pd lbi = do
101+ putStrLn "Custom post build step started: build elm-runtime.js"
102+ buildRuntime lbi
103+ postBuild simpleUserHooks as bfs pd lbi
38104
39105getFiles ext dir = do
40106 contents <- map (dir </>) `fmap` getDirectoryContents dir
@@ -43,30 +109,25 @@ getFiles ext dir = do
43109 filess <- mapM (getFiles ext) dirs
44110 return (files ++ concat filess)
45111
46−appendJS file = do
112+appendJS lbi file = do
47113 putStrLn (dropExtension file)
48114 str <- readFile file
49115 length str `seq` return ()
50− appendFile rts str
116+ appendFile (rts lbi) str
51117
52118appendElm lbi file = do
53119 system (elm lbi ++ " --only-js " ++ file)
54120 let jsFile = replaceExtension file ".js"
55− appendJS jsFile
121+ appendJS lbi jsFile
56122 removeFile jsFile
57123
58124buildRuntime lbi = do
59− createDirectoryIfMissing False rtsDir -- dist should already exist
60− writeFile rts "Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
125+ createDirectoryIfMissing False (rtsDir lbi) -- dist should already exist
126+ writeFile (rts lbi) "Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
61127 \Elm.Graphics = {}; ElmRuntime = {}; ElmRuntime.Render = {}\n"
62− mapM_ appendJS =<< getFiles ".js" "libraries"
128+ mapM_ (appendJS lbi) =<< getFiles ".js" "libraries"
63129 mapM_ (appendElm lbi) =<< getFiles ".elm" "libraries"
64− mapM_ appendJS =<< getFiles ".js" "runtime"
130+ mapM_ (appendJS lbi) =<< getFiles ".js" "runtime"
65131 putStrLn "\n+------------------------------------------+\
66132 \\n| Success building runtime and libraries! |\
67133 \\n+------------------------------------------+\n"
68−
69−buildTypes lbi = do
70− files <- getFiles ".elm" "libraries"
71− system (elm_doc lbi ++ " " ++ unwords files ++ " > " ++ types)
72− putStrLn "Custom build step completed: elm-doc"
compiler/Docs.hs+3−3
@@ -30,18 +30,18 @@ toModule (name, values) =
3030toValue (name, tipe, desc) =
3131 "{ \"name\" : " ++ show name ++
3232 ",\n \"type\" : \"" ++ show tipe ++
33− ",\n \"desc\" : " ++ show desc ++ "\n }"
33+ "\",\n \"desc\" : " ++ show desc ++ "\n }"
3434
3535docParse :: String -> Either String (String, [(String, Type, String)])
3636docParse = setupParser $ do
3737 optional freshLine
3838 (,) <$> option "Main" moduleName <*> types
39− where
39+ where
4040 skip = manyTill anyChar simpleNewline >> return []
4141 end = many1 anyChar >> return []
4242 types = concat <$> many (docs <|> try skip <|> end)
4343 getName = intercalate "." . fst
44− moduleName = do optional freshLine
44+ moduleName = do optional freshLine
4545 getName <$> moduleDef `followedBy` freshLine
4646
4747docs :: IParser [(String, Type, String)]
compiler/Model/LoadLibraries.hs+22−8
@@ -1,22 +1,36 @@
1+{-# LANGUAGE CPP #-}
12
23module LoadLibraries (docs) where
34
45import Language.Haskell.TH.Syntax
56import Paths_Elm
67import System.Directory
8+import System.FilePath
79
810docs :: Q Exp
9−docs = liftString =<< qRunIO readDocs
11+docs = liftString =<< qRunIO (readDocs dataDir)
1012
11−readDocs :: IO String
12−readDocs = do
13− name <- getDataFileName "docs.json"
13+-- When compiling elm (library and executable), docs.json isn't (yet) in the standard location
14+-- Therefore, Elm.cabal overrides the location.
15+-- Since this is only used by the TemplateHaskell, which reads the file at compile time,
16+-- this should be ok.
17+
18+dataDir :: IO FilePath
19+#if defined ELM_COMPILEDATADIR
20+dataDir = canonicalizePath (ELM_COMPILEDATADIR </> "docs.json")
21+#else
22+dataDir = getDataFileName "docs.json"
23+#endif
24+
25+readDocs :: IO FilePath -> IO String
26+readDocs path = do
27+ name <- path
1428 exists <- doesFileExist name
1529 if exists then readFile name
1630 else putStrLn warning >> return "{\"modules\":[]}"
1731
1832warning = "Warning! Types for standard library not loaded properly!\n\
19− \Run the following commands after compilation:\n\
20− \\n\
21− \ touch compiler/Model/LoadLibraries.hs\n\
22− \ cabal install\n\n"
33+ Run the following commands after compilation:\n\
34+ \n\
35+ touch compiler/Model/LoadLibraries.hs\n\
36+ cabal install\n\n"