ghc-stdin (empty) → 0.1.0.0
raw patch · 6 files changed
+195/−0 lines, 6 filesdep +basedep +ghcdep +ghc-pathssetup-changed
Dependencies added: base, ghc, ghc-paths, process, temporary
Files
- Changelog.md +4/−0
- GhcStdin.hs +83/−0
- LICENSE +28/−0
- README.md +44/−0
- Setup.hs +3/−0
- ghc-stdin.cabal +33/−0
+ Changelog.md view
@@ -0,0 +1,4 @@+### 0.1.0.0++- Initial version.+
+ GhcStdin.hs view
@@ -0,0 +1,83 @@+-----------------------------------------------------------------------------+-- |+-- Module : GhcStdin+-- Copyright : (c) Alexey Radkov 2022+-- License : BSD-style+--+-- Maintainer : alexey.radkov@gmail.com+-- Stability : experimental+-- Portability : non-portable (requires GHC with support of plugins)+--+-- A frontend plugin for GHC to compile source code from the standard input.+--+-----------------------------------------------------------------------------+++module GhcStdin (frontendPlugin) where++import GHC.Paths+#if MIN_VERSION_ghc(9,0,2)+import GHC.Plugins+#else+import GhcPlugins+#endif+import Control.Monad+import System.IO+import System.IO.Temp+import System.Process+import System.Exit++-- | Frontend plugin for GHC to compile source code from the standard input.+--+-- In GHC, it is not possible to read source code from the standard input.+--+-- @+-- __$__ echo \'module Main where main = putStrLn \"Ok\"\' | ghc -o simple_ok+-- ghc-9.2.3: no input files+-- Usage: For basic information, try the \`--help\' option.+-- @+--+-- This plugin makes this possible.+--+-- @+-- __$__ echo \'module Main where main = putStrLn \"Ok\"\' | ghc __/--frontend GhcStdin/__ /-ffrontend-opt=\"-o simple_ok\"/+-- [1 of 1] Compiling Main ( ghc-stdin-d8c31cf0ed893d79\/ghc-stdin260612-0.hs, ghc-stdin-d8c31cf0ed893d79\/ghc-stdin260612-0.o )+-- Linking simple_ok ...+-- __$__ ./simple_ok+-- Ok+-- @+--+-- Notice that GHC flags are passed via /-ffrontend-opt/ in a single string.+--+-- Another use case is collecting exported FFI C functions from a module and+-- putting them in a new shared library.+--+-- @+-- __$__ export NGX_MODULE_PATH=\/var\/lib\/nginx\/x86_64-linux-ghc-9.2.3+-- __$__ echo \'module NgxHealthcheck where import NgxExport.Healthcheck ()\' | ghc __/--frontend GhcStdin/__ /-ffrontend-opt=\"-Wall -O2 -dynamic -shared -fPIC -lHSrts_thr-ghc$(ghc --numeric-version) -L$NGX_MODULE_PATH -lngx_healthcheck_plugin -o ngx_healthcheck.so\"/ +-- [1 of 1] Compiling NgxHealthcheck ( ghc-stdin-74de48274545714b\/ghc-stdin266454-0.hs, ghc-stdin-74de48274545714b\/ghc-stdin266454-0.o )+-- Linking ngx_healthcheck.so ...+-- @+--+-- (this is a real-world example taken from+-- [nginx-healthcheck-plugin](https://github.com/lyokha/nginx-healthcheck-plugin)).+--+-- Internally, the plugin creates a temporary directory with a temporary source+-- file inside it with the contents read from the standard input. Then it spawns+-- another GHC process to compile this file with options passed in+-- /-ffrontend-opt/.+frontendPlugin :: FrontendPlugin+frontendPlugin = defaultFrontendPlugin { frontend = compileCodeFromStdin }++compileCodeFromStdin :: FrontendPluginAction+compileCodeFromStdin flags _ = liftIO $+ withTempDirectory "." "ghc-stdin" $ \dir ->+ withTempFile dir "ghc-stdin.hs" $ \src hsrc -> do+ contents <- getContents+ hPutStr hsrc contents >> hFlush hsrc+ (_, _, _, h) <- createProcess $ proc ghc $ src : wordsOfHead flags+ r <- waitForProcess h+ unless (r == ExitSuccess) $ exitWith r+ where wordsOfHead [] = []+ wordsOfHead (x : _) = words x+
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright 2022 Alexey Radkov++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.++3. Neither the name of the copyright holder nor the names of its+contributors may be used to endorse or promote products derived from+this software without specific prior written permission.++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.
+ README.md view
@@ -0,0 +1,44 @@+GHC frontend plugin GhcStdin+============================++[](https://github.com/lyokha/ghc-stdin/actions?query=workflow%3ACI)+[](https://hackage.haskell.org/package/ghc-stdin)++In GHC, it is not possible to read source code from the standard input.++```ShellSession+$ echo 'module Main where main = putStrLn "Ok"' | ghc -o simple_ok+ghc-9.2.3: no input files+Usage: For basic information, try the `--help' option.+```++This plugin makes this possible.++```ShellSession+$ echo 'module Main where main = putStrLn "Ok"' | ghc --frontend GhcStdin -ffrontend-opt="-o simple_ok"+[1 of 1] Compiling Main ( ghc-stdin-d8c31cf0ed893d79/ghc-stdin260612-0.hs, ghc-stdin-d8c31cf0ed893d79/ghc-stdin260612-0.o )+Linking simple_ok ...+$ ./simple_ok+Ok+```++Notice that GHC flags are passed via *-ffrontend-opt* in a single string.++Another use case is collecting exported FFI C functions from a module and+putting them in a new shared library.++```ShellSession+$ export NGX_MODULE_PATH=/var/lib/nginx/x86_64-linux-ghc-9.2.3+$ echo 'module NgxHealthcheck where import NgxExport.Healthcheck ()' | ghc --frontend GhcStdin -ffrontend-opt="-Wall -O2 -dynamic -shared -fPIC -lHSrts_thr-ghc$(ghc --numeric-version) -L$NGX_MODULE_PATH -lngx_healthcheck_plugin -o ngx_healthcheck.so" +[1 of 1] Compiling NgxHealthcheck ( ghc-stdin-74de48274545714b/ghc-stdin266454-0.hs, ghc-stdin-74de48274545714b/ghc-stdin266454-0.o )+Linking ngx_healthcheck.so ...+```++(this is a real-world example taken from+[nginx-healthcheck-plugin](https://github.com/lyokha/nginx-healthcheck-plugin)).++Internally, the plugin creates a temporary directory with a temporary source+file inside it with the contents read from the standard input. Then it spawns+another GHC process to compile this file with options passed in+*-ffrontend-opt*.+
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple+main = defaultMain+
+ ghc-stdin.cabal view
@@ -0,0 +1,33 @@+name: ghc-stdin+version: 0.1.0.0+license: BSD3+license-file: LICENSE+extra-source-files: Changelog.md, README.md+author: Alexey Radkov+maintainer: alexey.radkov@gmail.com+synopsis: Compile source code from the standard input+description: A frontend plugin for GHC to compile source code from+ the standard input.+category: Development+bug-reports: https://github.com/lyokha/ghc-stdin/issues+build-type: Simple+cabal-version: 1.20++source-repository head+ type: git+ location: https://github.com/lyokha/ghc-stdin++library+ default-language: Haskell2010+ build-depends: base >= 4.11.0.0 && < 5,+ ghc >= 8.4.1,+ ghc-paths,+ temporary,+ process++ exposed-modules: GhcStdin++ default-extensions: CPP++ ghc-options: -Wall+