Building
Prerequisites
cardano-wallet
uses the following Haskell build tool versions.
Cabal
Note: the Cabal build is checked by Buildkite.
-
Update your Hackage index (this may take a while):
> cabal update
Don't skip this, otherwise there may be warnings from Cabal about index states, or some packages will fail to build.
-
Build the project packages:
> cabal build all
-
Run the freshly-built
cardano-wallet
executable.As an example, this will show the help page:
> cabal run cardano-wallet:exe:cardano-wallet -- --help
-
Make a build with
-O2
level compiler optimizations:> cabal build cardano-wallet:exe:cardano-wallet -frelease
-
Build and run the test suites or benchmarks.
First, enable tests and benchmarks:
> cabal configure --enable-tests --enable-benchmarks
To run one of the unit test suites:
> cabal run cardano-wallet:test:unit
To run the DB benchmark:
> cabal run cardano-wallet:bench:db
To run the integration test suite:
> cabal run cardano-wallet:test:integration
-
Install binaries from
./dist-newstyle/
into a system location:> cabal install --install-method=copy --installdir=/usr/local/bin
-
Build without
scrypt
(for compatibility with Apple M1 chip)> cabal configure --disable-tests --disable-benchmarks -f-scrypt -O2 > cabal build cardano-wallet:exe:cardano-wallet
Nix
Use the Nix build if:
- You don't have Haskell development tools installed, but you do have Nix installed.
- You would like to cross-compile a build for Windows, or run the tests under Wine.
- You would like to quickly grab a build of another branch from the Hydra cache, without needing to build it yourself.
Follow the instructions on the Nix page to install and configure Nix.
As of 2022-12, the following information is out of date as https://hydra.iohk.io/ has been decomissioned.
Note: It must be stressed that, if you see GHC being built by Nix, then you don't have the IOHK Hydra binary cache configured correctly.
To build the wallet for your current platform:
> nix build
The resulting executable will appear at ./result/bin/cardano-wallet
.
Unless you have local changes in your git repo, Nix will download the build from a nix cache rather than building locally.
You may also run the executable directly with:
> nix run . -- <cardano wallet arguments>
or more comfortably, for pre-configured networks (mainnet
, testnet
, ...):
> CARDANO_NODE_SOCKET_PATH=../cardano-node/node.socket
> nix run .#mainnet/wallet -- <optional additional cardano wallet arguments>
You may run the integration tests with:
nix run .#packages.x86_64-linux.checks.cardano-wallet.integration
Cross-compiling with Nix
To build the wallet for Windows, from Linux:
nix build .#hydraJobs.linux.windows.cardano-wallet
Building straight from GitHub
The following command will build the master
branch, with the resulting executable appearing at ./result/bin/cardano-wallet
. To build another branch, add /<branch name, tag, or commit hash>
(see Nix Manual: Flake References for syntax). As before, if the target ref has already been built by Hydra, then it will be fetched from cache rather than built locally.
> nix build github:input-output-hk/cardano-wallet
> ./result/bin/cardano-wallet version
v2022-01-18 (git revision: ce772ff33623e2a522dcdc15b1d360815ac1336a)
Cabal+Nix build
Use the Cabal+Nix build if you want to develop with incremental builds, but also have it automatically download cached builds of all dependencies.
If you run nix develop
, it will start a
development environment
for cardano-wallet
. This will contain:
cabal-install
and a GHC configured with a package database containing all Haskell package dependencies;- system library dependencies;
- a Hoogle index and
hoogle
command for searching documentation; - development tools such as
haskell-language-server
,hlint
,stylish-haskell
, andweeder
; - the
sqlite3
command; - the Shelley node backend
cardano-node
andcardano-cli
; and - other Adrestia utility programs such as
cardano-address
andbech32
Inside this shell you can use cabal build
and ghci
for development.
For example, you might start an incremental build of the integration test suite with:
ghcid -c "cabal repl test:integration"
and run the test suite with:
cabal run test:integration
Profiling build with cached dependencies
Use nix develop .#profiled
to get a shell where Haskell
dependencies are built with profiling enabled. You won't need to
rebuild all of the dependencies because they can be downloaded from
the Hydra cache.
> nix develop .#profiled
[nix-shell:~/iohk/cardano-wallet]$ cabal build \
--enable-tests --enable-benchmarks \
--enable-profiling \
all
Haskell-Language-Server
The haskell-language-server provides an IDE for developers with some typical features:
- Jump to definition.
- Find references.
- Documentation on hover.
- etc.
Prerequisites
The following must be installed:
We do not require a special version per-project so these executables can be installed system-wide.
Additionally, the following tools are provided by the cardano-wallet nix development shell:
We require a particular version of each per-project, so it's recommended to use the nix development environment to ensure you have the correct version.
In these instructions we enter a nix development environment using direnv allow
rather than nix develop
or nix-shell
(see Editor Setup).
Setup
haskell-language-server requires some priming to work with cardano-wallet:
# Symlink hie.yaml to hie-direnv.yaml, which is the project configuration for haskell-language-server
ln -sf hie-direnv.yaml hie.yaml
# Build and cache the nix development environment
direnv allow
# Generate a build plan
cabal configure --enable-tests --enable-benchmarks -O0
# Build entire project
cabal build all
This will prime haskell-language-server to work with all modules of the project (tests, benchmarks, etc.) and be fully featured. Without these steps, haskell-language-server may fail to:
- Find auto-generated modules (such as Paths_* modules).
- Navigate across projects (jump-to-definition).
- Provide documentation on hover.
Testing
To test the haskell-language-server, use the following commands (these should be in your $PATH because you executed direnv allow
previously, or have entered a nix development environment):
hie-bios check lib/wallet/src/Cardano/Wallet.hs
haskell-language-server lib/wallet/exe/cardano-wallet.hs
Occasionally hie-bios
will fail with a Segmentation Fault
. In these cases just run hie-bios
again.
Note that these commands will only test a couple of files. To test the whole project, see Troubleshooting.
Editor Setup
With a working installation of haskell-language-server, we can integrate with our IDE of choice. See Configuring Your Editor.
IMPORTANT: you need to ensure that your editor invokes the same version of haskell-language-server that we have configured above. A simple way to do that is to launch your editor from within a nix development environment (e.g. nix develop --command 'vim'
), or, more practically, to configure your editor with direnv
support. Here are some examples:
Troubleshooting
Helpful resources:
- Configuring haskell-language-server
- hie-bios BIOS Configuration
- Troubleshooting haskell-language-server
The Testing commands only tested a subset of the files in the project. To troubleshoot configuration issues, it's important to determine the source of the error.
If you know the source of the error, you can reproduce it on the command line with haskell-language-server <the file>
. There are debug flags which might be useful (see --help
).
If you do not know the source of the error, you can test every file in the project with:
# Provide list_sources function.
source "$(dirname "$0")/../cabal-lib.sh"
# Get every file in the project.
mapfile -t srcs < <(list_sources)
# Execute haskell-language-server on every file in the project.
# Note that this command can take upwards of an hour.
haskell-language-server "${srcs[@]}"
Once you can reproduce the error, look through the Worked Examples below and see if you can resolve the issue. If you cannot, raise a GitHub issue (external) or a JIRA issue (internal) with reproduction steps and tag @sevanspowell or @rvl.
Worked Examples
NOTE: hie-bios BIOS Configuration is helpful background reading.
Source Filtering
In the past haskell-language-server failed when processing the lib/wallet/extra/Plutus/FlatInteger.hs
file, as it was technically a Haskell file in the repository, but wasn't intended to be compiled with the project.
To fix this issue, we excluded the lib/wallet/extra
folder from the project sources.
The bash function list_sources
in scripts/cabal-lib.sh
is responsible for determining the source files haskell-language-server sees. Modify this function to further remove any other files you wish to exclude:
list_sources() {
# Exclude lib/wallet/extra. Those files are Plutus scripts intended
# to be serialised for use in the tests. They are not intended to be built
# with the project.
# Exclude prototypes dir because it's a different project.
git ls-files 'lib/**/*.hs' | grep -v Main.hs | grep -v prototypes/ | grep -v lib/wallet/extra
}
GHCI Flags
There were previously issues debugging overlapping/ambiguous instances as the error message printed by haskell-language-server did not contain enough information. We rectified this by adding -fprint-potential-instances
to the GHCI flags of the haskell-language-server BIOS.
The bash function ghci_flags
in scripts/cabal-lib.sh
is responsible for providing the GHCI flags haskell-language-server uses. Modify this file with any other GHC flags you may require:
ghci_flags() {
cat <<EOF
-XOverloadedStrings
-XNoImplicitPrelude
-XTypeApplications
-XDataKinds
-fwarn-unused-binds
-fwarn-unused-imports
-fwarn-orphans
-fprint-potential-instances
-Wno-missing-home-modules
EOF
...
}