diff --git a/Setup.hs b/Setup.hs index 28aea3095..438d71aac 100644 --- a/Setup.hs +++ b/Setup.hs @@ -137,17 +137,33 @@ generateTargetModule verbosity dir targetDir = do ++ " dir <- getDataDir\n" ++ " return (dir ++ \"/\" ++ name)" +-- a module that has info about existence and location of a bundled toolchain +generateToolchainModule verbosity srcDir toolDir = do + let commonContent = "module Tools_idris where\n\n" + let toolContent = case toolDir of + Just dir -> "hasBundledToolchain = True\n" ++ + "getToolchainDir = \"" ++ dir ++ "\"\n" + Nothing -> "hasBundledToolchain = False\n" ++ + "getToolchainDir = \"\"" + let toolPath = srcDir "Tools_idris" Px.<.> "hs" + createDirectoryIfMissingVerbose verbosity True srcDir + rewriteFile toolPath (commonContent ++ toolContent) idrisConfigure _ flags _ local = do - configureRTS - generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local)) - when (isFreestanding $ configFlags local) (do - targetDir <- lookupEnv "IDRIS_INSTALL_DIR" + configureRTS + generateVersionModule verbosity (autogenModulesDir local) (isRelease (configFlags local)) + if (isFreestanding $ configFlags local) + then (do + toolDir <- lookupEnv "IDRIS_TOOLCHAIN_DIR" + generateToolchainModule verbosity (autogenModulesDir local) toolDir + targetDir <- lookupEnv "IDRIS_LIB_DIR" case targetDir of Just d -> generateTargetModule verbosity (autogenModulesDir local) d Nothing -> error $ "Trying to build freestanding without a target directory." - ++ " Set it by defining IDRIS_INSTALL_DIR.") - where + ++ " Set it by defining IDRIS_LIB_DIR.") + else + generateToolchainModule verbosity (autogenModulesDir local) Nothing + where verbosity = S.fromFlag $ S.configVerbosity flags version = pkgVersion . package $ localPkgDescr local @@ -162,6 +178,7 @@ idrisPreSDist args flags = do let verb = S.fromFlag (S.sDistVerbosity flags) generateVersionModule verb ("src") True generateTargetModule verb "src" "./libs" + generateToolchainModule verb "src" Nothing preSDist simpleUserHooks args flags idrisPostSDist args flags desc lbi = do diff --git a/codegen/idris-c/Main.hs b/codegen/idris-c/Main.hs index a866980a2..6d228b346 100644 --- a/codegen/idris-c/Main.hs +++ b/codegen/idris-c/Main.hs @@ -14,6 +14,8 @@ import Control.Monad import Paths_idris +import Util.System + data Opts = Opts { inputs :: [FilePath], interface :: Bool, output :: FilePath } @@ -31,7 +33,8 @@ getOpts = do xs <- getArgs process opts [] = opts c_main :: Opts -> Idris () -c_main opts = do elabPrims +c_main opts = do runIO setupBundledCC + elabPrims loadInputs (inputs opts) Nothing mainProg <- if interface opts then liftM Just elabMain diff --git a/idris.cabal b/idris.cabal index ed24ab528..66ec732a6 100644 --- a/idris.cabal +++ b/idris.cabal @@ -806,6 +806,7 @@ Library -- Auto Generated , Paths_idris , Version_idris + , Tools_idris Build-depends: base >=4 && <5 , annotated-wl-pprint >= 0.5.3 && < 0.6 diff --git a/main/Main.hs b/main/Main.hs index d5a7af105..b9e41a6f4 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -29,6 +29,7 @@ import Idris.CmdOptions import IRTS.System ( getLibFlags, getIdrisLibDir, getIncFlags ) import Util.DynamicLinker +import Util.System import Pkg.Package @@ -43,6 +44,7 @@ main = do opts <- runArgParser runIdris :: [Opt] -> Idris () runIdris opts = do + runIO setupBundledCC when (ShowIncs `elem` opts) $ runIO showIncs when (ShowLibs `elem` opts) $ runIO showLibs when (ShowLibdir `elem` opts) $ runIO showLibdir diff --git a/src/Util/System.hs b/src/Util/System.hs index c814e4441..938a867cd 100644 --- a/src/Util/System.hs +++ b/src/Util/System.hs @@ -1,5 +1,6 @@ +{-# LANGUAGE CPP #-} module Util.System(tempfile,withTempdir,rmFile,catchIO, isWindows, - readSource, writeSource) where + writeSource, readSource, setupBundledCC) where -- System helper functions. import Control.Monad (when) @@ -7,13 +8,19 @@ import System.Directory (getTemporaryDirectory , removeFile , removeDirectoryRecursive , createDirectoryIfMissing + , doesDirectoryExist ) -import System.FilePath ((), normalise) +import System.FilePath ((), normalise, isAbsolute, dropFileName) import System.IO import System.Info import System.IO.Error import Control.Exception as CE +#ifdef FREESTANDING +import Tools_idris +import System.Environment (getEnv, setEnv, getExecutablePath) +#endif + catchIO :: IO a -> (IOError -> IO a) -> IO a catchIO = CE.catch @@ -54,3 +61,24 @@ rmFile f = do putStrLn $ "Removing " ++ f catchIO (removeFile f) (\ioerr -> putStrLn $ "WARNING: Cannot remove file " ++ f ++ ", Error msg:" ++ show ioerr) + +setupBundledCC :: IO() +#ifdef FREESTANDING +setupBundledCC = when hasBundledToolchain + $ do + exePath <- getExecutablePath + path <- getEnv "PATH" + tcDir <- return getToolchainDir + absolute <- return $ isAbsolute tcDir + target <- return $ + if absolute + then tcDir + else dropFileName exePath ++ tcDir + let pathSep = if isWindows then ";" else ":" + present <- doesDirectoryExist target + when present + $ do newPath <- return $ target ++ pathSep ++ path + setEnv "PATH" newPath +#else +setupBundledCC = return () +#endif diff --git a/win-release.sh b/win-release.sh new file mode 100644 index 000000000..bcd4fcbcb --- /dev/null +++ b/win-release.sh @@ -0,0 +1,2 @@ + +IDRIS_LIB_DIR="./libs" IDRIS_TOOLCHAIN_DIR="./mingw/bin" CABALFLAGS="-fffi -ffreestanding -frelease" make