Skip to content

Commit 4ee158a

Browse files
committed
Get cardano-api to compile in wasm
1 parent 49bac63 commit 4ee158a

File tree

17 files changed

+829
-21
lines changed

17 files changed

+829
-21
lines changed

.github/bin/check-git-dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ commits () {
2323
done
2424
}
2525

26-
grep '\(^source-repository-package\|^ *location:\|^ *tag:\)' cabal.project | sed 's|^source-repository-package|-|g' | \
26+
cat cabal.project | sed '/-- WASM compilation specific/q' | grep '\(^source-repository-package\|^ *location:\|^ *tag:\)' - | sed 's|^source-repository-package|-|g' | \
2727
yq eval -P -j \
2828
> tmp/repositories.json
2929

.github/workflows/haskell-wasm.yml

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
name: Haskell CI (WASM)
2+
3+
on:
4+
merge_group:
5+
pull_request:
6+
push:
7+
# we need this to populate cache for `master` branch to make it available to the child branches, see
8+
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
9+
branches:
10+
- master
11+
# GH caches are removed when not accessed within 7 days - this schedule runs the job every 6 days making
12+
# sure that we always have some caches on master
13+
# schedule:
14+
# - cron: '0 0 */6 * *'
15+
16+
jobs:
17+
build:
18+
runs-on: ${{ matrix.sys.os }}
19+
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
sys:
24+
- { os: ubuntu-latest, shell: bash }
25+
# - { os: macos-latest, shell: bash }
26+
27+
defaults:
28+
run:
29+
shell: ${{ matrix.sys.shell }}
30+
31+
env:
32+
# Modify this value to "invalidate" the cabal cache.
33+
CABAL_CACHE_VERSION: "2025-05-29"
34+
35+
concurrency:
36+
group: >
37+
wasm
38+
a+${{ github.event_name }}
39+
b+${{ github.workflow_ref }}
40+
c+${{ github.job }}
41+
f+${{ matrix.sys.os }}
42+
g+${{ (startsWith(github.ref, 'refs/heads/gh-readonly-queue/') && github.run_id) || github.event.pull_request.number || github.ref }}
43+
cancel-in-progress: true
44+
45+
steps:
46+
- name: Concurrency group
47+
run: >
48+
echo
49+
wasm
50+
a+${{ github.event_name }}
51+
b+${{ github.workflow_ref }}
52+
c+${{ github.job }}
53+
f+${{ matrix.sys.os }}
54+
g+${{ (startsWith(github.ref, 'refs/heads/gh-readonly-queue/') && github.run_id) || github.event.pull_request.number || github.ref }}
55+
56+
- uses: actions/checkout@v4
57+
58+
- uses: cachix/install-nix-action@v30
59+
with:
60+
nix_path: nixpkgs=channel:nixos-unstable
61+
extra_nix_config: |
62+
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=
63+
substituters = https://cache.iog.io/ https://cache.nixos.org/
64+
65+
- uses: rrbutani/use-nix-shell-action@v1
66+
with:
67+
devShell: .#wasm
68+
69+
- name: Cabal update
70+
run: |
71+
wasm32-wasi-cabal update
72+
73+
# A dry run `build all` operation does *NOT* downlaod anything, it just looks at the package
74+
# indices to generate an install plan.
75+
- name: Build dry run
76+
run: |
77+
wasm32-wasi-cabal build cardano-wasm --dry-run
78+
79+
# From the install plan we generate a dependency list.
80+
- name: Record dependencies
81+
id: record-deps
82+
run: |
83+
cat dist-newstyle/cache/plan.json | jq -r '."install-plan"[] | select(.style != "local") | .id' | sort | uniq > dependencies.txt
84+
85+
- name: Store month number as environment variable used in cache version
86+
run: |
87+
cat <<EOF >> $GITHUB_ENV
88+
MONTHNUM=$(date -u '+%m')
89+
GHC=$(ghc --numeric-version)
90+
STORE=$(wasm32-wasi-cabal path --store | tail -n 1)
91+
EOF
92+
93+
# Cache is disabled because GHA default builders are not able to build all dependencies
94+
# because they lack RAM, so having the cache expire would break the CI check.
95+
# For this reason, we are providing a build of the dependencies instead in
96+
# the "Restore cached deps" step, and we make the check not required.
97+
# When we are able to make this CI check self-sufficient, we should reenable the
98+
# caching and remove the manual restoring of cached deps.
99+
100+
# From the dependency list we restore the cached dependencies.
101+
# We use the hash of `dependencies.txt` as part of the cache key because that will be stable
102+
# until the `index-state` values in the `cabal.project` file changes.
103+
# - name: Restore cached dependencies
104+
# uses: actions/cache/restore@v4
105+
# id: cache
106+
# with:
107+
# path: |
108+
# ${{ env.STORE }}
109+
# dist-newstyle
110+
# key:
111+
# wasm-cache-${{ env.CABAL_CACHE_VERSION }}-${{ runner.os }}-${{ env.GHC }}-${{ hashFiles('cardano-wasm/dependencies.txt') }}
112+
# restore-keys: |
113+
# wasm-cache-${{ env.CABAL_CACHE_VERSION }}-${{ runner.os }}-${{ env.GHC }}-
114+
115+
- name: Restore cached deps
116+
run: |
117+
wget "https://agrius.feralhosting.com/palas/wasm-cache/4c200033737be4736cd2a363d64c49a385937d5ea57d8e52773f65d08bbd1342.tar.bz2"
118+
tar -jxf 4c200033737be4736cd2a363d64c49a385937d5ea57d8e52773f65d08bbd1342.tar.bz2
119+
rm -fr ~/.ghc-wasm/.cabal/store/
120+
mv store ~/.ghc-wasm/.cabal/
121+
122+
# Now we install the dependencies. If the cache was found and restored in the previous step,
123+
# this should be a no-op, but if the cache key was not found we need to build stuff so we can
124+
# cache it for the next step.
125+
- name: Install dependencies
126+
run: |
127+
wasm32-wasi-cabal build cardano-wasm --only-dependencies --no-semaphore -j1 --ghc-options="-j1"
128+
129+
# Always store the cabal cache.
130+
# - name: Cache Cabal store
131+
# uses: actions/cache/save@v4
132+
# if: always()
133+
# with:
134+
# path: |
135+
# ${{ env.STORE }}
136+
# dist-newstyle
137+
# key:
138+
# ${{ steps.cache.outputs.cache-primary-key }}
139+
140+
# Now we build.
141+
- name: Build all
142+
run: |
143+
wasm32-wasi-cabal build cardano-wasm --no-semaphore -j1 --ghc-options="-j1"
144+
145+
# - name: Run tests
146+
# env:
147+
# TMPDIR: ${{ runner.temp }}
148+
# TMP: ${{ runner.temp }}
149+
# KEEP_WORKSPACE: 1
150+
# run: cabal test all --enable-tests --test-show-details=direct
151+
152+
# Uncomment the following back in for debugging. Remember to launch a `pwsh` from
153+
# the tmux session to debug `pwsh` issues. And be reminded that the `/msys2` and
154+
# `/msys2/mingw64` paths are not in PATH by default for the workflow, but tmate
155+
# will put them in.
156+
# You may also want to run
157+
#
158+
# $env:PATH=("C:\Program Files\PowerShell\7;{0}" -f $env:ORIGINAL_PATH)
159+
#
160+
# to restore the original path. Do note that some test might need msys2
161+
# and will silently fail if msys2 is not in path. See the "Run tests" step.
162+
#
163+
# - name: Setup tmate session
164+
# if: ${{ failure() }}
165+
# uses: mxschmitt/action-tmate@v3
166+
# with:
167+
# limit-access-to-actor: true
168+
169+
wasm-builds-complete:
170+
needs: [build]
171+
if: ${{ always() }}
172+
runs-on: ubuntu-latest
173+
steps:
174+
- name: Check if any previous job failed
175+
run: |
176+
if [[ "${{ needs.build.result }}" == "failure" ]]; then
177+
# this ignores skipped dependencies
178+
echo 'Required jobs failed to build.'
179+
exit 1
180+
else
181+
echo 'Build complete'
182+
fi
183+

