diff --git a/.github/workflows/bindings_haskell.yml b/.github/workflows/bindings_haskell.yml index 740085ac12d..32d6b13c1d9 100644 --- a/.github/workflows/bindings_haskell.yml +++ b/.github/workflows/bindings_haskell.yml @@ -60,8 +60,7 @@ jobs: - name: Build & Test working-directory: "bindings/haskell" run: | - cargo build - LIBRARY_PATH=../../target/debug LD_LIBRARY_PATH=../../target/debug cabal test + LD_LIBRARY_PATH=../../target/release cabal test - name: Save haskell cache uses: actions/cache/save@v3 with: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3290e34563a..0494ce6af6b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -210,8 +210,7 @@ jobs: - name: Build Docs working-directory: "bindings/haskell" run: | - cargo build - LIBRARY_PATH=../../target/debug cabal haddock --haddock-html --haddock-quickjump --haddock-hyperlink-source + cabal haddock --haddock-html --haddock-quickjump --haddock-hyperlink-source find dist-newstyle -path '**/build/**/doc' -exec cp -r {}/html/opendal-hs/ doc \; - name: Save haskell cache diff --git a/bindings/haskell/Cargo.toml b/bindings/haskell/Cargo.toml index fdea27a403d..be80e2d23ac 100644 --- a/bindings/haskell/Cargo.toml +++ b/bindings/haskell/Cargo.toml @@ -17,6 +17,7 @@ [package] name = "opendal-hs" +publish = false version = "0.1.0" authors.workspace = true diff --git a/bindings/haskell/Setup.hs b/bindings/haskell/Setup.hs new file mode 100644 index 00000000000..5a2c6048e91 --- /dev/null +++ b/bindings/haskell/Setup.hs @@ -0,0 +1,89 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +import Control.Monad +import Data.Maybe +import qualified Distribution.PackageDescription as PD +import Distribution.Simple +import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Setup +import Distribution.Simple.Utils +import Distribution.System +import System.Directory +import System.Environment +import System.Process + +main :: IO () +main = + defaultMainWithHooks + simpleUserHooks + { confHook = rustConfHook, + buildHook = rustBuildHook + } + +rustConfHook :: (PD.GenericPackageDescription, PD.HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo +rustConfHook (description, buildInfo) flags = do + localBuildInfo <- confHook simpleUserHooks (description, buildInfo) flags + let packageDescription = localPkgDescr localBuildInfo + library = fromJust $ PD.library packageDescription + libraryBuildInfo = PD.libBuildInfo library + dir <- getLibDir + return + localBuildInfo + { localPkgDescr = + packageDescription + { PD.library = + Just $ + library + { PD.libBuildInfo = + libraryBuildInfo + { PD.extraLibDirs = dir : PD.extraLibDirs libraryBuildInfo + } + } + } + } + +rustBuildHook :: PD.PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO () +rustBuildHook pkg_descr lbi hooks flags = do + putStrLn "Building Rust code..." + rawSystemExit (fromFlag $ buildVerbosity flags) "cargo" ["build", "--release"] + createHSLink + putStrLn "Build Rust code success!" + buildHook simpleUserHooks pkg_descr lbi hooks flags + where + createHSLink = do + dir <- getLibDir + ghcVersion <- init <$> readProcess "ghc" ["--numeric-version"] "" + let srcPath = dir ++ "/libopendal_hs." ++ getDynamicLibExtension lbi + let destPath = dir ++ "/libopendal_hs-ghc" ++ ghcVersion ++ "." ++ getDynamicLibExtension lbi + exist <- doesFileExist destPath + when (not exist) $ createFileLink srcPath destPath + +getLibDir :: IO String +getLibDir = do + cargoPath <- readProcess "cargo" ["locate-project", "--workspace", "--message-format=plain"] "" + let dir = take (length cargoPath - 11) cargoPath -- /Cargo.toml -> + return $ dir ++ "/target/release" + +getDynamicLibExtension :: LocalBuildInfo -> String +getDynamicLibExtension lbi = + let Platform _ os = hostPlatform lbi + in case os of + OSX -> "dylib" + Linux -> "so" + Windows -> "dll" + _ -> error "Unsupported OS" \ No newline at end of file diff --git a/bindings/haskell/opendal-hs.cabal b/bindings/haskell/opendal-hs.cabal index 5fae8c057e1..e611ad287ac 100644 --- a/bindings/haskell/opendal-hs.cabal +++ b/bindings/haskell/opendal-hs.cabal @@ -23,7 +23,12 @@ synopsis: OpenDAL Haskell Binding description: OpenDAL Haskell Binding. Open Data Access Layer: Access data freely, painlessly, and efficiently category: Storage, Binding -build-type: Simple +tested-with: GHC ==9.2.7 +build-type: Custom +custom-setup + setup-depends: Cabal, base, directory, process + +extra-source-files: src/*.rs, Cargo.toml, build.rs source-repository head type: git @@ -49,12 +54,12 @@ common base library import: base - extra-libraries: opendal_hs exposed-modules: OpenDAL other-modules: OpenDAL.FFI hs-source-dirs: haskell-src + extra-bundled-libraries: opendal_hs test-suite opendal-hs-test import: base