on master help sign in
Merge pull request #2079 from melted/toolchain
2e919c8David Christiansen
CHANGELOG+1
@@ -1,5 +1,6 @@
1New in 0.9.18:
1New in 0.9.18:
2--------------
2--------------
3+* Add support for bundled toolchains.
3* Strings are now UTF8 encoded in the default back end
4* Strings are now UTF8 encoded in the default back end
4* Idris source files are now assumed to be in UTF8, regardless of locale
5* Idris source files are now assumed to be in UTF8, regardless of locale
5 settings.
6 settings.
Setup.hs+23−6
@@ -137,17 +137,33 @@ generateTargetModule verbosity dir targetDir = do
137 ++ " dir <- getDataDir\n"
137 ++ " dir <- getDataDir\n"
138 ++ " return (dir ++ \"/\" ++ name)"
138 ++ " return (dir ++ \"/\" ++ name)"
139
139
140+-- a module that has info about existence and location of a bundled toolchain
141+generateToolchainModule verbosity srcDir toolDir = do
142+ let commonContent = "module Tools_idris where\n\n"
143+ let toolContent = case toolDir of
144+ Just dir -> "hasBundledToolchain = True\n" ++
145+ "getToolchainDir = \"" ++ dir ++ "\"\n"
146+ Nothing -> "hasBundledToolchain = False\n" ++
147+ "getToolchainDir = \"\""
148+ let toolPath = srcDir </> "Tools_idris" Px.<.> "hs"
149+ createDirectoryIfMissingVerbose verbosity True srcDir
150+ rewriteFile toolPath (commonContent ++ toolContent)
140
151
141idrisConfigure _ flags _ local = do
152idrisConfigure _ flags _ local = do
142− configureRTS
153+ configureRTS
143− generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local))
154+ generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local))
144− when (isFreestanding $ configFlags local) (do
155+ if (isFreestanding $ configFlags local)
156+ then (do
157+ toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR"
158+ generateToolchainModule verbosity (autogenModulesDir local) toolDir
145− targetDir <- lookupEnv "IDRIS_INSTALL_DIR"
159+ targetDir <- lookupEnv "IDRIS_LIB_DIR"
146 case targetDir of
160 case targetDir of
147 Just d -> generateTargetModule verbosity (autogenModulesDir local) d
161 Just d -> generateTargetModule verbosity (autogenModulesDir local) d
148 Nothing -> error $ "Trying to build freestanding without a target directory."
162 Nothing -> error $ "Trying to build freestanding without a target directory."
149− ++ " Set it by defining IDRIS_INSTALL_DIR.")
163+ ++ " Set it by defining IDRIS_LIB_DIR.")
164+ else
165+ generateToolchainModule verbosity (autogenModulesDir local) Nothing
150− where
166+ where
151 verbosity = S.fromFlag $ S.configVerbosity flags
167 verbosity = S.fromFlag $ S.configVerbosity flags
152 version = pkgVersion . package $ localPkgDescr local
168 version = pkgVersion . package $ localPkgDescr local
153
169
@@ -162,6 +178,7 @@ idrisPreSDist args flags = do
162 let verb = S.fromFlag (S.sDistVerbosity flags)
178 let verb = S.fromFlag (S.sDistVerbosity flags)
163 generateVersionModule verb ("src") True
179 generateVersionModule verb ("src") True
164 generateTargetModule verb "src" "./libs"
180 generateTargetModule verb "src" "./libs"
181+ generateToolchainModule verb "src" Nothing
165 preSDist simpleUserHooks args flags
182 preSDist simpleUserHooks args flags
166
183
167idrisPostSDist args flags desc lbi = do
184idrisPostSDist args flags desc lbi = do
codegen/idris-c/Main.hs+4−1
@@ -14,6 +14,8 @@ import Control.Monad
14
14
15import Paths_idris
15import Paths_idris
16
16
17+import Util.System
18+
17data Opts = Opts { inputs :: [FilePath],
19data Opts = Opts { inputs :: [FilePath],
18 interface :: Bool,
20 interface :: Bool,
19 output :: FilePath }
21 output :: FilePath }
@@ -31,7 +33,8 @@ getOpts = do xs <- getArgs
31 process opts [] = opts
33 process opts [] = opts
32
34
33c_main :: Opts -> Idris ()
35c_main :: Opts -> Idris ()
36+c_main opts = do runIO setupBundledCC
34−c_main opts = do elabPrims
37+ elabPrims
35 loadInputs (inputs opts) Nothing
38 loadInputs (inputs opts) Nothing
36 mainProg <- if interface opts
39 mainProg <- if interface opts
37 then liftM Just elabMain
40 then liftM Just elabMain
docs/faq/faq.rst+15
@@ -131,6 +131,21 @@ choice by the developers of Idris, Idris uses the C style convention.
131That is, the names ``Float`` and ``Double`` are used to describe
131That is, the names ``Float`` and ``Double`` are used to describe
132single and double precision numbers.
132single and double precision numbers.
133
133
134+What is -ffreestanding?
135+=======================
136+
137+The freestanding flag is used to build Idris binaries which have their
138+libs and compiler in a relative path. This is useful for building binaries
139+where the install directory is unknown at build time. When passing this
140+flag, the IDRIS_LIB_DIR environment variable needs to be set to the path
141+where the Idris libs reside relative to the idris executable. The
142+IDRIS_TOOLCHAIN_DIR environment variable is optional, if that is set,
143+Idris will use that path to find the C compiler.
144+
145+Example:
146+.. code-block::
147+ IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make
148+
134What does the name ‘Idris’ mean?
149What does the name ‘Idris’ mean?
135================================
150================================
136
151
idris.cabal+1
@@ -806,6 +806,7 @@ Library
806 -- Auto Generated
806 -- Auto Generated
807 , Paths_idris
807 , Paths_idris
808 , Version_idris
808 , Version_idris
809+ , Tools_idris
809
810
810 Build-depends: base >=4 && <5
811 Build-depends: base >=4 && <5
811 , annotated-wl-pprint >= 0.5.3 && < 0.6
812 , annotated-wl-pprint >= 0.5.3 && < 0.6
main/Main.hs+2
@@ -29,6 +29,7 @@ import Idris.CmdOptions
29import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )
29import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags )
30
30
31import Util.DynamicLinker
31import Util.DynamicLinker
32+import Util.System
32
33
33import Pkg.Package
34import Pkg.Package
34
35
@@ -43,6 +44,7 @@ main = do opts <- runArgParser
43
44
44runIdris :: [Opt] -> Idris ()
45runIdris :: [Opt] -> Idris ()
45runIdris opts = do
46runIdris opts = do
47+ runIO setupBundledCC
46 when (ShowIncs `elem` opts) $ runIO showIncs
48 when (ShowIncs `elem` opts) $ runIO showIncs
47 when (ShowLibs `elem` opts) $ runIO showLibs
49 when (ShowLibs `elem` opts) $ runIO showLibs
48 when (ShowLibdir `elem` opts) $ runIO showLibdir
50 when (ShowLibdir `elem` opts) $ runIO showLibdir
src/Util/System.hs+30−2
@@ -1,5 +1,6 @@
1+{-# LANGUAGE CPP #-}
1module Util.System(tempfile,withTempdir,rmFile,catchIO, isWindows,
2module Util.System(tempfile,withTempdir,rmFile,catchIO, isWindows,
2− readSource, writeSource) where
3+ writeSource, readSource, setupBundledCC) where
3
4
4-- System helper functions.
5-- System helper functions.
5import Control.Monad (when)
6import Control.Monad (when)
@@ -7,13 +8,19 @@ import System.Directory (getTemporaryDirectory
7 , removeFile
8 , removeFile
8 , removeDirectoryRecursive
9 , removeDirectoryRecursive
9 , createDirectoryIfMissing
10 , createDirectoryIfMissing
11+ , doesDirectoryExist
10 )
12 )
11−import System.FilePath ((</>), normalise)
13+import System.FilePath ((</>), normalise, isAbsolute, dropFileName)
12import System.IO
14import System.IO
13import System.Info
15import System.Info
14import System.IO.Error
16import System.IO.Error
15import Control.Exception as CE
17import Control.Exception as CE
16
18
19+#ifdef FREESTANDING
20+import Tools_idris
21+import System.Environment (getEnv, setEnv, getExecutablePath)
22+#endif
23+
17catchIO :: IO a -> (IOError -> IO a) -> IO a
24catchIO :: IO a -> (IOError -> IO a) -> IO a
18catchIO = CE.catch
25catchIO = CE.catch
19
26
@@ -54,3 +61,24 @@ rmFile f = do putStrLn $ "Removing " ++ f
54 catchIO (removeFile f)
61 catchIO (removeFile f)
55 (\ioerr -> putStrLn $ "WARNING: Cannot remove file "
62 (\ioerr -> putStrLn $ "WARNING: Cannot remove file "
56 ++ f ++ ", Error msg:" ++ show ioerr)
63 ++ f ++ ", Error msg:" ++ show ioerr)
64+
65+setupBundledCC :: IO()
66+#ifdef FREESTANDING
67+setupBundledCC = when hasBundledToolchain
68+ $ do
69+ exePath <- getExecutablePath
70+ path <- getEnv "PATH"
71+ tcDir <- return getToolchainDir
72+ absolute <- return $ isAbsolute tcDir
73+ target <- return $
74+ if absolute
75+ then tcDir
76+ else dropFileName exePath ++ tcDir
77+ let pathSep = if isWindows then ";" else ":"
78+ present <- doesDirectoryExist target
79+ when present
80+ $ do newPath <- return $ target ++ pathSep ++ path
81+ setEnv "PATH" newPath
82+#else
83+setupBundledCC = return ()
84+#endif
win-release.shnew file+2
@@ -0,0 +1,2 @@
1+
2+IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make