-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
how-to cabal #450
Comments
See also #7 and the various issues and PRs linked from it. |
Thanks @ScottFreeCode, for this excellent gist! It got me started on custom setups for invoking BNFC before building. I think it fits the cabal philosophy of preprocessors better if BNFC generates the files in the So, this is what I ended up with:
import Distribution.Simple (defaultMainWithHooks, simpleUserHooks, buildHook)
import Distribution.Simple.BuildPaths (autogenPackageModulesDir)
import System.Process (callProcess)
main :: IO ()
main = defaultMainWithHooks simpleUserHooks
{ buildHook = \ packageDescription localBuildInfo userHooks buildFlags -> do
-- For simplicity, generate files in build/global-autogen;
-- there they are available to all components of the package.
callProcess "bnfc"
[ "-o", autogenPackageModulesDir localBuildInfo
, "-d"
, "Example.cf"
]
-- Run the build process.
buildHook simpleUserHooks packageDescription localBuildInfo userHooks buildFlags
}
cabal-version: 2.0
...
build-type: Custom
custom-setup
setup-depends:
Cabal >= 2.0 && < 4
-- Distribution.Simple.BuildPaths.autogenPackageModulesDir is new in Cabal-2.0
, base >= 4.10 && < 5
-- Restrict to GHC >= 8.2 which ships Cabal-2.0 (otherwise Cabal has to be reinstalled)
, process
, BNFC >= 2.8.4 && < 2.10
executable ...
...
other-modules:
...
Example.Abs
Example.Lex
Example.Par
Example.Print
autogen-modules:
Example.Abs
Example.Lex
Example.Par
Example.Print
...
build-tool-depends:
-- The 'bnfc' executable is called from 'Setup.hs' only,
-- but 'build-tool-depends' is not supported in the 'custom-setup' stanza.
-- BNFC 2.8.4 dropped the 'Err' custom type in favour of the standard 'Either'.
BNFC:bnfc >= 2.8.4 && < 2.10
-- Not sure about the lower bounds, so we pick alex and happy versions
-- that work at least with GHC 8.0.
, alex:alex >= 3.1.4 && < 3.5
, happy:happy >= 1.19.5 && < 1.21
|
Nice! I'll have to look at that more closely when I'm feeling up to it. Nix made it easy to be lazy (not in the Haskell sense of the term): it automatically generates the build in a sandbox so my source folder isn't cluttered. Well, unless I nix-shell and then call Cabal myself; even then, I opted to gitignore the generated files, though it slips my mind at the moment exactly how I implemented it (by a source subfolder vs by file type and/or name; I can imagine doing either one). Putting them all in some build folder is definitely cleaner (and easier to gitignore), and doesn't depend on being wrapped in a Nix sandbox. |
Maybe this belongs on the website repo, but, would it be helpful to have a couple examples somewhere of how to automate generating code with BNFC as part of the build process?
I recall (would take more time to track down) that there are issues around "can Cabal be taught to use BNFC like it uses Happy and Alex?" To which the answer is "Well, not like it uses Happy and Alex, no, since with BNFC there isn't a one-to-one correspondence between input files and generated files."
I figured out how to do it using Setup.hs instead.
I have a couple gists here you could base examples off of: https://gist.github.com/ScottFreeCode/9b0ea3e52fa56c93ea8ca14791e55bb4
One is a simple single package. Another is my attempt at splitting it up into two packages (say, if you want a library implementing a language but then separately want an executable interpreter). Both also demonstrate wrapping in Nix (which can be safely ignored as it doesn't affect the Haskell / Cabal code! Well, if you do use Nix, you have to either
nix-build
or use Cabal's v1 commands if you're working insidenix-shell
, but I am talking with other developers in other issues about that problem.) Alongside them are a couple equivalent examples without BNFC, which you can use for comparison to see what is BNFC-specific / added in the BFNC ones.Anyhow, I hope that is helpful someway or another.
The text was updated successfully, but these errors were encountered: