4import Control.Exception (SomeException, catch)
6import Distribution.Simple
7import Distribution.Simple.BuildPaths (autogenModulesDir)
8import Distribution.Simple.InstallDirs as I
9import Distribution.Simple.LocalBuildInfo as L
10import qualified Distribution.Simple.Setup as S
11import qualified Distribution.Simple.Program as P
12import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, rewriteFile, notice, installOrdinaryFiles)
13import Distribution.Compiler
14import Distribution.PackageDescription
15import Distribution.Text
17import System.Environment
19import System.FilePath ((</>), splitDirectories,isAbsolute)
20import System.Directory
21import qualified System.FilePath.Posix as Px
24-- After Idris is built, we need to check and install the prelude and other libs
26-- -----------------------------------------------------------------------------
29-- make on mingw32 exepects unix style separators
32idrisCmd local = Px.joinPath $ splitDirectories $ ".." <//> ".." <//> buildDir local <//> "idris" <//> "idris"
34idrisCmd local = ".." </> ".." </> buildDir local </> "idris" </> "idris"
37-- -----------------------------------------------------------------------------
40-- use GNU make on FreeBSD
41#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS)\
42 || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS)
48 P.runProgramInvocation verbosity . P.simpleProgramInvocation mymake
51windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation "windres"
53-- -----------------------------------------------------------------------------
56usesGMP :: S.ConfigFlags -> Bool
58 case lookup (FlagName "gmp") (S.configConfigurationsFlags flags) of
63execOnly :: S.ConfigFlags -> Bool
65 case lookup (FlagName "execonly") (S.configConfigurationsFlags flags) of
70isRelease :: S.ConfigFlags -> Bool
72 case lookup (FlagName "release") (S.configConfigurationsFlags flags) of
77isFreestanding :: S.ConfigFlags -> Bool
79 case lookup (FlagName "freestanding") (S.configConfigurationsFlags flags) of
83-- -----------------------------------------------------------------------------
86idrisClean _ flags _ _ = cleanStdLib
88 verbosity = S.fromFlag $ S.cleanVerbosity flags
90 cleanStdLib = makeClean "libs"
92 makeClean dir = make verbosity [ "-C", dir, "clean", "IDRIS=idris" ]
95-- -----------------------------------------------------------------------------
99gitHash = do h <- Control.Exception.catch (readProcess "git" ["rev-parse", "--short", "HEAD"] "")
100 (\e -> let e' = (e :: SomeException) in return "PRE")
101 return $ takeWhile (/= '\n') h
103-- Put the Git hash into a module for use in the program
104-- For release builds, just put the empty string in the module
105generateVersionModule verbosity dir release = do
107 let versionModulePath = dir </> "Version_idris" Px.<.> "hs"
108 putStrLn $ "Generating " ++ versionModulePath ++
109 if release then " for release" else " for prerelease " ++ hash
110 createDirectoryIfMissingVerbose verbosity True dir
111 rewriteFile versionModulePath (versionModuleContents hash)
113 where versionModuleContents h = "module Version_idris where\n\n" ++
114 "gitHash :: String\n" ++
116 then "gitHash = \"\"\n"
117 else "gitHash = \"git:" ++ h ++ "\"\n"
119-- Generate a module that contains the lib path for a freestanding Idris
120generateTargetModule verbosity dir targetDir = do
121 let absPath = isAbsolute targetDir
122 let targetModulePath = dir </> "Target_idris" Px.<.> "hs"
123 putStrLn $ "Generating " ++ targetModulePath
124 createDirectoryIfMissingVerbose verbosity True dir
125 rewriteFile targetModulePath (versionModuleContents absPath targetDir)
126 where versionModuleContents absolute td = "module Target_idris where\n\n" ++
127 "import System.FilePath\n" ++
128 "import System.Environment\n" ++
129 "getDataDir :: IO String\n" ++
131 then "getDataDir = return \"" ++ td ++ "\"\n"
132 else "getDataDir = do \n" ++
133 " expath <- getExecutablePath\n" ++
134 " execDir <- return $ dropFileName expath\n" ++
135 " return $ execDir ++ \"" ++ td ++ "\"\n"
136 ++ "getDataFileName :: FilePath -> IO FilePath\n"
137 ++ "getDataFileName name = do\n"
138 ++ " dir <- getDataDir\n"
139 ++ " return (dir ++ \"/\" ++ name)"
141-- a module that has info about existence and location of a bundled toolchain
142generateToolchainModule verbosity srcDir toolDir = do
143 let commonContent = "module Tools_idris where\n\n"
144 let toolContent = case toolDir of
145 Just dir -> "hasBundledToolchain = True\n" ++
146 "getToolchainDir = \"" ++ dir ++ "\"\n"
147 Nothing -> "hasBundledToolchain = False\n" ++
148 "getToolchainDir = \"\""
149 let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
150 createDirectoryIfMissingVerbose verbosity True srcDir
151 rewriteFile toolPath (commonContent ++ toolContent)
153idrisConfigure _ flags _ local = do
155 generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local))
156 if isFreestanding $ configFlags local
158 toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
159 generateToolchainModule verbosity (autogenModulesDir local) toolDir
160 targetDir <- lookupEnv "IDRIS_LIB_DIR"
162 Just d -> generateTargetModule verbosity (autogenModulesDir local) d
163 Nothing -> error $ "Trying to build freestanding without a target directory."
164 ++ " Set it by defining IDRIS_LIB_DIR."
166 generateToolchainModule verbosity (autogenModulesDir local) Nothing
168 verbosity = S.fromFlag $ S.configVerbosity flags
169 version = pkgVersion . package $ localPkgDescr local
171 -- This is a hack. I don't know how to tell cabal that a data file needs
172 -- installing but shouldn't be in the distribution. And it won't make the
173 -- distribution if it's not there, so instead I just delete
174 -- the file after configure.
175 configureRTS = make verbosity ["-C", "rts", "clean"]
177idrisPreSDist args flags = do
178 let dir = S.fromFlag (S.sDistDirectory flags)
179 let verb = S.fromFlag (S.sDistVerbosity flags)
180 generateVersionModule verb "src" True
181 generateTargetModule verb "src" "./libs"
182 generateToolchainModule verb "src" Nothing
183 preSDist simpleUserHooks args flags
185idrisPostSDist args flags desc lbi = do
186 Control.Exception.catch (do let file = "src" </> "Version_idris" Px.<.> "hs"
187 let targetFile = "src" </> "Target_idris" Px.<.> "hs"
188 putStrLn $ "Removing generated modules:\n "
189 ++ file ++ "\n" ++ targetFile
191 removeFile targetFile)
192 (\e -> let e' = (e :: SomeException) in return ())
193 postSDist simpleUserHooks args flags desc lbi
195-- -----------------------------------------------------------------------------
198getVersion :: Args -> S.BuildFlags -> IO HookedBuildInfo
199getVersion args flags = do
201 let buildinfo = (emptyBuildInfo { cppOptions = ["-DVERSION="++hash] }) :: BuildInfo
202 return (Just buildinfo, [])
206idrisPreBuild args flags = do
207#ifdef mingw32_HOST_OS
208 createDirectoryIfMissingVerbose verbosity True dir
209 windres verbosity ["icons/idris_icon.rc","-o", dir++"idris_icon.o"]
210 return (Nothing, [("idris", emptyBuildInfo { ldOptions = [dir ++ "idris_icon.o"] })])
212 verbosity = S.fromFlag $ S.buildVerbosity flags
213 dir = S.fromFlagOrDefault "dist" $ S.buildDistPref flags
218idrisBuild _ flags _ local = unless (execOnly (configFlags local)) $ do
222 verbosity = S.fromFlag $ S.buildVerbosity flags
225 putStrLn "Building libraries..."
228 makeBuild dir = make verbosity [ "-C", dir, "build" , "IDRIS=" ++ idrisCmd local]
230 buildRTS = make verbosity (["-C", "rts", "build"] ++
231 gmpflag (usesGMP (configFlags local)))
234 gmpflag True = ["GMP=-DIDRIS_GMP"]
238-- -----------------------------------------------------------------------------
241idrisInstall verbosity copy pkg local = unless (execOnly (configFlags local)) $ do
246 target = datadir $ L.absoluteInstallDirs pkg local copy
249 putStrLn $ "Installing libraries in " ++ target
250 makeInstall "libs" target
253 let target' = target </> "rts"
254 putStrLn $ "Installing run time system in " ++ target'
255 makeInstall "rts" target'
258 let mandest = mandir (L.absoluteInstallDirs pkg local copy) ++ "/man1"
259 notice verbosity $ unwords ["Copying man page to", mandest]
260 installOrdinaryFiles verbosity mandest [("man", "idris.1")]
263 makeInstall src target =
264 make verbosity [ "-C", src, "install" , "TARGET=" ++ target, "IDRIS=" ++ idrisCmd local]
266-- -----------------------------------------------------------------------------
269-- Install libraries during both copy and install
270-- See https://github.com/haskell/cabal/issues/709
271main = defaultMainWithHooks $ simpleUserHooks
272 { postClean = idrisClean
273 , postConf = idrisConfigure
274 , preBuild = idrisPreBuild
275 , postBuild = idrisBuild
276 , postCopy = \_ flags pkg local ->
277 idrisInstall (S.fromFlag $ S.copyVerbosity flags)
278 (S.fromFlag $ S.copyDest flags) pkg local
279 , postInst = \_ flags pkg local ->
280 idrisInstall (S.fromFlag $ S.installVerbosity flags)
282 , preSDist = idrisPreSDist
283 , postSDist = idrisPostSDist
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