packages feed

ngx-export-distribution (empty) → 0.1.0.0

raw patch · 5 files changed

+281/−0 lines, 5 filesdep +Cabaldep +basedep +filepathsetup-changed

Dependencies added: Cabal, base, filepath

Files

+ Changelog.md view
@@ -0,0 +1,4 @@+### 0.1.0.0++- Initial version.+
+ LICENSE view
@@ -0,0 +1,25 @@+The following license covers this documentation, and the source code, except+where otherwise indicated.++Copyright 2018-2021, Alexey Radkov. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* 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 "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 HOLDERS 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.
+ NgxExport/Distribution.hs view
@@ -0,0 +1,222 @@+{-# LANGUAGE TupleSections #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  NgxExport.Distribution+-- Copyright   :  (c) Alexey Radkov 2021+-- License     :  BSD-style+--+-- Maintainer  :  alexey.radkov@gmail.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Quick and dirty build of simple shared libraries and collecting+-- dependencies. This was designed to build custom Haskell handlers for+-- <http://github.com/lyokha/nginx-haskell-module nginx-haskell-module>.+--+-----------------------------------------------------------------------------+++module NgxExport.Distribution (+    -- * Usage and examples+    -- $usage+                               defaultMain+                              ) where++import Distribution.Simple hiding (defaultMain)+import Distribution.Simple.LocalBuildInfo+import Distribution.Simple.Program.Builtin+import Distribution.Simple.Program.Run+import Distribution.Simple.Program.Db+import Distribution.Simple.Program+import Distribution.Simple.Setup+import Distribution.Types.PackageDescription+import Distribution.Types.BuildInfo+import Distribution.Types.Library+import Distribution.Verbosity+import Distribution.Pretty+import System.FilePath+import Control.Exception+import Control.Arrow+import Control.Monad+import Data.Maybe++-- $usage+--+-- This module allows for building simple shared libraries with Cabal.+--+-- Below is a simple example.+--+-- ==== File /ngx_distribution_test.hs/+-- @+-- {-\# LANGUAGE TemplateHaskell \#-}+--+-- module NgxDistributionTest where+--+-- import           NgxExport+--+-- import           Data.ByteString (ByteString)+-- import qualified Data.ByteString.Lazy.Char8 as C8L+-- import           Data.Aeson+-- import           Data.Maybe+--+-- incCnt :: ByteString -> C8L.ByteString+-- incCnt = C8L.pack . show . succ . fromMaybe (0 :: Int) . decodeStrict+-- ngxExportYY \'incCnt+-- @+--+-- ==== File /ngx-distribution-test.cabal/+-- @+-- name:                       ngx-distribution-test+-- version:                    0.1.0.0+-- build-type:                 __/Custom/__+-- cabal-version:              1.20+--+-- library+--   default-language:         Haskell2010+--   build-depends:            base >= 4.8 && < 5+--                           , ngx-export+--                           , ngx-export-distribution+--                           , bytestring+--                           , aeson+--+--   ghc-options:             -Wall -O2 -no-keep-hi-files -no-keep-o-files+-- @+--+-- ==== File /ngx-distribution-test.cabal/+-- @+-- import __/NgxExport.Distribution/__+-- main = 'defaultMain'+-- @+--+-- The configuration step requires that utilities /patchelf/ and+-- <https://github.com/lyokha/nginx-haskell-module/blob/master/utils/hslibdeps hslibdeps>+-- were found in /$PATH/.+--+-- Building is a bit cumbersome: it expects explicit option /--prefix/ at the+-- configuration step (which will be interpreted as the first part of the+-- /rpath/ by utility /hslibdeps/), and requires explicit ghc option /-o/ at+-- the build step which is as well used by /hslibdeps/ as the name of the+-- target library. The build also requires the explicit option for linkage+-- against the Haskell RTS library.+--+-- Let's build the example with commands /cabal v1-configure/ and+-- /cabal v1-build/ (the /v2-/commands should probably work as well).+--+-- > $ cabal v1-configure --prefix=/var/lib/nginx+-- > Resolving dependencies...+-- > [1 of 1] Compiling Main             ( dist/setup/setup.hs, dist/setup/Main.o )+-- > Linking ./dist/setup/setup ...+-- > Configuring ngx-distribution-test-0.1.0.0...+--+-- > $ cabal v1-build --ghc-options="ngx_distribution_test.hs -o ngx_distribution_test.so -lHSrts_thr-ghc$(ghc --numeric-version)"+-- > [1 of 1] Compiling NgxDistributionTest ( ngx_distribution_test.hs, ngx_distribution_test.o )+-- > Linking ngx_distribution_test.so ...+-- > ---> Collecting libraries+-- > '/usr/lib64/libHSrts_thr-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSrts_thr-ghc8.10.5.so'+-- > '/home/lyokha/.cabal/lib/x86_64-linux-ghc-8.10.5/libHSngx-export-1.7.5-JzTEmHewqdC9gGi6rzcAtt-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSngx-export-1.7.5-JzTEmHewqdC9gGi6rzcAtt-ghc8.10.5.so'+-- > '/home/lyokha/.cabal/lib/x86_64-linux-ghc-8.10.5/libHSmonad-loops-0.4.3-8Lx5Hn3pTtO62yOPdPW77x-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSmonad-loops-0.4.3-8Lx5Hn3pTtO62yOPdPW77x-ghc8.10.5.so'+-- > '/home/lyokha/.cabal/lib/x86_64-linux-ghc-8.10.5/libHSasync-2.2.4-ENjuIeC23kaKyMVDRYThP3-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSasync-2.2.4-ENjuIeC23kaKyMVDRYThP3-ghc8.10.5.so'+-- > '/usr/lib64/libHSstm-2.5.0.1-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSstm-2.5.0.1-ghc8.10.5.so'+-- > '/home/lyokha/.cabal/lib/x86_64-linux-ghc-8.10.5/libHSaeson-1.5.6.0-6XeGmWHoO3vJYEUW5PXPgC-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSaeson-1.5.6.0-6XeGmWHoO3vJYEUW5PXPgC-ghc8.10.5.so'+-- >+-- >    ...+-- >+-- > '/usr/lib64/libHSbase-4.14.2.0-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSbase-4.14.2.0-ghc8.10.5.so'+-- > '/usr/lib64/libHSinteger-gmp-1.0.3.0-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSinteger-gmp-1.0.3.0-ghc8.10.5.so'+-- > '/usr/lib64/libHSghc-prim-0.6.1-ghc8.10.5.so' -> 'x86_64-linux-ghc-8.10.5/libHSghc-prim-0.6.1-ghc8.10.5.so'+-- >+-- > ---> Patching ngx_distribution_test.so+-- > /var/lib/nginx/x86_64-linux-ghc-8.10.5:/home/lyokha/.cabal/lib/x86_64-linux-ghc-8.10.5:/usr/lib64:/usr/lib64/ghc-8.10.5/rts+--+-- Now the current working directory contains new files+-- /ngx_distribution_test.so/ and /ngx_distribution_test-0.1.0.0.tar.gz/ and a+-- new directory /x86_64-linux-ghc-8.10.5/. The tar-file contains the patched+-- shared library and the directory with dependent libraries: it is ready for+-- installation in directory /\/var\/lib\/nginx/ at the target system.+--+-- With this building approach, the following list of drawbacks must be taken+-- into account.+--+-- 1. Utility /hslibdeps/ collects only libraries prefixed with /libHS/.+-- 2. Command /cabal v1-clean/ only deletes directory /dist/, it does not+--    delete build artifacts in the current working directory.+-- 3. Behavior of Cabal commands other than /configure/, /build/ and /clean/ is+--    not well defined.++data LibNameNotSpecified = LibNameNotSpecified++instance Exception LibNameNotSpecified+instance Show LibNameNotSpecified where+    show = const "Error: the library name was not specified, \+                 \the name must be passed in ghc with option -o"++hslibdeps :: Program+hslibdeps = simpleProgram "hslibdeps"++patchelf :: Program+patchelf = simpleProgram "patchelf"++buildAndHslibdeps :: Verbosity -> PackageDescription -> LocalBuildInfo ->+    BuildFlags -> IO ()+buildAndHslibdeps verbosity desc lbi flags = do+    let configGhcOptions =+            map (("ghc", ) . pure) . concatMap snd+            . filter (\(c, o) -> c == GHC && not (null o)) $+                perCompilerFlavorToList $+                    options $ libBuildInfo $ fromJust $ library desc+        lib = fst $+            foldl (\a@(r, ready) (prog, v) ->+                if prog /= "ghc" || null v || isJust r+                    then a+                    else let v' = head v+                         in if v' == "-o"+                                then (Nothing, True)+                                else if ready+                                         then (Just v', False)+                                         else (Nothing, False)+                  ) (Nothing, False) $+                      buildProgramArgs flags ++ configGhcOptions+        env = map (second fromPathTemplate) $+            compilerTemplateEnv (compilerInfo $ compiler lbi) +++                platformTemplateEnv (hostPlatform lbi)+        dir = maybeUnknown (lookup ArchVar env) +++            '-' : maybeUnknown (lookup OSVar env) +++                '-' : maybeUnknown (lookup CompilerVar env)+        dirArg = "-d" : [dir]+        maybeUnknown = fromMaybe "unknown"+        rpathArg = maybe [] (("-t" :) . pure . (</> dir) . fromPathTemplate) $+            flagToMaybe $ prefix $ configInstallDirs $ configFlags lbi+    when (isNothing lib) $ throwIO LibNameNotSpecified+    let lib' = fromJust lib+        plbi = withPrograms lbi+    ghcP <- fst <$> requireProgram verbosity ghcProgram plbi+    let ghcR = programInvocation ghcP $ ["-dynamic", "-shared", "-fPIC"] +++            map (head . snd) configGhcOptions+    runProgramInvocation verbosity ghcR+    hslibdepsP <- fst <$> requireProgram verbosity hslibdeps plbi+    let hslibdepsR = programInvocation hslibdepsP $ lib' : rpathArg ++ dirArg+    runProgramInvocation verbosity hslibdepsR+    tarP <- fst <$> requireProgram verbosity tarProgram plbi+    let ver = pkgVersion $ package desc+        tar = addExtension (takeBaseName lib' ++ '-' : prettyShow ver) "tar.gz"+        tarR = programInvocation tarP ["czf", tar, lib', dir]+    runProgramInvocation verbosity tarR++ngxExportHooks :: UserHooks+ngxExportHooks =+    let hooks = simpleUserHooks+    in hooks { hookedPrograms = [hslibdeps]+             , confHook = \desc flags -> do+                 let pdb = configPrograms flags+                 _ <- requireProgram normal hslibdeps pdb >>=+                          requireProgram normal patchelf . snd+                 confHook simpleUserHooks desc flags+             , buildHook =  \desc lbi _ flags ->+                 buildAndHslibdeps normal desc lbi flags+             }++-- | A simple implementation of /main/ for a Cabal setup script.+defaultMain :: IO ()+defaultMain = defaultMainWithHooks ngxExportHooks+
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple+main = defaultMain+
+ ngx-export-distribution.cabal view
@@ -0,0 +1,27 @@+name:                       ngx-export-distribution+version:                    0.1.0.0+synopsis:                   Build custom libraries for Nginx haskell module+description:                Build custom libraries for+        <http://github.com/lyokha/nginx-haskell-module Nginx haskell module>.+homepage:                   http://github.com/lyokha/nginx-haskell-module+license:                    BSD3+license-file:               LICENSE+extra-source-files:         Changelog.md+author:                     Alexey Radkov <alexey.radkov@gmail.com>+maintainer:                 Alexey Radkov <alexey.radkov@gmail.com>+stability:                  experimental+copyright:                  2021 Alexey Radkov+category:                   Network+build-type:                 Simple+cabal-version:              1.20++library+  default-language:         Haskell2010+  build-depends:            base >= 4.8 && < 5+                          , Cabal+                          , filepath++  exposed-modules:          NgxExport.Distribution++  ghc-options:             -Wall+