Skip to content

Commit

Permalink
flake: cleanup & expose dynamic output
Browse files Browse the repository at this point in the history
Cleans up the nix flake as follows:

- conform to modern nixpkgs standards by removing the `with` statements
  and making scoping explicit
- removing `flake-compat` (which was broken on macos due to
  edolstra/flake-compat#53).

Additionally reworks the structure a little and makes the default flake
output dynamically linked, making it easier to consume from other nix
flakes (e.g. act).
  • Loading branch information
d-xo committed Oct 22, 2024
1 parent 52a0ec1 commit 1c61d72
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 75 deletions.
17 changes: 0 additions & 17 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 53 additions & 54 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
foundry.url = "github:shazow/foundry.nix/47f8ae49275eeff9bf0526d45e3c1f76723bb5d3";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
solidity = {
url = "github:ethereum/solidity/8a97fa7a1db1ec509221ead6fea6802c684ee887";
flake = false;
Expand All @@ -27,7 +23,7 @@
};
};

outputs = { self, nixpkgs, flake-utils, solidity, forge-std, ethereum-tests, foundry, solc-pkgs, ... }:
outputs = { nixpkgs, flake-utils, solidity, forge-std, ethereum-tests, foundry, solc-pkgs, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = (import nixpkgs {
Expand All @@ -36,21 +32,21 @@
config = { allowBroken = true; };
});
solc = (solc-pkgs.mkDefault pkgs pkgs.solc_0_8_26);
testDeps = with pkgs; [
go-ethereum
testDeps = [
solc
z3_4_12
cvc5
git
bitwuzla
foundry.defaultPackage.${system}
pkgs.go-ethereum
pkgs.z3_4_12
pkgs.cvc5
pkgs.git
pkgs.bitwuzla
];

secp256k1-static = stripDylib (pkgs.secp256k1.overrideAttrs (attrs: {
configureFlags = attrs.configureFlags ++ [ "--enable-static" ];
}));

hsPkgs = ps :
hspkgs = ps :
ps.haskellPackages.override {
overrides = hfinal: hprev: {
with-utf8 =
Expand All @@ -61,9 +57,10 @@
witch = ps.haskell.lib.doJailbreak hprev.witch;
};
};
hlib = pkgs.haskell.lib;

hevmBase = ps :
((hsPkgs ps).callCabal2nix "hevm" ./. {
((hspkgs ps).callCabal2nix "hevm" ./. {
# Haskell libs with the same names as C libs...
# Depend on the C libs, not the Haskell libs.
# These are system deps, not Cabal deps.
Expand All @@ -75,13 +72,14 @@
DAPP_SOLC = "${solc}/bin/solc";
});

hevmUnwrapped = { ps ? if pkgs.stdenv.isDarwin then pkgs else pkgs.pkgsStatic } :
(ps.lib.pipe
hevmUnwrapped = let
ps = if pkgs.stdenv.isDarwin then pkgs else pkgs.pkgsStatic;
in (ps.lib.pipe
(hevmBase ps)
[
(ps.haskell.lib.compose.overrideCabal (old: { testTarget = "test"; }))
(ps.haskell.lib.compose.addTestToolDepends testDeps)
(ps.haskell.lib.compose.appendConfigureFlags (
(hlib.compose.overrideCabal (old: { testTarget = "test"; }))
(hlib.compose.addTestToolDepends testDeps)
(hlib.compose.appendConfigureFlags (
[ "-fci"
"-O2"
]
Expand All @@ -93,32 +91,10 @@
"--extra-lib-dirs=${stripDylib (ps.libffi.overrideAttrs (_: { dontDisableStatic = true; }))}/lib"
"--extra-lib-dirs=${stripDylib (ps.ncurses.override { enableStatic = true; })}/lib"
]))
ps.haskell.lib.compose.dontHaddock
ps.haskell.lib.compose.doCheck
hlib.compose.dontHaddock
hlib.compose.doCheck
]);

# wrapped binary for use on systems with nix available.
# does not statically link.
# ensures all required runtime deps are available and on path.
hevmWrapped =
pkgs.symlinkJoin {
name = "hevm";
paths = [ (pkgs.haskell.lib.dontCheck (hevmUnwrapped { ps = pkgs; } )) ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/hevm \
--prefix PATH : "${pkgs.lib.makeBinPath [
pkgs.bash
pkgs.coreutils
pkgs.git
pkgs.z3
pkgs.cvc5
pkgs.bitwuzla
solc
]}"
'';
};

# "static" binary for distribution
# on linux this is actually a real fully static binary
# on macos this has everything except libcxx, libsystem and libiconv
Expand Down Expand Up @@ -160,6 +136,29 @@
chmod 555 $out/bin/hevm
'';


# wrapped binary for use on systems with nix available.
# does not statically link.
# ensures all required runtime deps are available and on path.
hevmWrapped =
pkgs.symlinkJoin {
name = "hevm";
paths = [ (hlib.dontCheck (hevmBase pkgs)) ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/hevm \
--prefix PATH : "${pkgs.lib.makeBinPath [
pkgs.bash
pkgs.coreutils
pkgs.git
pkgs.z3
pkgs.cvc5
pkgs.bitwuzla
solc
]}"
'';
};

# if we pass a library folder to ghc via --extra-lib-dirs that contains
# only .a files, then ghc will link that library statically instead of
# dynamically (even if --enable-executable-static is not passed to cabal).
Expand All @@ -175,8 +174,8 @@

# --- packages ----

packages.ci = with pkgs.haskell.lib; doBenchmark (dontHaddock (disableLibraryProfiling hevmUnwrapped));
packages.noTests = pkgs.haskell.lib.dontCheck hevmUnwrapped;
packages.ci = pkgs.lib.pipe hevmUnwrapped (with hlib.compose; [doBenchmark dontHaddock disableLibraryProfiling]);
packages.noTests = hlib.dontCheck (hevmBase pkgs);
packages.hevm = hevmWrapped;
packages.redistributable = hevmRedistributable;
packages.default = packages.hevm;
Expand All @@ -188,17 +187,17 @@

# --- shell ---

devShells.default = with pkgs; let
libraryPath = "${lib.makeLibraryPath [ libff secp256k1 gmp ]}";
in haskellPackages.shellFor {
devShells.default = let
libraryPath = "${pkgs.lib.makeLibraryPath [ pkgs.libff pkgs.secp256k1 pkgs.gmp ]}";
in (hspkgs pkgs).shellFor {
packages = _: [ (hevmBase pkgs) ];
buildInputs = [
curl
haskellPackages.cabal-install
mdbook
yarn
haskellPackages.eventlog2html
haskellPackages.haskell-language-server
pkgs.curl
pkgs.mdbook
pkgs.yarn
(hspkgs pkgs).cabal-install
(hspkgs pkgs).eventlog2html
(hspkgs pkgs).haskell-language-server
] ++ testDeps;
withHoogle = true;

Expand All @@ -210,7 +209,7 @@

# point cabal repl to system deps
LD_LIBRARY_PATH = libraryPath;
shellHook = lib.optionalString stdenv.isDarwin ''
shellHook = pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
export DYLD_LIBRARY_PATH="${libraryPath}";
'';
};
Expand Down
7 changes: 3 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@ nix profile install github:ethereum/hevm
We use `nix` to manage project dependencies. To start hacking on hevm you should first [install
nix](https://nixos.org/download.html).

Once nix is installed you can run `nix-shell` (or `nix develop` if you use flakes) from the repo
root to enter a development shell containing all required dev dependencies. If you use
[direnv](https://direnv.net/), then you can run `direnv allow`, and the shell will be automatically
entered each time you cd in the project repo.
Once nix is installed you can run `nix develop` from the repo root to enter a development shell
containing all required dev dependencies. If you use [direnv](https://direnv.net/), then you can run
`direnv allow`, and the shell will be automatically entered each time you cd in the project repo.

Once in the shell you can use the usual `cabal` commands to build and test hevm:

Expand Down

0 comments on commit 1c61d72

Please sign in to comment.