packages feed

cabal-bundle-clib (empty) → 0.1.0

raw patch · 7 files changed

+215/−0 lines, 7 filesdep +Cabaldep +basedep +bytestringsetup-changed

Dependencies added: Cabal, base, bytestring, directory, filepath, process, temporary, text, time

Files

+ CHANGELOG.md view
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright 2018-2019 Isumi Feng++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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cabal-bundle-clib.cabal view
@@ -0,0 +1,38 @@+cabal-version:       2.4+-- Initial package description 'cabal-bundle-clib.cabal' generated by+-- 'cabal init'.  For further documentation, see+-- http://haskell.org/cabal/users-guide/++name:                cabal-bundle-clib+version:             0.1.0+synopsis:            Bundling C/C++ projects in Cabal package made easy+license:             BSD-3-Clause+license-file:        LICENSE+author:              Isumi Feng+maintainer:          contact@zelinf.net+copyright:           2019, Isumi Feng+category:            Development+stability:           alpha+homepage:            https://github.com/isumif/cabal-bundle-clib+bug-reports:         https://github.com/isumif/cabal-bundle-clib/issues+description:         Please see the [README](https://github.com/isumif/cabal-bundle-clib)+extra-source-files:       CHANGELOG.md++library+  hs-source-dirs: src+  default-language: Haskell2010+  ghc-options: -Wall+  exposed-modules:+      Development.CabalBundleCLib+    , Development.CabalBundleCLib.Types+    , Development.CabalBundleCLib.CMake+  build-depends:+      base ^>=4.12.0.0+    , Cabal ^>=2.4.1.0+    , text+    , time+    , temporary+    , directory+    , process+    , filepath+    , bytestring
+ src/Development/CabalBundleCLib.hs view
@@ -0,0 +1,94 @@+module Development.CabalBundleCLib+  ( mainWithCLib+  , module Development.CabalBundleCLib.Types+  ) where++import           Data.Time.Clock                            (getCurrentTime)+import           Development.CabalBundleCLib.Types+import qualified Distribution.Compat.Lens                   as Lens+import qualified Distribution.PackageDescription            as Cabal hiding+                                                                      (Flag)+import qualified Distribution.Simple                        as Cabal+import qualified Distribution.Simple.Setup                  as Cabal+import qualified Distribution.Types.BuildInfo.Lens          as CabalLens+import qualified Distribution.Types.Library.Lens            as CabalLens+import qualified Distribution.Types.LocalBuildInfo          as Cabal+import qualified Distribution.Types.PackageDescription.Lens as CabalLens+import           System.Directory                           (removeFile)+import           System.FilePath                            ((</>))+import           System.IO.Temp                             (writeTempFile)++mainWithCLib :: FilePath -- ^c project root+             -> [String] -- ^bundled libraries+             -> [FilePath] -- ^parent dirs of libraries (relative to build root)+             -> (BuildAction -> BuildDirs -> IO ()) -- ^builder+             -- The three 'FilePath's are source dir, build dir and installation+             -- dir, respectively+             -> IO ()+mainWithCLib cProjRoot bundledLibs bundledLibDirs builder =+  Cabal.defaultMainWithHooks Cabal.simpleUserHooks+    { Cabal.confHook = customConfigure bundledLibs+    , Cabal.postConf = \_ _ _ _ -> pure () -- remove the check for foreign libs+    , Cabal.buildHook = customBuild cProjRoot bundledLibs bundledLibDirs builder+    }++customConfigure :: [String]+                -> (Cabal.GenericPackageDescription, Cabal.HookedBuildInfo)+                -> Cabal.ConfigFlags+                -> IO Cabal.LocalBuildInfo+customConfigure bundledLibs gpkgDesc configFlags = do+  lbi <- Cabal.confHook Cabal.simpleUserHooks gpkgDesc configFlags+  let localPkgDescr = Cabal.localPkgDescr lbi+      localPkgDescr' = Lens.over CabalLens.library updateLibrary localPkgDescr+  pure $ lbi { Cabal.localPkgDescr = localPkgDescr' }+  where+    updateLibrary :: Maybe Cabal.Library -> Maybe Cabal.Library+    updateLibrary = fmap $ Lens.over CabalLens.libBuildInfo updateBuildInfo+    updateBuildInfo :: Cabal.BuildInfo -> Cabal.BuildInfo+    updateBuildInfo bi = bi+      { Cabal.extraLibs = bundledLibs ++ Cabal.extraLibs bi+      , Cabal.extraBundledLibs = bundledLibs ++ Cabal.extraBundledLibs bi+      }++customBuild :: FilePath -- ^c project root+            -> [String] -- ^bundled libs+            -> [FilePath] -- bundled lib dirs+            -> (BuildAction -> BuildDirs -> IO ())+            -> Cabal.PackageDescription+            -> Cabal.LocalBuildInfo+            -> Cabal.UserHooks+            -> Cabal.BuildFlags+            -> IO ()+customBuild cProjRoot bundledLibs bundledLibDirs builder packageDesc localBuildInfo userHooks buildFlags = do+  currentTime <- getCurrentTime+  let versionInfo = "const char *clibver = \"" ++ show currentTime ++ "\";\n"+  let buildDir = Cabal.buildDir localBuildInfo+  clibVersionFile <- writeTempFile buildDir "clibver.c" versionInfo+  let updateLibrary :: Cabal.Library -> Cabal.Library+      updateLibrary lib =+        let lib' = Lens.over (CabalLens.libBuildInfo . CabalLens.cSources) (clibVersionFile :) lib+            lib'' = Lens.over (CabalLens.libBuildInfo . CabalLens.extraLibDirs)+              ((fmap (\dir -> buildDir </> dir) bundledLibDirs) ++) lib'+         in Lens.over (CabalLens.libBuildInfo . CabalLens.extraLibs) (bundledLibs ++) lib''+  let packageDesc' = Lens.over CabalLens.library (fmap updateLibrary) packageDesc+  builder+    (BuildActionBuild (getBuildMode localBuildInfo))+    (BuildDirs cProjRoot (buildDir </> "clibbuild") buildDir) -- TODO use some unique build dir name+  simpleBuildHook packageDesc' localBuildInfo userHooks buildFlags+  removeFile clibVersionFile++getBuildMode :: Cabal.LocalBuildInfo -> BuildMode+getBuildMode localBuildInfo =+  case Cabal.configOptimization . Cabal.configFlags $ localBuildInfo of+    Cabal.Flag level ->+      case level of+        Cabal.MaximumOptimisation -> BuildModeRelease+        _                         -> BuildModeDebug+    _ -> BuildModeDebug++simpleBuildHook :: Cabal.PackageDescription+                -> Cabal.LocalBuildInfo+                -> Cabal.UserHooks+                -> Cabal.BuildFlags+                -> IO ()+simpleBuildHook = Cabal.buildHook Cabal.simpleUserHooks
+ src/Development/CabalBundleCLib/CMake.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE RecordWildCards #-}++module Development.CabalBundleCLib.CMake+  ( simpleCMakeBuilder+  ) where++import           Development.CabalBundleCLib.Types+import           System.Directory                  (withCurrentDirectory)+import           System.FilePath                   ((</>))+import           System.Process                    (callCommand, callProcess)++simpleCMakeBuilder :: BuildAction -> BuildDirs -> IO ()+simpleCMakeBuilder BuildActionClean BuildDirs{..} =+  withCurrentDirectory buildDirsBuild $+    callProcess "make" ["clean"]+simpleCMakeBuilder (BuildActionBuild mode) BuildDirs{..} = do+  callProcess "cmake" ["-S", buildDirsSource, "-B", buildDirsBuild, (buildModeToFlag mode)]+  callProcess "cmake" ["--build", buildDirsBuild]+  callCommand $ "cp " ++ buildDirsBuild </> "*.a" ++ " " ++ buildDirsInstall++buildModeToFlag :: BuildMode -> String+buildModeToFlag buildMode = "-DCMAKE_BUILD_TYPE=" ++ mode+  where+    mode = case buildMode of+             BuildModeDebug   -> "Debug"+             BuildModeRelease -> "Release"++{-+cmake -S $SOURCE_DIR -B $BUILD_DIR+cmake --build $BUILD_DIR+cp $BUILD_DIR/*.a $BUILD_DIR/*.so.* $INSTALL_DIR+-}
+ src/Development/CabalBundleCLib/Types.hs view
@@ -0,0 +1,23 @@+module Development.CabalBundleCLib.Types+  ( BuildAction(..)+  , BuildMode(..)+  , BuildDirs(..)+  , Builder+  ) where++-- |Type for build actions.+data BuildAction =+    BuildActionBuild BuildMode+  | BuildActionClean+  deriving (Show, Eq)++data BuildMode = BuildModeDebug | BuildModeRelease+  deriving (Show, Eq)++data BuildDirs = BuildDirs+  { buildDirsSource  :: FilePath+  , buildDirsBuild   :: FilePath+  , buildDirsInstall :: FilePath+  } deriving (Show, Eq)++type Builder = BuildAction -> BuildDirs -> IO ()