shake-ats 1.4.0.0 → 1.4.1.0
raw patch · 5 files changed
+125/−120 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Development.Shake.ATS: Binary :: Bool -> ArtifactType
- Development.Shake.ATS: DynamicLibrary :: ArtifactType
+ Development.Shake.ATS: Executable :: ArtifactType
+ Development.Shake.ATS: patscc :: MonadIO m => ATSToolConfig -> m String
+ Development.Shake.ATS: patsopt :: MonadIO m => ATSToolConfig -> m String
- Development.Shake.ATS: BinaryTarget :: [String] -> ATSToolConfig -> Bool -> [String] -> String -> [ForeignCabal] -> [(String, String, Bool)] -> String -> [String] -> [String] -> ArtifactType -> BinaryTarget
+ Development.Shake.ATS: BinaryTarget :: [String] -> ATSToolConfig -> Bool -> [String] -> [String] -> [ForeignCabal] -> [(String, String, Bool)] -> String -> [String] -> [String] -> ArtifactType -> BinaryTarget
- Development.Shake.ATS: GCC :: Maybe String -> Maybe String -> CCompiler
+ Development.Shake.ATS: GCC :: Maybe String -> CCompiler
- Development.Shake.ATS: GHC :: Maybe String -> Maybe String -> CCompiler
+ Development.Shake.ATS: GHC :: Maybe String -> CCompiler
- Development.Shake.ATS: [src] :: BinaryTarget -> String
+ Development.Shake.ATS: [src] :: BinaryTarget -> [String]
- Development.Shake.ATS: data CCompiler
+ Development.Shake.ATS: data CCompiler :: *
- Development.Shake.ATS: patsHome :: Version -> Action String
+ Development.Shake.ATS: patsHome :: MonadIO m => Version -> m String
Files
- shake-ats.cabal +1/−1
- src/Development/Shake/ATS.hs +100/−49
- src/Development/Shake/ATS/Environment.hs +9/−41
- src/Development/Shake/ATS/Rules.hs +1/−1
- src/Development/Shake/ATS/Type.hs +14/−28
shake-ats.cabal view
@@ -1,5 +1,5 @@ name: shake-ats-version: 1.4.0.0+version: 1.4.1.0 synopsis: Utilities for building ATS projects with shake description: Various helper functions for building [ATS](http://www.ats-lang.org/) with the [shake](http://shakebuild.com/) library homepage: https://github.com/vmchale/shake-ats#readme
src/Development/Shake/ATS.hs view
@@ -20,6 +20,8 @@ , ccToDir , compatible , host+ , patscc+ , patsopt -- Types , Version (..) , ForeignCabal (..)@@ -37,34 +39,35 @@ import Data.Maybe (fromMaybe) import Data.Semigroup (Semigroup (..)) import qualified Data.Text.Lazy as TL-import Development.Shake+import Development.Shake hiding (doesFileExist) import Development.Shake.ATS.Environment import Development.Shake.ATS.Rules import Development.Shake.ATS.Type+import Development.Shake.C import Development.Shake.FilePath import Development.Shake.Version import Language.ATS import Lens.Micro-import System.Directory (copyFile, createDirectoryIfMissing)+import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist) import System.Exit (ExitCode (ExitSuccess)) -- | Whether generated libraries are to be considered compatible. compatible :: CCompiler -> CCompiler -> Bool-compatible (GCC Nothing Nothing) Clang = True-compatible Clang (GCC Nothing Nothing) = True-compatible x y = x == y+compatible GCCStd Clang = True+compatible Clang GCCStd = True+compatible x y = x == y --- | Run @patsopt@ given information about+-- | Run @patsopt@ given information about various things atsCommand :: CmdResult r => ATSToolConfig -> String -- ^ Source file -> String -- ^ C code to be generated -> Action r atsCommand tc sourceFile out = do- h <- patsHome (compilerVer tc)- let home = h ++ "lib/ats2-postiats-" ++ show (libVersion tc)- atsArgs = [EchoStderr False, AddEnv "PATSHOME" home]- patsc = home ++ "/bin/patsopt"- command atsArgs patsc ["--output", out, "-dd", sourceFile, "-cc"]+ path <- fromMaybe "" <$> getEnv "PATH"+ home' <- home tc+ let env = patsEnv home' path+ patsc <- patsopt tc+ command env patsc ["--output", out, "-dd", sourceFile, "-cc"] gcFlag :: Bool -> String gcFlag False = "-DATS_MEMALLOC_LIBC"@@ -76,26 +79,25 @@ copySources (ATSToolConfig v v' _ _) sources = forM_ sources $ \dep -> do h <- patsHome v'- let home = h ++ "lib/ats2-postiats-" ++ show v- liftIO $ createDirectoryIfMissing True (home ++ "/" ++ takeDirectory dep)- liftIO $ copyFile dep (home ++ "/" ++ dep)+ let home' = h ++ "lib/ats2-postiats-" ++ show v+ liftIO $ createDirectoryIfMissing True (home' ++ "/" ++ takeDirectory dep)+ liftIO $ copyFile dep (home' ++ "/" ++ dep) -- This is the @$PATSHOMELOCS@ variable to be passed to the shell. patsHomeLocs :: Int -> String patsHomeLocs n = intercalate ":" $ (<> ".atspkg/contrib") . ("./" <>) <$> g where g = [ join $ replicate i "../" | i <- [1..n] ] --- TODO depend on GHC version? makeCFlags :: [String] -- ^ Inputs -> [ForeignCabal] -- ^ Haskell libraries -> String -- ^ GHC version -> Bool -- ^ Whether to use the Garbage collector -> [String]-makeCFlags ss fc ghcV b = gcFlag' : (hsExtra <> ss) where+makeCFlags ss fc ghcV' b = gcFlag' : (hsExtra <> ss) where gcFlag' = bool ("-optc" <>) id noHs $ gcFlag b- hsExtra = bool (["--make", "-odir", ".atspkg", "-no-hs-main", "-package-db", "~/.cabal/store/ghc-" ++ ghcV ++ "/package.db/"] ++ packageDbs) mempty noHs+ hsExtra = bool (["--make", "-I.", "-odir", ".atspkg", "-no-hs-main", "-package-db", "~/.cabal/store/ghc-" ++ ghcV' ++ "/package.db/"] ++ packageDbs) mempty noHs noHs = null fc- packageDbs = (\x -> ["-package-db", x ++ "/dist-newstyle/packagedb/ghc-" ++ ghcV]) =<< libToDirs fc+ packageDbs = (\x -> ["-package-db", x ++ "/dist-newstyle/packagedb/ghc-" ++ ghcV']) =<< libToDirs fc libToDirs :: [ForeignCabal] -> [String] libToDirs = fmap (takeDirectory . TL.unpack . h)@@ -104,10 +106,54 @@ uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d) uncurry3 f (x, y, z) = f x y z --- TODO libraries should be linked against *cross-compiled* versions!!--- aka we need to compile atslib+-- Change architecture to use C stuff better?+-- Step 1: Use patsopt to generate C files+-- Step 2: Use gcc to generate `.o` files+-- Step 3: Generate library/binary from those files.++-- | Location of @patscc@+patscc :: MonadIO m => ATSToolConfig -> m String+patscc = patsTool "patscc"++-- | Location of @patsopt@+patsopt :: MonadIO m => ATSToolConfig -> m String+patsopt = patsTool "patsopt"++patsTool :: MonadIO m => String -> ATSToolConfig -> m String+patsTool tool tc = do+ h <- patsHome (compilerVer tc)+ pure $ h ++ "lib/ats2-postiats-" ++ show (libVersion tc) ++ "/bin/" ++ tool++cconfig :: MonadIO m => ATSToolConfig -> [String] -> Bool -> [String] -> m CConfig+cconfig tc libs gc extras = do+ h <- patsHome (compilerVer tc)+ let cc' = cc tc+ h' <- pkgHome cc'+ home' <- home tc+ let libs' = ("atslib" :) $ bool libs ("gc" : libs) gc+ pure $ CConfig [h ++ "ccomp/runtime/", h, h' ++ "include"] libs' [h' ++ "lib", home' ++ "/ccomp/atslib/lib"] extras++home :: MonadIO m => ATSToolConfig -> m String+home tc = do+ h <- patsHome (compilerVer tc)+ pure $ h ++ "lib/ats2-postiats-" ++ show (libVersion tc)++patsEnv :: FilePath -> FilePath -> [CmdOption]+patsEnv home' path = EchoStderr False :+ zipWith AddEnv+ ["PATSHOME", "PATH", "PATSHOMELOCS"]+ [home', home' ++ "/bin:" ++ path, patsHomeLocs 5]++atsToC :: FilePath -> FilePath+atsToC = (-<.> "c") . (".atspkg/c/" <>)++ghcV :: [ForeignCabal] -> Action String+ghcV hsLibs = case hsLibs of+ [] -> pure undefined+ _ -> ghcVersion+ atsBin :: BinaryTarget -> Rules ()-atsBin BinaryTarget{..} = do+atsBin tgt@BinaryTarget{..} = do unless (null genTargets) $ mapM_ (uncurry3 genATS) genTargets@@ -115,35 +161,40 @@ unless (null hsLibs) $ mapM_ cabalExport hsLibs + let cTargets = atsToC <$> src++ foldr (>>) (pure ()) (atsCGen toolConfig tgt <$> src <*> cTargets)+ binTarget %> \_ -> do- h <- patsHome (compilerVer toolConfig)- let cc' = cc toolConfig- h' <- pkgHome cc'- let home = h ++ "lib/ats2-postiats-" ++ show (libVersion toolConfig)- need otherDeps- sources <- (<> cDeps) <$> transitiveDeps ((^._2) <$> genTargets) [src]- b' <- doesFileExist "atspkg.dhall"- let hb = bool id ("atspkg.dhall" :) b'- need (hb (sources ++ (TL.unpack . objectFile <$> hsLibs)))- copySources toolConfig sources - let ccommand = unwords [ ccToString cc', "-I" ++ h ++ "ccomp/runtime/", "-I" ++ h, "-I" ++ h' ++ "include", "-L" ++ h' ++ "lib", "-L" ++ home ++ "/ccomp/atslib/lib"]- path <- fromMaybe "" <$> getEnv "PATH"- let toLibs = fmap ("-l" <>)- let libs' = ("atslib" :) $ bool libs ("gc" : libs) gc -- TODO make atslib a configuration option- ghcV <- case hsLibs of- [] -> pure undefined- _ -> ghcVersion- command_- [EchoStderr False, AddEnv "PATSHOME" home, AddEnv "PATH" (home ++ "/bin:" ++ path), AddEnv "PATSHOMELOCS" $ patsHomeLocs 5]- (home ++ "/bin/patscc")- (mconcat- [ [src, "-atsccomp", ccommand, "-o", binTarget, "-cleanaft"]- , makeCFlags cFlags hsLibs ghcV gc- , toLibs libs'- ])+ need cTargets --- given directory.+ ghcV' <- ghcV hsLibs++ cconfig' <- cconfig toolConfig libs gc (makeCFlags cFlags hsLibs ghcV' gc)++ let g Executable = ccAction+ g StaticLibrary = staticLibA++ unit $ g tgtType (cc toolConfig) cTargets binTarget cconfig'++atsCGen :: ATSToolConfig+ -> BinaryTarget+ -> FilePath -- ^ ATS source+ -> FilePattern -- ^ Pattern for C file to be generated+ -> Rules ()+atsCGen tc BinaryTarget{..} atsSrc cFiles =+ cFiles %> \out -> do++ -- tell shake which files to track and copy them to the appropriate+ -- directory+ need (otherDeps ++ (TL.unpack . objectFile <$> hsLibs))+ sources <- (<> cDeps) <$> transitiveDeps ((^._2) <$> genTargets) [atsSrc]+ need sources+ copySources tc sources++ atsCommand tc atsSrc out+ cgen :: ATSToolConfig -> FilePath -- ^ Directory containing ATS source code -> Rules ()@@ -164,13 +215,13 @@ trim :: String -> String trim = init . drop 1 -transitiveDeps :: [FilePath] -> [FilePath] -> Action [FilePath]+transitiveDeps :: (MonadIO m) => [FilePath] -> [FilePath] -> m [FilePath] transitiveDeps _ [] = pure [] transitiveDeps gen ps = fmap join $ forM ps $ \p -> if p `elem` gen then pure mempty else do contents <- liftIO $ readFile p let ats = fromRight mempty . parse $ contents let dir = takeDirectory p- deps <- filterM (\f -> ((f `elem` gen) ||) <$> doesFileExist f) $ fixDir dir . trim <$> getDependencies ats+ deps <- filterM (\f -> ((f `elem` gen) ||) <$> (liftIO . doesFileExist) f) $ fixDir dir . trim <$> getDependencies ats deps' <- transitiveDeps gen deps pure $ (p:deps) ++ deps'
src/Development/Shake/ATS/Environment.hs view
@@ -2,58 +2,26 @@ , pkgHome , patsHome , ccToDir- , ccToString- , ccFromString- , host ) where -import Data.List (isPrefixOf, isSuffixOf)-import Data.Maybe (fromMaybe)+import Control.Monad.IO.Class import qualified Data.Text.Lazy as TL-import Development.Shake import Development.Shake.ATS.Type+import Development.Shake.C import Development.Shake.FilePath-import System.Info--host :: String-host = arch ++ withManufacturer os- where withManufacturer "darwin" = "-apple-" ++ os- withManufacturer _ = "-unknown-" ++ os+import System.Environment (getEnv) ccToDir :: CCompiler -> String-ccToDir (GCC (Just s) _) = reverse (drop 1 $ reverse s) ++ "/"-ccToDir _ = ""--ccToString :: CCompiler -> String-ccToString Clang = "clang"-ccToString (Other s) = s-ccToString (GCC pre suff) = mkQualified pre suff "gcc"-ccToString (GHC pre suff) = mkQualified pre suff "ghc"--ccFromString :: String -> CCompiler-ccFromString "gcc" = GCC Nothing Nothing-ccFromString "clang" = Clang-ccFromString "ghc" = GHC Nothing Nothing-ccFromString s- | "gcc" `isSuffixOf` s = GCC (Just (reverse . drop 3 . reverse $ s)) Nothing- | "gcc" `isPrefixOf` s = GCC Nothing (Just $ drop 3 s)- | "ghc" `isSuffixOf` s = GHC (Just (reverse . drop 3 . reverse $ s)) Nothing- | "ghc" `isPrefixOf` s = GHC Nothing (Just $ drop 3 s)-ccFromString _ = GCC Nothing Nothing--mkQualified :: Monoid a => Maybe a -> Maybe a -> a -> a-mkQualified pre suff = h (g <$> [pre, suff])- where g = maybe id mappend- h = foldr fmap id+ccToDir (GCC (Just s)) = reverse (drop 1 $ reverse s) ++ "/"+ccToDir _ = "" -- | The directory @~/.atspkg@-pkgHome :: CCompiler -> Action String-pkgHome cc' = fromMaybe "/usr/local/" <$> mh- where mh = fmap (++ ("/.atspkg/" ++ ccToDir cc')) <$> getEnv "HOME"+pkgHome :: MonadIO m => CCompiler -> m String+pkgHome cc' = liftIO $ (++ ("/.atspkg/" ++ ccToDir cc')) <$> getEnv "HOME" -- | The directory that will be @PATSHOME@.-patsHome :: Version -> Action String-patsHome v = fmap (++ (show v ++ "/")) (pkgHome (GCC Nothing Nothing))+patsHome :: MonadIO m => Version -> m String+patsHome v = fmap (++ (show v ++ "/")) (pkgHome (GCC Nothing)) fixDir :: FilePath -> String -> String fixDir p =
src/Development/Shake/ATS/Rules.hs view
@@ -51,7 +51,7 @@ obf %> \out -> do need (cf : fmap ((obfDir <> "/") <>) trDeps)- command_ [Cwd obfDir] "cabal" ["new-build"]+ command_ [Cwd obfDir] "cabal" ["new-build", "-O2"] let subdir = takeDirectory cbp ++ "/" correctDir = (libName `isPrefixOf`)
src/Development/Shake/ATS/Type.hs view
@@ -1,30 +1,20 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE PatternSynonyms #-}----- gcc -c -o lib1.o lib1.c--- gcc ats-src/libnumbertheory.o -shared -o ats-src/libnumbertheory.so--- gcc number-theory-ffi_dats.c -c -fPIC -o ats-src/libnumbertheory.o -IATS2-Postiats-include-0.3.8/ -IATS2-Postiats-include-0.3.8/ccomp/runtime/+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE StandaloneDeriving #-} module Development.Shake.ATS.Type ( ForeignCabal (..) , Version (..) , BinaryTarget (..) , ArtifactType (..) , ATSToolConfig (..)- , CCompiler (GCC, Clang, GHC, Other, GCCStd, GHCStd) ) where -import Data.Binary (Binary (..))-import Data.Dependency (Version (..))-import qualified Data.Text.Lazy as TL-import GHC.Generics (Generic)--pattern GCCStd :: CCompiler-pattern GCCStd = GCC Nothing Nothing--pattern GHCStd :: CCompiler-pattern GHCStd = GHC Nothing Nothing+import Data.Binary (Binary (..))+import Data.Dependency (Version (..))+import qualified Data.Text.Lazy as TL+import Development.Shake.C+import GHC.Generics (Generic) -- We should have four build types: --@@ -53,17 +43,13 @@ -- -- * Also binary caches are good. +deriving instance Generic CCompiler+deriving instance Binary CCompiler+ data ArtifactType = StaticLibrary- | DynamicLibrary- | Binary Bool -- ^ Whether binary build should create a static binary+ | Executable deriving (Generic, Binary) -data CCompiler = GCC { _prefix :: Maybe String, _suffix :: Maybe String }- | Clang- | Other String- | GHC { _prefix :: Maybe String, _suffix :: Maybe String }- deriving (Eq, Generic, Binary)- -- | Information about where to find @patscc@ and @patsopt@. data ATSToolConfig = ATSToolConfig { libVersion :: Version , compilerVer :: Version@@ -76,7 +62,7 @@ , toolConfig :: ATSToolConfig , gc :: Bool -- ^ Whether to configure build for use with the garbage collector. , libs :: [String] -- ^ Libraries against which to link- , src :: String -- ^ Source file for binary.+ , src :: [String] -- ^ ATS source files. If building an executable, at most one may contain @main0@. , hsLibs :: [ForeignCabal] -- ^ Cabal-based Haskell libraries , genTargets :: [(String, String, Bool)] -- ^ Files to be run through @hs2ats@. , binTarget :: String -- ^ Binary target