I've been doing some more work with atspkg
and polyglot builds. It is now in
slightly better shape, and it gives us the ability to call ATS code in Haskell
almost painlessly.
Cabal Builds
Cabal is the common architectures for building and install Haskell libraries. It is sophisticated, accompanying a massive Cabal library. Since it's written in Haskell, it's relatively easy to just plug everything in.
We'll be using atspkg for our build, as usual. This will handle package management and dependency resolution for the ATS side of things. The main disadvantage is that your package's builds will be noticeably longer.
Our first step will be to prepare a polyglot project using pi:
pi git vmchale/haskell-ats ats-library
cd ats-library/
Take it for a test drive with
cabal new-test
cabal new-bench
You should see something exciting: the Haskell package builds with ATS
dependencies! The Setup.hs
file runs a build process defined by
atspkg.dhall
, installing the necessary compiler and any package dependencies.
Opening up atspkg.dhall
, you should see the following:
let prelude = https://raw.githubusercontent.com/vmchale/atspkg/master/ats-pkg/dhall/atspkg-prelude.dhall
in prelude.default //
{ libraries =
[
prelude.lib //
{ name = "ats-library"
, src = [ "ats-src/ats-library.dats" ]
, libTarget = "dist-newstyle/lib/libats-library.a"
}
]
}
This works in concert with the following in our .cabal
file:
extra-source-files: ats-src/*.dats
, dist-newstyle/lib/empty
, atspkg.dhall
custom-setup
setup-depends: base
, ats-pkg >= 2.6.1.0
, Cabal
library
hs-source-dirs: src
library
extra-libraries: ats-library
extra-lib-dirs: ./dist-newstyle/lib
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
if flag(development)
ghc-options: -Werror
if impl(ghc >= 8.0)
ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat
ghc-options: -Wall
And that's it! Our ATS source code now builds inside a Haskell package. We can
even modify atspkg.dhall
to add dependencies or multiple source files:
let prelude = https://raw.githubusercontent.com/vmchale/atspkg/master/ats-pkg/dhall/atspkg-prelude.dhall
in prelude.default //
{ libraries =
[
prelude.lib //
{ name = "ats-library"
, src = [ "ats-src/ats-library0.dats", "ats-src/ats-library1.dats" ]
, libTarget = "dist-newstyle/lib/libats-library.a"
}
]
, dependencies = prelude.mapPlainDeps [ "atscntrb-hx-intinf" ]
}
As you can see, this is a powerful tool for cross-language builds. I suspect that Haskell ecosystem will benefit immensely from such fluent, safe access to low-level functionality.