|
| 1 | +# Cabal Support for Bytecode Objects and Bytecode Libraries |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +Extend Cabal to support building, installing, and managing persistent bytecode |
| 6 | +artifacts (`.gbc` files) and bytecode libraries alongside native code, enabling |
| 7 | +faster build times and better tooling integration for development and REPL use |
| 8 | +cases. |
| 9 | + |
| 10 | +## Motivation |
| 11 | + |
| 12 | +Currently, GHC's bytecode interpreter only generates transient, in-memory |
| 13 | +bytecode that must be regenerated every time a module is loaded in GHCi or for |
| 14 | +Template Haskell evaluation. This proposal extends Cabal and `cabal-install` to support persistent |
| 15 | +bytecode artifacts, which will: |
| 16 | + |
| 17 | +- Enable caching of bytecode for faster (`cabal repl`) startup and tooling |
| 18 | +- Reduce compilation time for development workflows |
| 19 | +- Provide better integration between Cabal and GHC's bytecode capabilities |
| 20 | +- Support the new `-fwrite-bytecode` flag in GHC for persistent bytecode generation |
| 21 | + |
| 22 | +This is not intended to replace native code for production executables, but |
| 23 | +rather to extend Cabal's capabilities where fast build times, portability, and |
| 24 | +tooling integration are more important than peak execution speed. |
| 25 | + |
| 26 | +## Proposed Change |
| 27 | + |
| 28 | +### Changes to `ghc-pkg` |
| 29 | + |
| 30 | +- Add a new field `bytecode-library-dirs` to the package database to store the locations of bytecode libraries. |
| 31 | + |
| 32 | +### Changes to Cabal Library (Setup Interface) |
| 33 | + |
| 34 | +The main changes are to add a new bytecode "library way" to Cabal. |
| 35 | + |
| 36 | +- Add `--enable-library-bytecode` build option to the Cabal library interface which when enabled will pass `-fwrite-bytecode` to GHC |
| 37 | +- If requesting an object way and the bytecode way, then `-fbyte-code-and-object-code` will be passed to GHC to enable compilation of all artifacts in a single pass. |
| 38 | +- Once a library is finished being compiled, cabal will create a bytecode library archive containing all the `.gbc` files for the library. |
| 39 | +- The bytecode library will be installed into the package database alongside the native library. |
| 40 | +- Add a new option to enable the `repl` command to write bytecode files. This will be enabled by default. |
| 41 | + |
| 42 | +### Changes to cabal-install (User Interface) |
| 43 | + |
| 44 | +- `--enable-library-bytecode` flag: When specified, enables bytecode generation for the build |
| 45 | +- This flag exposes the underlying `--enable-library-bytecode` build option from the Cabal library |
| 46 | +- This flag is like `--enable-shared` or `--enable-library-profiling`, it is a way specifier. |
| 47 | + |
| 48 | +## Alternatives Considered |
| 49 | + |
| 50 | +- The other option is to not add support to Cabal for bytecode libraries, and |
| 51 | +instead have the user manually create a bytecode library archive and install it |
| 52 | +into the package database. This approach would lead to a difficult adoption of |
| 53 | +the feature. |
| 54 | + |
| 55 | +## Backwards Compatibility / Migration |
| 56 | + |
| 57 | +This change maintains full backwards compatibility: |
| 58 | + |
| 59 | +- Default Behavior: Bytecode generation is disabled by default, so existing builds are unaffected |
| 60 | +- Optional Feature: The `--enable-library-bytecode` flag is opt-in, requiring explicit user action |
| 61 | + |
| 62 | +## Interested parties |
| 63 | + |
| 64 | +- Haskell Tooling Developers: Those building IDEs, language servers, and development tools that would benefit from faster bytecode loading |
| 65 | +- GHC Developers: The GHC team implementing the `-fwrite-bytecode` functionality |
| 66 | +- Cabal Maintainers: The Cabal team who will review and integrate these changes |
| 67 | +- Package Authors: Developers who want faster development cycles and better tooling integration |
| 68 | +- Haskell Community: Users who would benefit from improved development experience |
| 69 | + |
| 70 | +### Contact Status |
| 71 | + |
| 72 | +- GHC Team: I am collaborating with Cheng Shao, and Rodrigo Mesquita on the bytecode implementation |
| 73 | +- Cabal Team: Will engage with Cabal maintainers for review and integration |
| 74 | +- Tooling Community: I made a [post on discourse](https://discourse.haskell.org/t/rfc-introduce-a-serialisable-bytecode-format-and-corresponding-bytecode-way/12678) asking for feedback on the proposal. |
| 75 | + |
| 76 | +## Implementation Notes |
| 77 | + |
| 78 | +### Implementation Plan |
| 79 | + |
| 80 | +1. Phase 1: Extend Cabal library to support bytecode configuration and artifact generation |
| 81 | + - Add `--enable-library-bytecode` build option to the Cabal library |
| 82 | + - Implement bytecode generation in the build system |
| 83 | + - Extend package registration for bytecode artifacts |
| 84 | + |
| 85 | +2. Phase 2: Implement cabal-install user interface changes |
| 86 | + - Add `--enable-library-bytecode` command-line flag |
| 87 | + |
| 88 | +3. Phase 3: Integration testing and documentation |
| 89 | + - Test across different platforms and configurations |
| 90 | + - Document new features and usage patterns |
| 91 | + |
| 92 | +Either myself or a colleague can implement these changes. |
| 93 | + |
| 94 | +## Open Questions |
| 95 | + |
| 96 | +- `cabal-install` could also support the option to use `-fprefer-bytecode`, which would imply generating bytecode for dependencies rather than object code |
| 97 | + in the same build way as the compiler. |
| 98 | +- There currently isn't support for building "bytecode executables", and hence no `--enable-executable-bytecode` flag. |
| 99 | + |
| 100 | +## References |
| 101 | + |
| 102 | +* [GHC Issue 26298](https://gitlab.haskell.org/ghc/ghc/-/issues/26298) |
| 103 | +* [Cabal Issue 11188](https://github.com/haskell/cabal/issues/11188) |
| 104 | +* Discourse post: [RFC: Introduce a serialisable bytecode format and corresponding bytecode way](https://discourse.haskell.org/t/rfc-introduce-a-serialisable-bytecode-format-and-corresponding-bytecode-way/12678) |
0 commit comments