ghcflags (empty) → 1.0.0
raw patch · 3 files changed
+131/−0 lines, 3 filesdep +basedep +directorydep +ghc
Dependencies added: base, directory, ghc
Files
- GhcFlags/Plugin.hs +82/−0
- LICENSE +9/−0
- ghcflags.cabal +40/−0
+ GhcFlags/Plugin.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE CPP #-}++-- | A ghc plugin that creates `.ghc.flags` files (and `.ghc.version`) populated+-- with the flags that were last used to invoke ghc for some modules, for+-- consumption by tools that need to know the build parameters.+--+-- https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/extending_ghc.html#compiler-plugins+module GhcFlags.Plugin+ ( plugin,+ )+where++import qualified Config as GHC+import Control.Monad (when)+import Control.Monad.IO.Class (liftIO)+import Data.Foldable (traverse_)+import Data.List (stripPrefix)+import qualified GHC+import qualified GhcPlugins as GHC+import System.Directory (doesFileExist)+import System.Environment+import System.IO.Error (catchIOError)++plugin :: GHC.Plugin+plugin =+ GHC.defaultPlugin+ { GHC.installCoreToDos = install+#if MIN_VERSION_GLASGOW_HASKELL(8, 6, 0, 0)+ , GHC.pluginRecompile = GHC.purePlugin+#endif+ }++install :: [GHC.CommandLineOption] -> [GHC.CoreToDo] -> GHC.CoreM [GHC.CoreToDo]+install _ core = do+ dflags <- GHC.getDynFlags+ args <- liftIO $ getArgs++ -- downstream tools shouldn't use this plugin, or all hell will break loose+ let ghcFlags = unwords $ replace ["-fplugin", "GhcFlags.Plugin"] [] args++ -- TODO this currently only supports ghc being called with directories and+ -- home modules, we should also support calling with explicit file names.+ paths = GHC.importPaths dflags+ writeGhcFlags path = writeDifferent (path <> "/.ghc.flags") ghcFlags+ enable = case GHC.hscTarget dflags of+ GHC.HscInterpreted -> False+ GHC.HscNothing -> False+ _ -> True++ when enable $ liftIO $ do+ traverse_ writeGhcFlags paths+ writeDifferent ".ghc.version" GHC.cProjectVersion++ pure core++-- only writes out the file when it will result in changes, and silently fails+-- on exceptions because the plugin should never interrupt normal ghc work.+writeDifferent :: FilePath -> String -> IO ()+writeDifferent file content =+ ignoreIOExceptions+ $ whenM isDifferent (writeFile file content)+ where+ isDifferent =+ ifM (doesFileExist file) ((content /=) <$> readFile file) (pure True)++-- from Data.List.Extra+replace :: Eq a => [a] -> [a] -> [a] -> [a]+replace [] _ _ = error "Extra.replace, first argument cannot be empty"+replace from to xs | Just xs' <- stripPrefix from xs = to ++ replace from to xs'+replace from to (x : xs) = x : replace from to xs+replace _ _ [] = []++-- from Control.Monad.Extra+whenM :: Monad m => m Bool -> m () -> m ()+whenM b t = ifM b t (return ())++ifM :: Monad m => m Bool -> m a -> m a -> m a+ifM b t f = do b' <- b; if b' then t else f++-- from System.Directory.Internal+ignoreIOExceptions :: IO () -> IO ()+ignoreIOExceptions io = io `catchIOError` (\_ -> pure ())
+ LICENSE view
@@ -0,0 +1,9 @@+Copyright 2019 Tseen She++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ghcflags.cabal view
@@ -0,0 +1,40 @@+cabal-version: 2.2+name: ghcflags+version: 1.0.0+synopsis: Dump the ghc flags during compilation+license: BSD-2-Clause+license-file: LICENSE+author: Tseen She+maintainer: Tseen She+copyright: 2019 Tseen She+bug-reports: https://gitlab.com/tseenshe/hsinspect/merge_requests+tested-with: GHC ^>=8.4.4 || ^>=8.6.5+category: Building+description:+ Generate @.ghc.flags@ and @.ghc.version@ files during compilation++source-repository head+ type: git+ location: https://gitlab.com/tseenshe/hsinspect.git++-- https://www.haskell.org/cabal/users-guide/cabal-projectindex.html++common deps+ build-depends:+ , base >=4.11 && <5+ , directory+ , ghc++ -- , containers+ -- , ghc-boot+ -- , time++ ghc-options: -Wall -Werror=missing-home-modules+ default-language: Haskell2010++library+ import: deps+ hs-source-dirs: .++ -- cabal-fmt: expand plugin+ exposed-modules: GhcFlags.Plugin