3#if !defined(MIN_VERSION_Cabal)
4# define MIN_VERSION_Cabal(x,y,z) 0
9import Control.Exception (SomeException, catch)
11import Distribution.Simple
12import Distribution.Simple.BuildPaths
13import Distribution.Simple.InstallDirs as I
14import Distribution.Simple.LocalBuildInfo as L
15import qualified Distribution.Simple.Setup as S
16import qualified Distribution.Simple.Program as P
17import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, rewriteFile, notice, installOrdinaryFiles)
18import Distribution.Compiler
19import Distribution.PackageDescription
20import Distribution.Text
22import System.Environment
24import System.FilePath ((</>), splitDirectories,isAbsolute)
25import System.Directory
26import qualified System.FilePath.Posix as Px
29#if (MIN_VERSION_Cabal(2,0,0))
30import Distribution.Types.UnqualComponentName
34-- After Idris is built, we need to check and install the prelude and other libs
36-- -----------------------------------------------------------------------------
39-- make on mingw32 exepects unix style separators
42idrisCmd local = Px.joinPath $ splitDirectories $ ".." <//> ".." <//> buildDir local <//> "idris" <//> "idris"
44idrisCmd local = ".." </> ".." </> buildDir local </> "idris" </> "idris"
47-- -----------------------------------------------------------------------------
50-- use GNU make on FreeBSD
51#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS)\
52 || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS)
58 P.runProgramInvocation verbosity . P.simpleProgramInvocation mymake
61windres verbosity = P.runProgramInvocation verbosity . P.simpleProgramInvocation "windres"
63-- -----------------------------------------------------------------------------
66usesGMP :: S.ConfigFlags -> Bool
68 case lookup (mkFlagName "gmp") (S.configConfigurationsFlags flags) of
73execOnly :: S.ConfigFlags -> Bool
75 case lookup (mkFlagName "execonly") (S.configConfigurationsFlags flags) of
80isRelease :: S.ConfigFlags -> Bool
82 case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
87isFreestanding :: S.ConfigFlags -> Bool
89 case lookup (mkFlagName "freestanding") (S.configConfigurationsFlags flags) of
94#if !(MIN_VERSION_Cabal(2,0,0))
95mkFlagName :: String -> FlagName
99-- -----------------------------------------------------------------------------
102idrisClean _ flags _ _ = cleanStdLib
104 verbosity = S.fromFlag $ S.cleanVerbosity flags
106 cleanStdLib = makeClean "libs"
108 makeClean dir = make verbosity [ "-C", dir, "clean", "IDRIS=idris" ]
110-- -----------------------------------------------------------------------------
114gitHash = do h <- Control.Exception.catch (readProcess "git" ["rev-parse", "--short", "HEAD"] "")
115 (\e -> let e' = (e :: SomeException) in return "PRE")
116 return $ takeWhile (/= '\n') h
118-- Put the Git hash into a module for use in the program
119-- For release builds, just put the empty string in the module
120generateVersionModule verbosity dir release = do
122 let versionModulePath = dir </> "Version_idris" Px.<.> "hs"
123 putStrLn $ "Generating " ++ versionModulePath ++
124 if release then " for release" else " for prerelease " ++ hash
125 createDirectoryIfMissingVerbose verbosity True dir
126 rewriteFile versionModulePath (versionModuleContents hash)
128 where versionModuleContents h = "module Version_idris where\n\n" ++
129 "gitHash :: String\n" ++
131 then "gitHash = \"\"\n"
132 else "gitHash = \"git:" ++ h ++ "\"\n"
134-- Generate a module that contains the lib path for a freestanding Idris
135generateTargetModule verbosity dir targetDir = do
136 let absPath = isAbsolute targetDir
137 let targetModulePath = dir </> "Target_idris" Px.<.> "hs"
138 putStrLn $ "Generating " ++ targetModulePath
139 createDirectoryIfMissingVerbose verbosity True dir
140 rewriteFile targetModulePath (versionModuleContents absPath targetDir)
141 where versionModuleContents absolute td = "module Target_idris where\n\n" ++
142 "import System.FilePath\n" ++
143 "import System.Environment\n" ++
144 "getDataDir :: IO String\n" ++
146 then "getDataDir = return \"" ++ td ++ "\"\n"
147 else "getDataDir = do \n" ++
148 " expath <- getExecutablePath\n" ++
149 " execDir <- return $ dropFileName expath\n" ++
150 " return $ execDir ++ \"" ++ td ++ "\"\n"
151 ++ "getDataFileName :: FilePath -> IO FilePath\n"
152 ++ "getDataFileName name = do\n"
153 ++ " dir <- getDataDir\n"
154 ++ " return (dir ++ \"/\" ++ name)"
156-- a module that has info about existence and location of a bundled toolchain
157generateToolchainModule verbosity srcDir toolDir = do
158 let commonContent = "module Tools_idris where\n\n"
159 let toolContent = case toolDir of
160 Just dir -> "hasBundledToolchain = True\n" ++
161 "getToolchainDir = \"" ++ dir ++ "\"\n"
162 Nothing -> "hasBundledToolchain = False\n" ++
163 "getToolchainDir = \"\""
164 let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
165 createDirectoryIfMissingVerbose verbosity True srcDir
166 rewriteFile toolPath (commonContent ++ toolContent)
168idrisConfigure _ flags pkgdesc local = do
170 withLibLBI pkgdesc local $ \_ libcfg -> do
171 let libAutogenDir = autogenComponentModulesDir local libcfg
172 generateVersionModule verbosity libAutogenDir (isRelease (configFlags local))
173 if isFreestanding $ configFlags local
175 toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
176 generateToolchainModule verbosity libAutogenDir toolDir
177 targetDir <- lookupEnv "IDRIS_LIB_DIR"
179 Just d -> generateTargetModule verbosity libAutogenDir d
180 Nothing -> error $ "Trying to build freestanding without a target directory."
181 ++ " Set it by defining IDRIS_LIB_DIR."
183 generateToolchainModule verbosity libAutogenDir Nothing
185 verbosity = S.fromFlag $ S.configVerbosity flags
186 version = pkgVersion . package $ localPkgDescr local
188 -- This is a hack. I don't know how to tell cabal that a data file needs
189 -- installing but shouldn't be in the distribution. And it won't make the
190 -- distribution if it's not there, so instead I just delete
191 -- the file after configure.
192 configureRTS = make verbosity ["-C", "rts", "clean"]
194#if !(MIN_VERSION_Cabal(2,0,0))
195 autogenComponentModulesDir lbi _ = autogenModulesDir lbi
198idrisPreSDist args flags = do
199 let dir = S.fromFlag (S.sDistDirectory flags)
200 let verb = S.fromFlag (S.sDistVerbosity flags)
201 generateVersionModule verb "src" True
202 generateTargetModule verb "src" "./libs"
203 generateToolchainModule verb "src" Nothing
204 preSDist simpleUserHooks args flags
206idrisSDist sdist pkgDesc bi hooks flags = do
207 pkgDesc' <- addGitFiles pkgDesc
208 sdist pkgDesc' bi hooks flags
210 addGitFiles :: PackageDescription -> IO PackageDescription
211 addGitFiles pkgDesc = do
213 return $ pkgDesc { extraSrcFiles = extraSrcFiles pkgDesc ++ files}
214 gitFiles :: IO [FilePath]
215 gitFiles = liftM lines (readProcess "git" ["ls-files"] "")
217idrisPostSDist args flags desc lbi = do
218 Control.Exception.catch (do let file = "src" </> "Version_idris" Px.<.> "hs"
219 let targetFile = "src" </> "Target_idris" Px.<.> "hs"
220 putStrLn $ "Removing generated modules:\n "
221 ++ file ++ "\n" ++ targetFile
223 removeFile targetFile)
224 (\e -> let e' = (e :: SomeException) in return ())
225 postSDist simpleUserHooks args flags desc lbi
227-- -----------------------------------------------------------------------------
230getVersion :: Args -> S.BuildFlags -> IO HookedBuildInfo
231getVersion args flags = do
233 let buildinfo = (emptyBuildInfo { cppOptions = ["-DVERSION="++hash] }) :: BuildInfo
234 return (Just buildinfo, [])
237#if !(MIN_VERSION_Cabal(2,0,0))
238mkUnqualComponentName = id
241idrisPreBuild args flags = do
242#ifdef mingw32_HOST_OS
243 createDirectoryIfMissingVerbose verbosity True dir
244 windres verbosity ["icons/idris_icon.rc","-o", dir++"/idris_icon.o"]
245 return (Nothing, [(mkUnqualComponentName "idris", emptyBuildInfo { ldOptions = [dir ++ "/idris_icon.o"] })])
247 verbosity = S.fromFlag $ S.buildVerbosity flags
248 dir = S.fromFlagOrDefault "dist" $ S.buildDistPref flags
253idrisBuild _ flags _ local
254 = if (execOnly (configFlags local)) then buildRTS
258 verbosity = S.fromFlag $ S.buildVerbosity flags
261 putStrLn "Building libraries..."
264 makeBuild dir = make verbosity [ "-C", dir, "build" , "IDRIS=" ++ idrisCmd local]
266 buildRTS = make verbosity (["-C", "rts", "build"] ++
267 gmpflag (usesGMP (configFlags local)))
270 gmpflag True = ["GMP=-DIDRIS_GMP"]
272-- -----------------------------------------------------------------------------
275idrisInstall verbosity copy pkg local
276 = if (execOnly (configFlags local)) then installRTS
277 else do installStdLib
281 target = datadir $ L.absoluteInstallDirs pkg local copy
284 let target' = target -- </> "libs"
285 putStrLn $ "Installing libraries in " ++ target'
286 makeInstall "libs" target'
289 let target' = target </> "rts"
290 putStrLn $ "Installing run time system in " ++ target'
291 makeInstall "rts" target'
294 let mandest = mandir (L.absoluteInstallDirs pkg local copy) ++ "/man1"
295 notice verbosity $ unwords ["Copying man page to", mandest]
296 installOrdinaryFiles verbosity mandest [("man", "idris.1")]
298 makeInstall src target =
299 make verbosity [ "-C", src, "install" , "TARGET=" ++ target, "IDRIS=" ++ idrisCmd local]
301-- -----------------------------------------------------------------------------
304-- There are two "dataDir" in cabal, and they don't relate to each other.
305-- When fetching modules, idris uses the second path (in the pkg record),
306-- which by default is the root folder of the project.
307-- We want it to be the install directory where we put the idris libraries.
308fixPkg pkg target = pkg { dataDir = target }
310idrisTestHook args pkg local hooks flags = do
311 let target = datadir $ L.absoluteInstallDirs pkg local NoCopyDest
312 testHook simpleUserHooks args (fixPkg pkg target) local hooks flags
314-- -----------------------------------------------------------------------------
317-- Install libraries during both copy and install
318-- See https://github.com/haskell/cabal/issues/709
319main = defaultMainWithHooks $ simpleUserHooks
320 { postClean = idrisClean
321 , postConf = idrisConfigure
322 , preBuild = idrisPreBuild
323 , postBuild = idrisBuild
324 , postCopy = \_ flags pkg local ->
325 idrisInstall (S.fromFlag $ S.copyVerbosity flags)
326 (S.fromFlag $ S.copyDest flags) pkg local
327 , postInst = \_ flags pkg local ->
328 idrisInstall (S.fromFlag $ S.installVerbosity flags)
330 , preSDist = idrisPreSDist
331 , sDistHook = idrisSDist (sDistHook simpleUserHooks)
332 , postSDist = idrisPostSDist
333 , testHook = idrisTestHook
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