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 +4/−0
- LICENSE +25/−0
- NgxExport/Distribution.hs +222/−0
- Setup.hs +3/−0
- ngx-export-distribution.cabal +27/−0
+ 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+