• Stars
    star
    161
  • Rank 233,470 (Top 5 %)
  • Language
    Haskell
  • License
    Other
  • Created almost 6 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The GHC API, decoupled from GHC versions

ghc-lib Hackage version Stackage version Build Status

Copyright Β© 2019-2023, Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. SPDX-License-Identifier: (Apache-2.0 OR BSD-3-Clause)

The GHC API allows you to use the GHC compiler as a library, so you can parse, analyze and compile Haskell code. The GHC API comes preinstalled with GHC, and is tied to that GHC version - if you are using GHC 8.6.3, you get version 8.6.3 of the API, and can't change it. The ghc-lib project solves that problem, letting you mix and match versions of the GHC compiler and GHC API. Why might you want that?

  • Imagine you are writing a tool to work with several versions of the GHC compiler. The GHC API changes significantly between each version, so doing this would require writing a lot of C preprocessor code to support it. An alternative is to use one version of ghc-lib which works across multiple versions of GHC.

More precisely, building ghc-lib is the same as bootstrapping GHC. For a given ghc-lib 'flavor' (like --ghc-flavor=ghc-9.6.1), a build GHC can be at most "two versions behind & not newer" (e.g. --ghc-flavor=ghc-9.6.1 β‡’ [ghc-9.2.1, ghc-9.6.2)1. ghc-lib cabal files will not produce build plans for configurations outside of these bounds. Clients assume the same build constraints through transitivity e.g. HLint.

  • Imagine you are modifying the GHC API or want features from GHC HEAD. With ghc-lib you can depend on the revised GHC API, without upgrading the compiler used to build everything, speeding up iteration.

The ghc-lib project provides two packages : ghc-lib-parser and ghc-lib. The ghc-lib-parser package is that subset of the GHC API that is just enough to parse Haskell code. The ghc-lib package extends (and re-exports) ghc-lib-parser with the rest. While ghc-lib provides the full GHC API, it doesn't contain a runtime system, nor does it create a package database. That means you can't run code produced by ghc-lib (no runtime), and compiling off-the-shelf code is very hard (no package database containing the base library). What you can do:

There are some downsides to ghc-lib:

  • The lack of runtime means you can't run code, which includes running code at compile time, e.g. TemplateHaskell.
  • While ghc-lib isn't tied to any specific GHC versions, it can only read package databases and .hi files for one particular version of GHC. That means your existing package database probably can't be consumed by ghc-lib (unless you happen to perfectly match the GHC version, in which case you could just have used the GHC API), and it doesn't ship with a package database so you'd have to painfully build your own.
  • Compilation times for the ghc-lib packages are not small, taking approximately 5 minutes for each on our CI machines.

Using ghc-lib

The packages ghc-lib-parser and ghc-lib are available on Hackage, and can be used like any normal packages, e.g. cabal install ghc-lib. Since ghc-lib-parser and ghc-lib conflict perfectly with the GHC API and template-haskell, the packages are not exposed by default so if you use GHC directly, you need to pass -package ghc-lib, the GHC user guide has more information : use the language extension PackageImports to do import "ghc-lib" ... or import "ghc-lib-parser" ... as approriate. There are two release streams within the ghc-lib name:

  • Version 8.8.1 will be the version of ghc-lib produced against the released GHC 8.8.1, once it comes out;
  • Version 0.20190204 is the version of ghc-lib using GHC HEAD on the date 2019-02-04.

The Hackage packages are licensed under the BSD-3-Clause license, just like GHC itself. This repo, including the examples and the script that generates ghc-lib, are licensed under the BSD-3-Clause OR Apache-2.0 license.

Creating ghc-lib

We create the packages by taking a checkout of GHC, and combining the ghc package with the various dependencies it is tightly tied to (e.g. template-haskell) in two new cabal files ghc-lib-parser.cabal and ghc-lib.cabal. These new packages depend on a few generated outputs (which we build using the GHC build system) and some Cmm files. The ghc-lib-gen directory contains a script that puts all the pieces together. Because GHC itself is capable of being bootstrapped with older GHC versions (> 8.4.4) (its Stage0 build), the generated ghc-lib also compiles with multiple GHC versions.

To build ghc-lib-parser and ghc-lib you need clones of this repository and the GHC repository.

Warning : ghc-lib-parser and ghc-lib are known to work on all of MacOS, Linux and Windows. Distributions produced with cabal sdist on Linux/MacOS build on Windows, but a cabal sdist produced on Windows does not build on MacOS/Linux.

Building ghc-lib

By far the easist way to produce ghc-lib-parser and ghc-lib packages is to execute the CI script which incidentally builds and executes the examples (this procedure makes versioned packages based on the current date and expresses the version constraint between ghc-lib and ghc-lib-parser accordingly).

# Setup
git clone [email protected]:digital-asset/ghc-lib.git
cd ghc-lib
stack runhaskell --package extra --package optparse-applicative CI.hs -- --ghc-flavor=ghc-8.8.1

Releasing ghc-lib (notes for maintainers)

Build ghc-lib using the above instructions and upload the resulting .tar.gz files to Hackage.

FAQ

How do I use the ghc-lib/ghc-lib-parser version macros?

Read the Standard CPP macros section of the GHC users guide for the semantics of the MIN_VERSION_pkgname(x, y, z) macros and keep in mind that builds of ghc-lib-parser/ghc-lib from GHC head are ascribed version numbers of the form 0.Ξ±.

Building ghc-lib for DAML

The CI.hs script has special support for building custom versions of ghc-lib specifically tailored to the DAML compiler, which requires a handful of patches to be applied on top of GHC. The syntax is slightly different from the general case: the --ghc-flavor flag is replaced with an "enabling" flag --da and three more specific flags. A full call example would be:

stack runhaskell --package extra \
                 --package optparse-applicative \
                 CI.hs -- --da \
                          --merge-base-sha=ghc-8.8.1-release \
                          --patch=upstream/da-master-8.8.1 \
                          --patch=upstream/da-unit-ids-8.8.1 \
                          --gen-flavor=da-ghc-8.8.1 \
                          --upstream=https://github.com/digital-asset/ghc.git

The DAML-specific process only differs from the normal one in that it patches GHC with the given patches. More specifically, it will:

  • Clone GHC. (This is also done by the normal workflow.)
  • Add the DA fork of GHC as a remote named upstream; this can be overridden with the --upstream flag. For example, in local development, --upstream=$PWD/../ghc-fork/. Note that if you want to specify a local path (as in this example), it should be an absolute one, as the command will be run from the folder into which GHC has been cloned.
  • Checkout the commit provided as merge-base-sha.
  • Create a new commit by merging in all of the commits specified through the --patch flags.
  • Proceed as normal for the rest of the workflow.

At some later stage, the workflow calls out to the ghc-lib-gen program, and at that point it needs to pass in a "flavor" argument; it will use the value of the --gen-flavor option for that.

Note that deployment for the DAML version is handled from within the DAML CI.

Footnotes

  1. The set ghc-9.2.1, ghc-9.2.2, ..., ghc-9.4.1, ghc-9.4.2, ..., ghc-9.6.1 ↩

More Repositories

1

daml

The Daml smart contract language
Scala
796
star
2

canton

Global Workflow Composition that is Scalable, Secure, and GDPR-compliant
Scala
74
star
3

ex-models

Haskell
45
star
4

dev-env

Per-project isolated set of dev tools
Shell
40
star
5

ex-healthcare-claims-processing

Reference DAML application demonstrating a healthcare use case.
Haskell
33
star
6

ex-cbdc

TypeScript
23
star
7

daml-on-fabric

Enabling DAML applications to run on Hyperledger Fabric
Java
23
star
8

daml-finance-app

TypeScript
20
star
9

ex-bond-issuance

Reference DAML application demonstrating a bond issuance use case.
Haskell
20
star
10

da-marketplace

TypeScript
17
star
11

daml-finance

Haskell
17
star
12

lib-cdm-event-specification-module

Haskell
17
star
13

ex-bond-trading

A simple bond trading application
Java
15
star
14

ex-tutorial-nodejs

An interactive tutorial to get started with the Node.js bindings for DAML
JavaScript
14
star
15

ex-cdm-swaps

Haskell
12
star
16

ex-supply-chain

Reference DAML application demonstrating a supply chain use case.
TypeScript
12
star
17

lib-finance

Haskell
12
star
18

ex-java-bindings

Three examples demonstrating three different approaches to using the Java ledger API bindings
Java
12
star
19

daml-ui-template

TypeScript
10
star
20

ex-collateral

An example of collateral management in DAML
Haskell
10
star
21

ex-mortgage-repackaging

Reference DAML application demonstrating the use case of repackaging Mortgage Based Securities.
Haskell
10
star
22

dazl-client

dazl Ledger API client
Python
10
star
23

daml-cheat-sheet

A Cheat Sheet for DAML
CSS
9
star
24

wallet-sample-app

TypeScript
8
star
25

ghc

Fork of GHC (https://gitlab.haskell.org/ghc/ghc.git)
Haskell
8
star
26

daml-js

Node.js bindings for DAML
TypeScript
7
star
27

ex-structured-products

Reference DAML application demonstrating the trading of Structured Equity Derivative Products.
Java
7
star
28

ex-secure-daml-infra

Reference example of a secure Ledger deployment using mTLS and JWT tokens
Shell
7
star
29

daml-platform-observability-example

Project showcasing observability features of the Daml Platform.
Shell
7
star
30

ex-repo-market

UNSUPPORTED. An example DAML application showing settlement in the repurchase agreement market through a 3rd party clearing house
Java
7
star
31

ex-know-your-customer

A reference application demonstrating the lifecycle of KYC (Know Your Customer) data subscriptions between data providers, analysts and customers.
Java
7
star
32

lib-daml-jvm-test

A library providing functions for testing DAML applications on JVM.
Java
6
star
33

ex-secure-canton-infra

Reference deployment of a secure Canton infrastructure (PKI, JWT, HA)
Shell
6
star
34

docs.daml.com

Managing the docs.daml.com site
Sass
6
star
35

ex-asset-servicing

TypeScript
6
star
36

ex-inventory-management

Crypto Inventory Management System has been designed to make it easy and safe for crypto funds to manage their crypto assets on public ledgers.
Java
6
star
37

daml-helm-charts

Daml Enterprise deployment with high availability.
Mustache
6
star
38

ex-structured-trade-finance

Reference DAML application demonstrating a structured trade financing use case.
JavaScript
5
star
39

rusty-engine

A prototype of a DAML Engine written in Rust
Rust
5
star
40

daml-on-x-example

DAML-on-X Example Ledger Implementation
Scala
5
star
41

contingent-claims

Haskell
5
star
42

davl

Digital Asset Vacation Ledger
TypeScript
4
star
43

hub-automation-example

An example of a Pythonbot written for Daml Hub
Java
4
star
44

derivhack2019

4
star
45

daml-dit-ddit

Python
3
star
46

ex-market-data-service

Java
3
star
47

rln

Java
3
star
48

create-daml-app

This is an obsolete copy of a template that has now been moved to the DAML SDK repo. Please see https://docs.daml.com/getting-started/index.html for the latest version.
TypeScript
3
star
49

daml-dit-if

Python
2
star
50

custom-views

Scala
2
star
51

ex-custom-views-spring-boot

Java
2
star
52

daml-katacoda

Shell
2
star
53

dabl-react

DABLified react bindings
TypeScript
2
star
54

lib-message-integration

Haskell
2
star
55

tlms-cd-code-demo

Haskell
2
star
56

trigger-failure

Example code for dealing with Daml Trigger failures
Haskell
2
star
57

daml-net

C#
2
star
58

decentralized-canton-sync

Scala
2
star
59

daml-common

Shell
1
star
60

gadi-example

TypeScript
1
star
61

daml-dit-integration-symphony

Daml Hub Integration for creating Symphony Bots
Python
1
star
62

dablchat

DABL Chat. A DAML app that can be deployed to project:DABL
TypeScript
1
star
63

certification-damlfundamentals-capstone

Instructions and guidelines to pass the Daml Fundamentals certification via a capstone project.
Haskell
1
star
64

daml-ctl

Misc control-of-flow structures for daml, mostly adapted from Haskell.
1
star
65

daml-dit-integration-coindesk

Python
1
star
66

ex-authentication-auth0

JavaScript
1
star
67

hlint

Fork of Hlint (https://github.com/ndmitchell/hlint)
Haskell
1
star
68

daml-maven-plugin

A Maven plugin wrapping DAML Assistant.
Java
1
star
69

dablchess

DABL Chess game
TypeScript
1
star
70

ex-upgrade

This is out of date, please refer to recent documentation on https://docs.daml.com instead.
1
star
71

certification-damlfundamentals-ledgerprogramming-lab-solution

1
star
72

boat

1
star
73

ex-java-bindings-with-opentelemetry

An example of writing a client application that uses java codegen and open telemetry
Java
1
star