shake-ats 1.5.0.6 → 1.5.0.7
raw patch · 5 files changed
+137/−154 lines, 5 filesdep ~language-atsdep ~shake-ext
Dependency ranges changed: language-ats, shake-ext
Files
- shake-ats.cabal +52/−45
- src/Development/Shake/ATS.hs +49/−82
- src/Development/Shake/ATS/Generate.hs +1/−1
- src/Development/Shake/ATS/Rules.hs +22/−12
- src/Development/Shake/ATS/Type.hs +13/−14
shake-ats.cabal view
@@ -1,48 +1,55 @@-name: shake-ats-version: 1.5.0.6-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-license: BSD3-license-file: LICENSE-author: Vanessa McHale-maintainer: vamchale@gmail.com-copyright: Copyright: (c) 2018 Vanessa McHale-category: Development, Build, ATS, Shake-build-type: Simple-extra-doc-files: README.md-cabal-version: 1.18+cabal-version: 1.18+name: shake-ats+version: 1.5.0.7+license: BSD3+license-file: LICENSE+copyright: Copyright: (c) 2018 Vanessa McHale+maintainer: vamchale@gmail.com+author: Vanessa McHale+homepage: https://github.com/vmchale/shake-ats#readme+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+category: Development, Build, ATS, Shake+build-type: Simple+extra-doc-files: README.md -Flag development {- Description: Enable `-Werror`- manual: True- default: False-}+source-repository head+ type: darcs+ location: https://hub.darcs.net/vmchale/ats -library- hs-source-dirs: src- exposed-modules: Development.Shake.ATS- other-modules: Development.Shake.ATS.Type- , Development.Shake.ATS.Rules- , Development.Shake.ATS.Environment- , Development.Shake.ATS.Generate- build-depends: base >= 4.7 && < 5- , language-ats >= 0.3.0.3- , shake-ext >= 2.6.0.0- , hs2ats >= 0.2.0.1- , directory- , microlens- , text- , dependency- , shake- , binary- default-language: Haskell2010- if flag(development)- ghc-options: -Werror- if impl(ghc >= 8.0)- ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat- ghc-options: -Wall+flag development+ description:+ Enable `-Werror`+ default: False+ manual: True -source-repository head- type: darcs- location: https://hub.darcs.net/vmchale/ats+library+ exposed-modules:+ Development.Shake.ATS+ hs-source-dirs: src+ other-modules:+ Development.Shake.ATS.Type+ Development.Shake.ATS.Rules+ Development.Shake.ATS.Environment+ Development.Shake.ATS.Generate+ default-language: Haskell2010+ ghc-options: -Wall+ build-depends:+ base >=4.7 && <5,+ language-ats,+ shake-ext >=2.7.0.0,+ hs2ats >=0.2.0.1,+ directory -any,+ microlens -any,+ text -any,+ dependency -any,+ shake -any,+ binary -any+ + if flag(development)+ ghc-options: -Werror+ + if impl(ghc >=8.0)+ ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates+ -Wcompat
src/Development/Shake/ATS.hs view
@@ -5,27 +5,22 @@ {-# LANGUAGE TypeSynonymInstances #-} module Development.Shake.ATS ( -- * Shake Rules- cgen- , cgenPretty- , cleanATS+ cleanATS , atsBin , atsLex , cabalExport- -- * Actions- , patsHome+ , cgen+ , genATS -- * Helper functions , getSubdirs- , ccToString- , ccFromString , ccToDir- , compatible- , host+ , withPF+ -- * Environment/configuration , patscc , patsopt -- Types- , Version (..) , ForeignCabal (..)- , BinaryTarget (..)+ , ATSTarget (..) , ATSToolConfig (..) , CCompiler (..) , ArtifactType (..)@@ -53,12 +48,6 @@ import System.Environment (getEnv) import System.Exit (ExitCode (ExitSuccess)) --- | Whether generated libraries are to be considered compatible.-compatible :: CCompiler -> CCompiler -> Bool-compatible GCCStd Clang = True-compatible Clang GCCStd = True-compatible x y = x == y- -- | Run @patsopt@ given information about various things atsCommand :: CmdResult r => ATSToolConfig -> String -- ^ Source file@@ -67,11 +56,21 @@ atsCommand tc sourceFile out = do path <- liftIO $ getEnv "PATH" home' <- home tc- h <- liftIO $ getEnv "HOME"- let env = patsEnv h home' path+ let env = patsEnv home' path patsc <- patsopt tc+ 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+ ret@(Exit c, Stderr err, Stdout _) <- act :: Action (Exit, Stderr String, Stdout String)+ cmd_ [Stdin err] Shell "pats-filter"+ if c /= ExitSuccess+ then error "patsopt failure"+ else pure ret+ gcFlag :: Bool -> String gcFlag False = "-DATS_MEMALLOC_LIBC" gcFlag True = "-DATS_MEMALLOC_GCBDW"@@ -86,9 +85,10 @@ liftIO $ createDirectoryIfMissing True (home' ++ "/" ++ takeDirectory dep) liftIO $ copyFile dep (home' ++ "/" ++ dep) --- This is the @$PATSHOMELOCS@ variable to be passed to the shell.-patsHomeLocs :: FilePath -> Int -> String-patsHomeLocs _ n = intercalate ":" $ (<> ".atspkg/contrib") . ("./" <>) <$> g+-- | 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 <- [0..n] ] makeCFlags :: [String] -- ^ Inputs@@ -129,6 +129,7 @@ h' <- pkgHome cc' home' <- home tc 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 home :: MonadIO m => ATSToolConfig -> m String@@ -136,11 +137,11 @@ h <- patsHome (compilerVer tc) pure $ h ++ "lib/ats2-postiats-" ++ show (libVersion tc) -patsEnv :: FilePath -> FilePath -> FilePath -> [CmdOption]-patsEnv h home' path = EchoStderr False :+patsEnv :: FilePath -> FilePath -> [CmdOption]+patsEnv home' path = EchoStderr False : zipWith AddEnv ["PATSHOME", "PATH", "PATSHOMELOCS"]- [home', home' ++ "/bin:" ++ path, patsHomeLocs h 5]+ [home', home' ++ "/bin:" ++ path, patsHomeLocs 5] atsToC :: FilePath -> FilePath atsToC = (-<.> "c") . (".atspkg/c/" <>)@@ -154,17 +155,14 @@ doLib Executable = pure mempty doLib _ = id -atsBin :: BinaryTarget -> Rules ()-atsBin tgt@BinaryTarget{..} = do+atsBin :: ATSTarget -> Rules ()+atsBin ATSTarget{..} = do - unless (null linkTargets) $- mapM_ (uncurry genLinks) linkTargets+ mapM_ (uncurry genLinks) linkTargets - unless (null genTargets) $- mapM_ (uncurry3 genATS) genTargets+ mapM_ (uncurry3 genATS) genTargets - unless (null hsLibs) $- mapM_ cabalExport hsLibs+ mapM_ cabalExport hsLibs let cTargets = atsToC <$> src @@ -178,7 +176,9 @@ cconfig' <- cconfig toolConfig libs gc (makeCFlags cFlags mempty (pure undefined) gc) - zipWithM_ (atsCGen toolConfig tgt) src cTargets+ let atsGen = (snd <$> linkTargets) <> ((^._2) <$> genTargets)+ atsExtras = otherDeps <> (TL.unpack . objectFile <$> hsLibs)+ zipWithM_ (cgen toolConfig atsExtras atsGen) src cTargets doLib tgtType (zipWithM_ (objectFileR (cc toolConfig) cconfig') cTargets (h' cTargets)) @@ -192,73 +192,40 @@ unit $ g tgtType (cc toolConfig) (h' cTargets) binTarget cconfig'' -atsCGen :: ATSToolConfig- -> BinaryTarget- -> FilePath -- ^ ATS source- -> FilePattern -- ^ Pattern for C file to be generated- -> Rules ()-atsCGen tc BinaryTarget{..} atsSrc cFiles =+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 = 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 ((snd <$> linkTargets) <> ((^._2) <$> genTargets)) [atsSrc]- need sources- copySources tc sources-- atsCommand tc atsSrc out--cgen :: ATSToolConfig- -> [String] -- ^ Additional source files- -> FilePath -- ^ Directory containing ATS source code- -> Rules ()-cgen tc extras dir =-- "//*.c" %> \out -> do need extras- let sourceFile = dir ++ "/" ++ (takeBaseName out -<.> "dats")- handleSource tc sourceFile- atsCommand tc sourceFile out+ sources <- transitiveDeps atsGens [atsSrc]+ need sources+ copySources toolConfig sources -handleSource :: ATSToolConfig -> FilePath -> Action ()-handleSource tc sourceFile = do- sources <- transitiveDeps [] [sourceFile]- need sources- copySources tc sources+ atsCommand toolConfig atsSrc out -- | This provides rules for generating C code from ATS source files in the trim :: String -> String trim = init . drop 1 -- | Print any errors to standard error.-maybeError :: (MonadIO m) => Either ATSError b -> m ()-maybeError Right{} = pure ()-maybeError (Left y) = printErr y+maybeError :: (MonadIO m) => FilePath -> Either ATSError b -> m ()+maybeError _ Right{} = pure ()+maybeError p (Left y) = warnErr p y 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, err) = (fromRight mempty &&& maybeError) . parse $ contents+ let (ats, err) = (fromRight mempty &&& maybeError p) . parseM $ contents err let dir = takeDirectory p deps <- filterM (\f -> ((f `elem` gen) ||) <$> (liftIO . doesFileExist) f) $ fixDir dir . trim <$> getDependencies ats deps' <- transitiveDeps gen deps pure $ (p:deps) ++ deps'---- | This uses @pats-filter@ to prettify the errors.-cgenPretty :: ATSToolConfig- -> FilePath- -> Rules ()-cgenPretty tc dir =-- "//*.c" %> \out -> do-- let sourceFile = dir ++ "/" ++ (takeBaseName out -<.> "dats")- handleSource tc sourceFile- (Exit c, Stderr err, Stdout _) :: (Exit, Stderr String, Stdout String) <- atsCommand tc sourceFile out- cmd_ [Stdin err] Shell "pats-filter"- if c /= ExitSuccess- then error "patscc failure"- else pure ()
src/Development/Shake/ATS/Generate.hs view
@@ -6,7 +6,7 @@ import Lens.Micro generateLinks :: String -> Either ATSError String-generateLinks = fmap (printATS . generateLinks') . parse+generateLinks = fmap (printATS . generateLinks') . parseM generateLinks' :: ATS a -> ATS a generateLinks' (ATS ds) = ATS (fmap g ds <> [macDecl]) -- ATS [Local undefined (ATS (fmap g ds <> [macDecl])) (ATS mempty)]
src/Development/Shake/ATS/Rules.hs view
@@ -7,19 +7,19 @@ ) where import Control.Monad-import Data.List (isPrefixOf) import Data.Semigroup (Semigroup (..)) import qualified Data.Text.Lazy as TL import Development.Shake hiding (doesDirectoryExist) import Development.Shake.ATS.Generate-import Development.Shake.ATS.Type hiding (BinaryTarget (..))+import Development.Shake.ATS.Type hiding (ATSTarget (..)) import Development.Shake.Cabal import Development.Shake.FilePath+import Development.Shake.Version import Language.ATS.Generate import System.Directory -- | Given a plain Haskell source file, generate a @.sats@ file containing--- analogous types.+-- the equivalent types. genATS :: FilePath -- ^ Haskell source -> FilePath -- ^ @.sats@ file to generate -> Bool -- ^ Whether to call cpphs preprocessor@@ -46,7 +46,12 @@ ss <- mapM getSubdirs ds' pure $ ds' <> join ss --- TODO cabal exports can happen concurrently w/ compiler & whatnot+-- 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 () cabalExport (ForeignCabal cbp' cf' obf') = do @@ -56,27 +61,32 @@ obfDir = takeDirectory (obf -<.> "hs") libName = takeBaseName cf - trDeps <- liftIO $ getCabalDeps cf+ (v, trDeps) <- liftIO $ getCabalDeps cf obf %> \out -> do need (cf : fmap ((obfDir <> "/") <>) trDeps)- command_ [Cwd obfDir] "cabal" ["new-build", "all", "-O2"]+ command_ [Cwd obfDir] "cabal" ["new-build", "all"] + ghcV <- quietly ghcVersion let subdir = takeDirectory cbp ++ "/"- correctDir = (libName `isPrefixOf`)+ correctDir = (== "build") endsBuild = correctDir . last . splitPath- dir <- filter endsBuild <$> liftIO (getSubdirs $ subdir ++ "dist-newstyle/build")- let obj = head dir ++ "/opt/build/" ++ takeFileName obf+ pkgDir = subdir ++ "dist-newstyle/build/" ++ platform ++ "/ghc-" ++ ghcV ++ "/" ++ libName ++ "-" ++ showVersion v ++ "/"++ dir <- filter endsBuild <$> liftIO (getSubdirs pkgDir)+ let obj = head dir ++ "/" ++ takeFileName obf liftIO $ copyFile obj out let hdr = dropExtension obj ++ "_stub.h" liftIO $ copyFile hdr (takeDirectory out ++ "/" ++ takeFileName hdr) -- | Build a @.lats@ file.-atsLex :: FilePattern -> Rules ()-atsLex fp =+atsLex :: FilePath -- ^ Filepath of @.lats@ file+ -> FilePattern -- ^ File pattern for generated output+ -> Rules ()+atsLex latsIn fp = fp %> \out -> do- lats <- liftIO $ readFile (out -<.> "lats")+ lats <- liftIO $ readFile latsIn (Stdout contents) <- command [Stdin lats] "atslex" [] liftIO $ writeFile out contents
src/Development/Shake/ATS/Type.hs view
@@ -5,7 +5,7 @@ module Development.Shake.ATS.Type ( ForeignCabal (..) , Version (..)- , BinaryTarget (..)+ , ATSTarget (..) , ArtifactType (..) , ATSToolConfig (..) ) where@@ -59,19 +59,18 @@ } deriving (Generic, Binary) -- | Type for binary and library builds with ATS.-data BinaryTarget = BinaryTarget { 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- , cDeps :: [String] -- ^ C files necessary to compile the target- , otherDeps :: [String] -- ^ Other files necessary to compile target- , tgtType :: ArtifactType -- ^ Build type- } deriving (Generic, Binary)+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+ } deriving (Generic, Binary) -- | Data type containing information about Haskell components of a build. data ForeignCabal = ForeignCabal { projectFile :: Maybe TL.Text -- ^ @cabal.project@ file to track