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 +5/−0
- NgxExport/Distribution.hs +104/−45
- ngx-export-distribution.cabal +1/−1
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>.