.github/workflows/hls.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
test-hls-works:
1515
env:
1616
# Modify this value to "invalidate" the cache.
17-
HLS_CACHE_VERSION: "2024-07-24"
17+
HLS_CACHE_VERSION: "2025-06-11"
1818

1919
runs-on: ubuntu-latest
2020
timeout-minutes: 60

.gitignore

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ dist/
1919
result*
2020
/launch-*
2121
stack.yaml.lock
22+
*.hi
23+
*.o
24+
Main
2225

2326
/.cache
2427
/db
@@ -40,12 +43,12 @@ supervisord.pid
4043
tags
4144
/config
4245
/data
43-
./*.skey
44-
./*.vkey
45-
./*.cert
46+
/*.skey
47+
/*.vkey
48+
/*.cert
4649

4750
# For now require that users generate their own hie.yaml
48-
hie.yaml
51+
/hie.yaml
4952

5053
# Ignore Visual Studio code configuration
5154
.vscode/tasks.json

cabal.project

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ index-state:
1919
packages:
2020
cardano-api
2121
cardano-api-gen
22+
cardano-wasm
2223

2324
extra-packages: Cabal, process
2425

@@ -59,3 +60,94 @@ if impl (ghc >= 9.12)
5960
-- https://github.com/kapralVV/Unique/issues/11
6061
, Unique:hashable
6162

63+
-- WASM compilation specific
64+
65+
if arch(wasm32)
66+
source-repository-package
67+
type: git
68+
location: https://github.com/amesgen/plutus.git
69+
tag: dc1edea4458d6fb794b245a26c730620265645f3
70+
subdir:
71+
plutus-core
72+
plutus-ledger-api
73+
plutus-tx
74+
--sha256: sha256-QBtLmoS54b5QMAKIDOJIM6lmRC+1leBpuGKaFc7QQos=
75+
76+
package plutus-core
77+
flags: +do-not-build-plutus-exec
78+
79+
source-repository-package
80+
type: git
81+
location: https://github.com/haskell-wasm/hs-memory.git
82+
tag: a198a76c584dc2cfdcde6b431968de92a5fed65e
83+
--sha256: sha256-LRC3L+J921+/moZS7F17vCfM/4usYy/eMR+w/mXsjeA=
84+
85+
source-repository-package
86+
type: git
87+
location: https://github.com/palas/ouroboros-network.git
88+
tag: ef3e30603e4e45dac336a085114ee22b7aa8c9ed
89+
subdir:
90+
ouroboros-network
91+
ouroboros-network-framework
92+
--sha256: sha256-+IdAmWJqzRy+erKONywtk+5YLrm63q942nZavoEA4E4=
93+
94+
source-repository-package
95+
type: git
96+
location: https://github.com/palas/criterion.git
97+
tag: dd160d2b5f051e918e72fe1957d77905682b8d6c
98+
subdir:
99+
criterion-measurement
100+
--sha256: sha256-wzEwOUTeFL0C3QnS25/3X1ue2tUuedrLqtT0h1JZW6c=
101+
102+
source-repository-package
103+
type: git
104+
location: https://github.com/palas/haskell-lmdb-mock.git
105+
tag: c8d61e6eee03ee271e7768c0576110da885aec48
106+
--sha256: sha256-+gB1MmM6qRApz1p7tFsdvKoAWDrYB4a+bJ9Djm6ieYI=
107+
108+
source-repository-package
109+
type: git
110+
location: https://github.com/palas/double-conversion.git
111+
tag: b2030245727ee56de76507fe305e3741f6ce3260
112+
--sha256: sha256-kzwHHQzHPfPnIDtnSDAom7YGSzWjr0113x0zsfI/Tb0=
113+
114+
source-repository-package
115+
type: git
116+
location: https://github.com/amesgen/cborg
117+
tag: 2dff24d241d9940c5a7f5e817fcf4c1aa4a8d4bf
118+
subdir: cborg
119+
--sha256: sha256-yuz1apKQ0EB9LtJkc/I1EEtB4oZnURMvCckvdFbT6qM=
120+
121+
source-repository-package
122+
type: git
123+
location: https://github.com/Jimbo4350/foundation.git
124+
tag: b3cb78484fe6f6ce1dfcef59e72ceccc530e86ac
125+
subdir:
126+
basement
127+
foundation
128+
--sha256: sha256-QKKHl/XocxGD7bwAoGe7VaIg9o8x4dA20j3sJOgiTBw=
129+
130+
source-repository-package
131+
type: git
132+
location: https://github.com/palas/mempack.git
133+
tag: 0211addbbbf51011e5348d3696566eb12ccbef07
134+
--sha256: sha256-iLc+foF2AM3vG6deuZ51+faI6buMkubMP75md51hMe8=
135+
136+
source-repository-package
137+
type: git
138+
location: https://github.com/haskell-wasm/network
139+
tag: ab92e48e9fdf3abe214f85fdbe5301c1280e14e9
140+
--sha256: sha256-U+ln/gbXoQZpNjZHydNa0FG/9GdJFgL1+T3+7KTzDWo=
141+
142+
package cardano-crypto-praos
143+
flags: -external-libsodium-vrf
144+
145+
package atomic-counter
146+
flags: +no-cmm
147+
148+
constraints: time installed
149+
allow-newer: time
150+
151+
package crypton
152+
ghc-options: -optc-DARGON2_NO_THREADS
153+

cardano-api/cardano-api.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ common project-config
3838
-Wunused-packages
3939

4040
common maybe-unix
41-
if !os(windows)
41+
if !(os(windows)|| arch(wasm32))
4242
build-depends: unix
4343

4444
common maybe-Win32
@@ -236,6 +236,7 @@ library
236236
Cardano.Api.IO.Internal.Base
237237
Cardano.Api.IO.Internal.Compat
238238
Cardano.Api.IO.Internal.Compat.Posix
239+
Cardano.Api.IO.Internal.Compat.Wasm
239240
Cardano.Api.IO.Internal.Compat.Win32
240241
Cardano.Api.Internal.Orphans
241242
Cardano.Api.Internal.Orphans.Misc

cardano-api/src/Cardano/Api/IO/Internal/Compat.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ where
1111
import Cardano.Api.Error
1212
import Cardano.Api.IO.Internal.Base
1313
import Cardano.Api.IO.Internal.Compat.Posix
14+
import Cardano.Api.IO.Internal.Compat.Wasm
1415
import Cardano.Api.IO.Internal.Compat.Win32
1516

1617
import Control.Monad.Except (ExceptT)

cardano-api/src/Cardano/Api/IO/Internal/Compat/Posix.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-# LANGUAGE CPP #-}
22
{-# LANGUAGE ScopedTypeVariables #-}
33

4-
#if !defined(mingw32_HOST_OS)
4+
#if !defined(mingw32_HOST_OS) && !defined(wasm32_HOST_ARCH)
55
#define UNIX
66
#endif
77

0 commit comments

Comments
 (0)