shake-ats 1.5.0.7 → 1.5.0.8
raw patch · 6 files changed
+138/−71 lines, 6 filesdep +hashabledep +lensdep −microlensdep ~shake-ext
Dependencies added: hashable, lens
Dependencies removed: microlens
Dependency ranges changed: shake-ext
Files
- shake-ats.cabal +3/−2
- src/Development/Shake/ATS.hs +70/−39
- src/Development/Shake/ATS/Environment.hs +3/−0
- src/Development/Shake/ATS/Generate.hs +1/−1
- src/Development/Shake/ATS/Rules.hs +11/−12
- src/Development/Shake/ATS/Type.hs +50/−17
shake-ats.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: shake-ats-version: 1.5.0.7+version: 1.5.0.8 license: BSD3 license-file: LICENSE copyright: Copyright: (c) 2018 Vanessa McHale@@ -37,11 +37,12 @@ ghc-options: -Wall build-depends: base >=4.7 && <5,+ hashable, language-ats, shake-ext >=2.7.0.0, hs2ats >=0.2.0.1, directory -any,- microlens -any,+ lens -any, text -any, dependency -any, shake -any,
src/Development/Shake/ATS.hs view
@@ -7,26 +7,45 @@ module Development.Shake.ATS ( -- * Shake Rules cleanATS , atsBin- , atsLex- , cabalExport , cgen , genATS+ , atsLex -- * Helper functions , getSubdirs , ccToDir , withPF+ , defaultATSTarget+ , defaultATSToolConfig -- * Environment/configuration , patscc , patsopt- -- Types+ -- * Types , ForeignCabal (..) , ATSTarget (..) , ATSToolConfig (..) , CCompiler (..) , ArtifactType (..)+ , ATSGen (..)+ -- * Lenses+ , atsTarget+ , cFlags+ , binTarget+ , cc+ , compilerVer+ , genTargets+ , hsLibs+ , libVersion+ , libs+ , linkStatic+ , linkTargets+ , otherDeps+ , src+ , tgtType+ , toolConfig ) where import Control.Arrow+import Control.Lens import Control.Monad import Control.Monad.IO.Class import Data.Bool (bool)@@ -43,7 +62,6 @@ import Development.Shake.FilePath import Development.Shake.Version import Language.ATS-import Lens.Micro import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist) import System.Environment (getEnv) import System.Exit (ExitCode (ExitSuccess))@@ -62,9 +80,9 @@ command env patsc ["--output", out, "-dd", sourceFile, "-cc"] -- | Filter any generated errors with @pats-filter@.-withPF :: Bool -> Action (Exit, Stderr String, Stdout String) -> Action (Exit, Stderr String, Stdout String)-withPF False = id-withPF True = \act -> do+withPF :: Action (Exit, Stderr String, Stdout String) -- ^ Result of a 'cmd' or 'command'+ -> Action (Exit, Stderr String, Stdout String)+withPF act = do ret@(Exit c, Stderr err, Stdout _) <- act :: Action (Exit, Stderr String, Stdout String) cmd_ [Stdin err] Shell "pats-filter" if c /= ExitSuccess@@ -78,7 +96,7 @@ -- Copy source files to the appropriate place. This is necessary because -- @#include@s in ATS are weird. copySources :: ATSToolConfig -> [FilePath] -> Action ()-copySources (ATSToolConfig v v' _ _) sources =+copySources (ATSToolConfig v v' _ _ _) sources = forM_ sources $ \dep -> do h <- patsHome v' let home' = h ++ "lib/ats2-postiats-" ++ show v@@ -106,9 +124,6 @@ libToDirs = fmap (takeDirectory . TL.unpack . h) where h (ForeignCabal mpr cf _) = fromMaybe cf mpr -uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)-uncurry3 f (x, y, z) = f x y z- -- | Location of @patscc@ patscc :: MonadIO m => ATSToolConfig -> m String patscc = patsTool "patscc"@@ -119,23 +134,23 @@ patsTool :: MonadIO m => String -> ATSToolConfig -> m String patsTool tool tc = (<> prep) <$> ph- where ph = patsHome (compilerVer tc)- prep = "lib/ats2-postiats-" ++ show (libVersion tc) ++ "/bin/" ++ tool+ where ph = patsHome (_compilerVer tc)+ prep = "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+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+ let libs'' = ("atslib" :) $ bool libs' ("gc" : libs') gc' -- TODO only include /ccomp/atslib/lib if it's not a cross build- pure $ CConfig [h ++ "ccomp/runtime/", h, h' ++ "include", ".atspkg/contrib"] libs' [h' ++ "lib", home' ++ "/ccomp/atslib/lib"] extras+ pure $ CConfig [h ++ "ccomp/runtime/", h, h' ++ "include", ".atspkg/contrib"] libs'' [h' ++ "lib", home' ++ "/ccomp/atslib/lib"] extras (_linkStatic tc) home :: MonadIO m => ATSToolConfig -> m String home tc = do- h <- patsHome (compilerVer tc)- pure $ h ++ "lib/ats2-postiats-" ++ show (libVersion tc)+ h <- patsHome (_compilerVer tc)+ pure $ h ++ "lib/ats2-postiats-" ++ show (_libVersion tc) patsEnv :: FilePath -> FilePath -> [CmdOption] patsEnv home' path = EchoStderr False :@@ -147,7 +162,7 @@ atsToC = (-<.> "c") . (".atspkg/c/" <>) ghcV :: [ForeignCabal] -> Action String-ghcV hsLibs = case hsLibs of+ghcV hsLibs' = case hsLibs' of [] -> pure undefined _ -> ghcVersion @@ -155,50 +170,66 @@ doLib Executable = pure mempty doLib _ = id +defaultATSTarget :: [FilePath] -- ^ ATS source files+ -> ArtifactType+ -> FilePath -- ^ Target+ -> ATSTarget+defaultATSTarget sources tgt' out =+ ATSTarget mempty defaultATSToolConfig False mempty sources mempty mempty mempty out mempty tgt'++defaultATSToolConfig :: ATSToolConfig+defaultATSToolConfig =+ ATSToolConfig v v False (GCC Nothing) False+ where v = Version [0,3,9]++-- | Rules for generating binaries or libraries from ATS code. This is very+-- general; use 'defaultATSTarget' for sensible defaults that can be modified+-- with the provided lenses. atsBin :: ATSTarget -> Rules () atsBin ATSTarget{..} = do - mapM_ (uncurry genLinks) linkTargets+ mapM_ (uncurry genLinks) _linkTargets - mapM_ (uncurry3 genATS) genTargets+ mapM_ (\(ATSGen x y z) -> genATS x y z) _genTargets - mapM_ cabalExport hsLibs+ mapM_ cabalExport _hsLibs - let cTargets = atsToC <$> src+ let cTargets = atsToC <$> _src let h Executable = id h StaticLibrary = fmap (-<.> "o") h SharedLibrary = fmap (-<.> "o")- g Executable = ccAction+ g Executable = binaryA g StaticLibrary = staticLibA g SharedLibrary = sharedLibA- h' = h tgtType+ h' = h _tgtType - cconfig' <- cconfig toolConfig libs gc (makeCFlags cFlags mempty (pure undefined) gc)+ cconfig' <- cconfig _toolConfig _libs _gc (makeCFlags _cFlags mempty (pure undefined) _gc) - let atsGen = (snd <$> linkTargets) <> ((^._2) <$> genTargets)- atsExtras = otherDeps <> (TL.unpack . objectFile <$> hsLibs)- zipWithM_ (cgen toolConfig atsExtras atsGen) src cTargets+ let atsGen = (snd <$> _linkTargets) <> ((^.atsTarget) <$> _genTargets)+ atsExtras = _otherDeps <> (TL.unpack . objectFile <$> _hsLibs)+ zipWithM_ (cgen _toolConfig atsExtras atsGen) _src cTargets - doLib tgtType (zipWithM_ (objectFileR (cc toolConfig) cconfig') cTargets (h' cTargets))+ doLib _tgtType (zipWithM_ (objectFileR (_cc _toolConfig) cconfig') cTargets (h' cTargets)) - binTarget %> \_ -> do+ _binTarget %> \_ -> do need (h' cTargets) - ghcV' <- ghcV hsLibs+ ghcV' <- ghcV _hsLibs - cconfig'' <- cconfig toolConfig libs gc (makeCFlags cFlags hsLibs ghcV' gc)+ cconfig'' <- cconfig _toolConfig _libs _gc (makeCFlags _cFlags _hsLibs ghcV' _gc) - unit $ g tgtType (cc toolConfig) (h' cTargets) binTarget cconfig''+ unit $ g _tgtType (_cc _toolConfig) (h' cTargets) _binTarget cconfig'' +-- | Generate C code from ATS code. cgen :: ATSToolConfig -> [FilePath] -- ^ Extra files to track -> [FilePath] -- ^ ATS source that may be generated. -> FilePath -- ^ ATS source -> FilePattern -- ^ Pattern for C file to be generated -> Rules ()-cgen toolConfig extras atsGens atsSrc cFiles =+cgen toolConfig' extras atsGens atsSrc cFiles = cFiles %> \out -> do -- tell shake which files to track and copy them to the appropriate@@ -206,9 +237,9 @@ need extras sources <- transitiveDeps atsGens [atsSrc] need sources- copySources toolConfig sources+ copySources toolConfig' sources - atsCommand toolConfig atsSrc out+ atsCommand toolConfig' atsSrc out -- | This provides rules for generating C code from ATS source files in the trim :: String -> String
src/Development/Shake/ATS/Environment.hs view
@@ -11,6 +11,9 @@ import Development.Shake.FilePath import System.Environment (getEnv) +-- | Given a C compiler, return the appropriate directory for its globally+-- installed artifacts. This is used to keep libraries built for different+-- platforms separate. ccToDir :: CCompiler -> String ccToDir (GCC (Just s)) = reverse (drop 1 $ reverse s) ++ "/" ccToDir _ = ""
src/Development/Shake/ATS/Generate.hs view
@@ -1,9 +1,9 @@ module Development.Shake.ATS.Generate ( generateLinks ) where +import Control.Lens import Data.Semigroup import Language.ATS-import Lens.Micro generateLinks :: String -> Either ATSError String generateLinks = fmap (printATS . generateLinks') . parseM
src/Development/Shake/ATS/Rules.hs view
@@ -21,13 +21,13 @@ -- | Given a plain Haskell source file, generate a @.sats@ file containing -- the equivalent types. genATS :: FilePath -- ^ Haskell source- -> FilePath -- ^ @.sats@ file to generate+ -> FilePattern -- ^ @.sats@ file to generate -> Bool -- ^ Whether to call cpphs preprocessor -> Rules ()-genATS src target cpphs =+genATS src' target cpphs' = target %> \out -> liftIO $ do createDirectoryIfMissing True (takeDirectory out)- genATSTypes src out cpphs+ genATSTypes src' out cpphs' genLinks :: FilePath -> FilePath -> Rules () genLinks dats link =@@ -36,6 +36,7 @@ let proc = generateLinks contents writeFile out (either undefined id proc) +-- | Get subdirectories recursively. getSubdirs :: FilePath -> IO [FilePath] getSubdirs p = do ds <- listDirectory p@@ -46,10 +47,6 @@ ss <- mapM getSubdirs ds' pure $ ds' <> join ss --- libHSforeign-0.1.0.0-inplace-ghc8.2.2.so--- libHSforeign-0.1.0.0-inplace.a--- Foreign_stub.h- -- | These rules take a @.cabal@ file and the @.o@ file to be produced from -- them, building the @.o@ file. cabalExport :: ForeignCabal -> Rules ()@@ -67,6 +64,7 @@ need (cf : fmap ((obfDir <> "/") <>) trDeps) command_ [Cwd obfDir] "cabal" ["new-build", "all"] + -- TODO move this to the @shake-ext@ package? ghcV <- quietly ghcVersion let subdir = takeDirectory cbp ++ "/" correctDir = (== "build")@@ -90,8 +88,9 @@ (Stdout contents) <- command [Stdin lats] "atslex" [] liftIO $ writeFile out contents -cleanATS :: Rules ()-cleanATS = "clean" ~> do- removeFilesAfter "." ["//*.c", "//tags"]- removeFilesAfter ".atspkg" ["//*"]- removeFilesAfter "ats-deps" ["//*"]+-- | Clean up after an ATS build.+cleanATS :: Action ()+cleanATS =+ zipWithM_ removeFilesAfter+ [".", ".atspkg", "ats-deps"]+ [["//*.c", "//*_lats.dats", "//tags"], ["//*"], ["//*"]]
src/Development/Shake/ATS/Type.hs view
@@ -2,16 +2,38 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} module Development.Shake.ATS.Type ( ForeignCabal (..) , Version (..) , ATSTarget (..) , ArtifactType (..) , ATSToolConfig (..)+ , ATSGen (..)+ -- * Lenses+ , atsTarget+ , hasPretty+ , cFlags+ , otherDeps+ , toolConfig+ , cc+ , linkStatic+ , src+ , gc+ , binTarget+ , genTargets+ , hsLibs+ , libs+ , tgtType+ , compilerVer+ , libVersion+ , linkTargets ) where +import Control.Lens import Data.Binary (Binary (..)) import Data.Dependency (Version (..))+import Data.Hashable (Hashable) import qualified Data.Text.Lazy as TL import Development.Shake.C import GHC.Generics (Generic)@@ -52,28 +74,39 @@ deriving (Generic, Binary) -- | Information about where to find @patscc@ and @patsopt@.-data ATSToolConfig = ATSToolConfig { libVersion :: Version- , compilerVer :: Version- , hasPretty :: Bool -- ^ Whether to display errors via @pats-filter@- , cc :: CCompiler -- ^ C compiler to be used+data ATSToolConfig = ATSToolConfig { _libVersion :: Version -- ^ Standard library version to be used.+ , _compilerVer :: Version -- ^ Version of @patscc@ to be used.+ , _hasPretty :: Bool -- ^ Whether to display errors via @pats-filter@+ , _cc :: CCompiler -- ^ C compiler to be used+ , _linkStatic :: Bool -- ^ Force static linking } deriving (Generic, Binary) +data ATSGen = ATSGen { hsFile :: FilePath -- ^ Haskell file containing types+ , _atsTarget :: FilePath -- ^ ATS file to be generated+ , cpphs :: Bool -- ^ Whether to use the C preprocessor on the Haskell code+ } deriving (Generic, Binary)+ -- | Type for binary and library builds with ATS.-data ATSTarget = ATSTarget { cFlags :: [String] -- ^ Flags to be passed to the C compiler- , toolConfig :: ATSToolConfig- , gc :: Bool -- ^ Whether to configure build for use with the garbage collector.- , libs :: [String] -- ^ Libraries against which to link- , 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@.- , linkTargets :: [(String, String)] -- ^ Targets for @_link.hats@ generation.- , binTarget :: String -- ^ Binary target- , otherDeps :: [String] -- ^ Other files necessary to compile target- , tgtType :: ArtifactType -- ^ Build type+data ATSTarget = ATSTarget { _cFlags :: [String] -- ^ Flags to be passed to the C compiler+ , _toolConfig :: ATSToolConfig -- ^ Configuration options for @patsopt@+ , _gc :: Bool -- ^ Whether to build with the garbage collection enabled+ , _libs :: [String] -- ^ Libraries against which to link+ , _src :: [FilePath] -- ^ ATS source files. If building an executable, at most one may contain @main0@.+ , _hsLibs :: [ForeignCabal] -- ^ Cabal-based Haskell libraries.+ , _genTargets :: [ATSGen] -- ^ Files to be run through @hs2ats@.+ , _linkTargets :: [(FilePath, FilePath)] -- ^ Targets for @_link.hats@ generation.+ , _binTarget :: FilePath -- ^ Target+ , _otherDeps :: [FilePath] -- ^ Other files to track.+ , _tgtType :: ArtifactType -- ^ Build type } deriving (Generic, Binary) --- | Data type containing information about Haskell components of a build.+-- | Data type containing information about Haskell components of a build. Any+-- functions exposed in the object file will be callable in C or ATS code. data ForeignCabal = ForeignCabal { projectFile :: Maybe TL.Text -- ^ @cabal.project@ file to track , cabalFile :: TL.Text -- ^ @.cabal@ file associated with the library , objectFile :: TL.Text -- ^ Object file to be generated- } deriving (Eq, Show, Generic, Binary)+ } deriving (Eq, Show, Generic, Binary, Hashable)++makeLenses ''ATSGen+makeLenses ''ATSTarget+makeLenses ''ATSToolConfig