packages feed

ngx-export-distribution 0.1.1.0 → 0.2.0.0

raw patch · 3 files changed

+110/−46 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ NgxExport.Distribution: buildSharedLib :: Verbosity -> PackageDescription -> LocalBuildInfo -> BuildFlags -> IO FilePath
+ NgxExport.Distribution: ngxExportHooks :: Verbosity -> UserHooks
+ NgxExport.Distribution: patchAndCollectDependentLibs :: Verbosity -> FilePath -> PackageDescription -> LocalBuildInfo -> IO ()

Files

Changelog.md view
@@ -1,3 +1,8 @@+### 0.2.0.0++- More robust processing of build and configuration flags.+- Export several internal functions from the module.+ ### 0.1.1.0  - Support only Cabal versions >= 3.0.0.0.
NgxExport/Distribution.hs view
@@ -20,7 +20,10 @@ module NgxExport.Distribution (     -- * Usage and examples     -- $usage-                               defaultMain+                               buildSharedLib+                              ,patchAndCollectDependentLibs+                              ,ngxExportHooks+                              ,defaultMain                               ) where  import Distribution.Simple hiding (defaultMain)@@ -70,13 +73,16 @@ -- name:                       ngx-distribution-test -- version:                    0.1.0.0 -- build-type:                 __/Custom/__--- cabal-version:              1.20+-- cabal-version:              1.24 --+-- __/custom-setup/__+--   setup-depends:            base >= 4.8 && < 5+--                           , __/ngx-export-distribution/__+-- -- library --   default-language:         Haskell2010 --   build-depends:            base >= 4.8 && < 5 --                           , ngx-export---                           , ngx-export-distribution --                           , bytestring --                           , aeson --@@ -138,11 +144,11 @@ -- 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.+-- - Utility /hslibdeps/ collects only libraries prefixed with /libHS/,+-- - command /cabal v1-clean/ only deletes directory /dist/, it does not delete+--   build artifacts in the current working directory,+-- - behavior of Cabal commands other than /configure/, /build/ and /clean/ is+--   not well defined.  data LibNameNotSpecified = LibNameNotSpecified @@ -157,66 +163,119 @@ patchelf :: Program patchelf = simpleProgram "patchelf" -buildAndHslibdeps :: Verbosity -> PackageDescription -> LocalBuildInfo ->-    BuildFlags -> IO ()-buildAndHslibdeps verbosity desc lbi flags = do+-- | Builds a shared library.+--+-- Runs /ghc/ compiler with the following arguments.+--+-- - /-dynamic/, /-shared/, /-fPIC/,+-- - all arguments listed in /ghc-options/ in the Cabal file,+-- - all arguments passed in option /--ghc-options/ from command-line.+--+-- Requires that the arguments contain /-o path/ for the path to the shared+-- library to build.+--+-- Returns the path to the built shared library.+buildSharedLib :: Verbosity                         -- ^ Verbosity level+               -> PackageDescription                -- ^ Package description+               -> LocalBuildInfo                    -- ^ Local build info+               -> BuildFlags                        -- ^ Build flags+               -> IO FilePath+buildSharedLib verbosity desc lbi flags = do     let configGhcOptions =-            map (("ghc", ) . pure) . concatMap snd-            . filter (\(c, o) -> c == GHC && not (null o)) $-                perCompilerFlavorToList $+            maybe [] (map ("ghc", )) $+                lookup GHC $ perCompilerFlavorToList $                     options $ libBuildInfo $ fromJust $ library desc         lib = fst $-            foldl (\a@(r, ready) (prog, v) ->-                if prog /= "ghc" || null v || isJust r+            foldl (\a@(r, _) (prog, v) ->+                if prog /= "ghc" || 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)+                    else foldl (\a'@(r', ready) v' ->+                                    if isJust r'+                                        then a'+                                        else if v' == "-o"+                                                 then (Nothing, True)+                                                 else if ready+                                                          then (Just v', False)+                                                          else (Nothing, False)+                               ) a v                   ) (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)+                      buildProgramArgs flags +++                          map (second pure) configGhcOptions+    when (isNothing lib) $ throwIO LibNameNotSpecified+    ghcP <- fst <$> requireProgram verbosity ghcProgram (withPrograms lbi)+    let ghcR = programInvocation ghcP $ ["-dynamic", "-shared", "-fPIC"] +++            map snd configGhcOptions+    runProgramInvocation verbosity ghcR+    return $ fromJust lib++-- | Patches the shared library and collects dependent Haskell libraries.+--+-- Performs the following steps.+--+-- - Adds the value of /prefix/ to the list of /rpath/ in the shared library,+-- - collects all dependent Haskell libraries in a directory whose name forms+--   as /arch-os-compiler/,+-- - archives the shared library and the directory with the collected dependent+--   libraries in a /tar.gz/ file.+--+-- The initial 2 steps are performed by utility+-- <https://github.com/lyokha/nginx-haskell-module/blob/master/utils/hslibdeps hslibdeps>.+-- It collects all libraries with prefix /libHS/ from the list returned by+-- command /ldd/ applied to the shared library.+patchAndCollectDependentLibs :: Verbosity           -- ^ Verbosity level+                             -> FilePath            -- ^ Path to the library+                             -> PackageDescription  -- ^ Package description+                             -> LocalBuildInfo      -- ^ Local build info+                             -> IO ()+patchAndCollectDependentLibs verbosity lib desc lbi = do+    let dir = prettyShow (hostPlatform lbi) +++            '-' : prettyShow (compilerId $ compiler lbi)         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+    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]+        tar = addExtension (takeBaseName lib ++ '-' : prettyShow ver) "tar.gz"+        tarR = programInvocation tarP ["czf", tar, lib, dir]     runProgramInvocation verbosity tarR -ngxExportHooks :: UserHooks-ngxExportHooks =+-- | Build hooks.+--+-- Based on 'simpleUserHooks'. Overrides+--+-- - 'confHook' by configuring programs /hslibdeps/ and /patchelf/ and then+--   running the original /confHook/ from /simpleUserHooks/,+-- - 'buildHook' by running in sequence 'buildSharedLib' and+--   'patchAndCollectDependentLibs'.+--+-- Other hooks from /simpleUserHooks/ get derived as is. Running them is+-- neither tested nor recommended.+ngxExportHooks :: Verbosity                         -- ^ Verbosity level+               -> UserHooks+ngxExportHooks verbosity =     let hooks = simpleUserHooks     in hooks { hookedPrograms = [hslibdeps]              , confHook = \desc flags -> do                  let pdb = configPrograms flags-                 _ <- requireProgram normal hslibdeps pdb >>=-                          requireProgram normal patchelf . snd+                 _ <- requireProgram verbosity hslibdeps pdb >>=+                          requireProgram verbosity patchelf . snd                  confHook simpleUserHooks desc flags              , buildHook =  \desc lbi _ flags ->-                 buildAndHslibdeps normal desc lbi flags+                 buildSharedLib verbosity desc lbi flags >>= \lib ->+                     patchAndCollectDependentLibs verbosity lib desc lbi              }  -- | A simple implementation of /main/ for a Cabal setup script.+--+-- Implemented as+--+-- @+-- defaultMain = 'defaultMainWithHooks' $ 'ngxExportHooks' 'normal'+-- @ defaultMain :: IO ()-defaultMain = defaultMainWithHooks ngxExportHooks+defaultMain = defaultMainWithHooks $ ngxExportHooks normal 
ngx-export-distribution.cabal view
@@ -1,5 +1,5 @@ name:                       ngx-export-distribution-version:                    0.1.1.0+version:                    0.2.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>.