aboutsummaryrefslogtreecommitdiffstats
path: root/flake.nix
diff options
context:
space:
mode:
Diffstat (limited to 'flake.nix')
-rw-r--r--flake.nix345
1 files changed, 279 insertions, 66 deletions
diff --git a/flake.nix b/flake.nix
index 14cc8de..c81b6b0 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,82 +1,295 @@
{
- description = "Sakura's flakes";
+ description = "Sakura Relational Engine";
+ # Flake dependency specification
+ #
+ # To update all flake inputs:
+ #
+ # $ nix flake update --commit-lockfile
+ #
+ # To update individual flake inputs:
+ #
+ # $ nix flake lock --update-input <input> ... --commit-lockfile
+ #
inputs = {
- nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
-
- flake-parts = {
- url = "github:hercules-ci/flake-parts";
- };
-
- treefmt-nix.url = "github:numtide/treefmt-nix";
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ # Convenience functions for writing flakes
+ flake-utils.url = "github:numtide/flake-utils";
+ # Precisely filter files copied to the nix store
+ nix-filter.url = "github:numtide/nix-filter";
};
- outputs = { self, nixpkgs, flake-parts, treefmt-nix, ... }@inputs:
- flake-parts.lib.mkFlake { inherit inputs; } {
- systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
-
- perSystem = { pkgs, system, ... }:
- let
- erlangLatest = pkgs.erlang_28;
-
- rebar_config = builtins.readFile ./rebar.config;
- match = builtins.match ".*release,.+sakura, \"([0-9.]+)\".*" rebar_config;
- pversion = builtins.head match;
- in {
- # This sets `pkgs` to a nixpkgs with allowUnfree option set.
- _module.args.pkgs = import nixpkgs {
- inherit system;
- config.allowUnfree = true;
+ outputs = { self, nixpkgs, flake-utils, nix-filter }:
+ # Construct an output set that supports a number of default systems
+ flake-utils.lib.eachDefaultSystem (system:
+ let
+ # Legacy packages that have not been converted to flakes
+ legacyPackages = nixpkgs.legacyPackages.${system};
+ # OCaml packages available on nixpkgs
+ # Library functions from nixpkgs
+ lib = legacyPackages.lib;
+ ocamlPackages = legacyPackages.ocamlPackages;
+ # merklecpp = legacyPackages.callPackage ./deps/merklecpp.nix { };
+ libressl = legacyPackages.callPackage ./deps/libressl.nix { };
+ ppx_protocol_conv =
+ legacyPackages.callPackage ./deps/ppx_protocol_conv.nix {
+ lib = legacyPackages.lib;
+ fetchFromGitHub = legacyPackages.fetchFromGitHub;
+ ocamlPackages = ocamlPackages; };
+ ppx_protocol_conv_xml_light =
+ legacyPackages.callPackage ./deps/ppx_protocol_conv_xml_light.nix {
+ lib = legacyPackages.lib;
+ ppx_protocol_conv = ppx_protocol_conv;
+ fetchFromGitHub = legacyPackages.fetchFromGitHub;
+ ocamlPackages = ocamlPackages; };
+ librelational_engine =
+ legacyPackages.callPackage ./deps/relational_engine_lib.nix {
+ libressl = libressl;
+ # merklecpp = merklecpp;
+ };
+ # Filtered sources (prevents unecessary rebuilds)
+ sources = {
+ ocaml = nix-filter.lib {
+ root = ./.;
+ include = [
+ ".ocamlformat"
+ "dune-project"
+ (nix-filter.lib.inDirectory "bin")
+ (nix-filter.lib.inDirectory "lib")
+ (nix-filter.lib.inDirectory "test")
+ ];
};
- # nix build
- packages = {
- default =
- let
- deps = import ./rebar-deps.nix {
- inherit (pkgs) fetchHex fetchFromGitHub fetchgit;
- builder = pkgs.beamPackages.buildRebar3;
- };
- in
- pkgs.beamPackages.rebar3Relx {
- pname = "sakura";
- version = pversion;
- src = pkgs.lib.cleanSource ./.;
- releaseType = "release";
- profile = "prod";
- buildInputs = (
- with pkgs;
- [
- coreutils
- gawk
- gnugrep
- openssl
- ]
- ++ lib.optional stdenv.isLinux [
- liburing
- ]
- );
- beamDeps = builtins.attrValues deps;
- };
+ nix = nix-filter.lib {
+ root = ./.;
+ include = [ (nix-filter.lib.matchExt "nix") ];
};
+ };
+ in {
+ # Exposed packages that can be built or run with `nix build` or
+ # `nix run` respectively:
+ #
+ # $ nix build .#<name>
+ # $ nix run .#<name> -- <args?>
+ #
+ packages = {
+ # The package that will be built or run by default. For example:
+ #
+ # $ nix build
+ # $ nix run -- <args?>
+ #
+ default = self.packages.${system}.relational_engine;
+
+ relational_engine = ocamlPackages.buildDunePackage {
+ pname = "relational_engine";
+ version = "0.1.0";
+ duneVersion = "3";
+ src = sources.ocaml;
- # Define devShell for Erlang + Rebar3
- devShells = {
- default = pkgs.mkShell {
- packages = with pkgs; [
- erlang-language-platform
- rebar3
- ] ++ [erlangLatest];
+ env = {
+ # MERKLECPP_INCLUDE_PATH = "${merklecpp}/include";
+ LIBRESSL_INCLUDE_PATH = "${libressl}/include";
+ LIBRESSL_LIB_PATH = "${libressl}/lib";
+ OS_LIB_EXTENSION =
+ if legacyPackages.stdenv.isDarwin then "dylib" else "so";
+ LIBRELATIONAL_ENGINE_LIB_PATH = "${librelational_engine}/lib";
+ LIBRELATIONAL_ENGINE_INCLUDE_PATH = "${librelational_engine}/include";
};
+
+ nativeInputs = [ ];
+
+ buildInputs = [ ppx_protocol_conv_xml_light
+ ppx_protocol_conv ]
+ ++ (with ocamlPackages; [
+ ctypes
+ ctypes-foreign
+ data-encoding
+ ppx_inline_test
+ ppx_deriving
+ ppx_sexp_conv
+ lwt
+ lwt-exit
+ ]);
+
+ strictDeps = true;
+
};
+ };
+ # Flake checks
+ #
+ # $ nix flake check
+ #
+ checks = {
+ # Run tests for the `relational_engine` package
+ relational_engine = let
+ # Patches calls to dune commands to produce log-friendly output
+ # when using `nix ... --print-build-log`. Ideally there would be
+ # support for one or more of the following:
+ #
+ # In Dune:
+ #
+ # - have workspace-specific dune configuration files
+ #
+ # In NixPkgs:
+ #
+ # - allow dune flags to be set in in `ocamlPackages.buildDunePackage`
+ # - alter `ocamlPackages.buildDunePackage` to use `--display=short`
+ # - alter `ocamlPackages.buildDunePackage` to allow `--config-file=FILE` to be set
+ patchDuneCommand =
+ let subcmds = [ "build" "test" "runtest" "install" ];
+ in lib.replaceStrings
+ (lib.lists.map (subcmd: "dune ${subcmd}") subcmds)
+ (lib.lists.map (subcmd: "dune ${subcmd} --display=short")
+ subcmds);
+
+ in self.packages.${system}.relational_engine.overrideAttrs
+ (oldAttrs: {
+ name = "check-${oldAttrs.name}";
+ doCheck = true;
+ buildPhase = patchDuneCommand oldAttrs.buildPhase;
+ checkPhase = patchDuneCommand oldAttrs.checkPhase;
+ # skip installation (this will be tested in the `relational_engine-app` check)
+ installPhase = "touch $out";
+ });
+
+ # Check Dune and OCaml formatting
+ dune-fmt = legacyPackages.runCommand "check-dune-fmt" {
+ nativeBuildInputs = [
+ ocamlPackages.dune_3
+ ocamlPackages.ocaml
+ legacyPackages.ocamlformat
+ ];
+ } ''
+ echo "checking dune and ocaml formatting"
+ dune build \
+ --display=short \
+ --no-print-directory \
+ --root="${sources.ocaml}" \
+ --build-dir="$(pwd)/_build" \
+ @fmt
+ touch $out
+ '';
+
+ dune-test = legacyPackages.runCommand "check-dune-test" {
+ nativeBuildInputs = [
+ ocamlPackages.dune_3
+ ocamlPackages.ocaml
+ legacyPackages.ocamlformat
+ ocamlPackages.ppx_inline_test
+ ocamlPackages.ppx_deriving
+ ocamlPackages.ppx_sexp_conv
+ ocamlPackages.lwt
+ ocamlPackages.lwt-exit
+ ppx_protocol_conv
+ ppx_protocol_conv_xml_light
+ ];
+ } ''
+ echo "checking dune and ocaml formatting"
+ dune build \
+ --display=short \
+ --no-print-directory \
+ --root="${sources.ocaml}" \
+ --build-dir="$(pwd)/_build" \
+ @fmt
+ touch $out
+ '';
+
+ # Check documentation generation
+ dune-doc = legacyPackages.runCommand "check-dune-doc" {
+ ODOC_WARN_ERROR = "true";
+ nativeBuildInputs =
+ [ ocamlPackages.dune_3 ocamlPackages.ocaml ocamlPackages.odoc ];
+ } ''
+ echo "checking ocaml documentation"
+ dune build \
+ --display=short \
+ --no-print-directory \
+ --root="${sources.ocaml}" \
+ --build-dir="$(pwd)/_build" \
+ @doc
+ touch $out
+ '';
+
+ # Check Nix formatting
+ # nixpkgs-fmt = legacyPackages.runCommand "check-nixpkgs-fmt" {
+ # nativeBuildInputs = [ legacyPackages.nixpkgs-fmt ];
+ # } ''
+ # echo "checking nix formatting"
+ # nixpkgs-fmt --check ${sources.nix}
+ # touch $out
+ # '';
+ };
+
+ # Development shells
+ #
+ # $ nix develop .#<name>
+ # $ nix develop .#<name> --command dune build @test
+ #
+ # [Direnv](https://direnv.net/) is recommended for automatically loading
+ # development environments in your shell. For example:
+ #
+ # $ echo "use flake" > .envrc && direnv allow
+ # $ dune build @test
+ #
+ devShells = {
+ default = legacyPackages.mkShell {
+
+ env = {
+ # MERKLECPP_INCLUDE_PATH = "${merklecpp}/include";
+ LIBRESSL_INCLUDE_PATH = "${libressl}/include";
+ LIBRESSL_LIB_PATH = "${libressl}/lib";
+ OS_LIB_EXTENSION =
+ if legacyPackages.stdenv.isDarwin then "dylib" else "so";
+ LIBRELATIONAL_ENGINE_LIB_PATH = "${librelational_engine}/lib";
+ LIBRELATIONAL_ENGINE_INCLUDE_PATH = "${librelational_engine}/include";
+ };
+
+ # Development tools
+ packages = [
+ # Source file formatting
+ legacyPackages.nixpkgs-fmt
+ legacyPackages.ocamlformat
+ # For `dune build --watch ...`
+ # legacyPackages.fswatch
+ # For `dune build @doc`
+ ocamlPackages.odoc
+ # OCaml editor support
+ ocamlPackages.ocaml-lsp
+ # Nicely formatted types on hover
+ ocamlPackages.ocamlformat-rpc-lib
+ # Fancy REPL thing
+ ocamlPackages.utop
+ # Libraries
+ # ocamlPackages.menhir
+ ocamlPackages.ctypes
+ ocamlPackages.ctypes-foreign
+ ocamlPackages.data-encoding
+ ocamlPackages.ppx_inline_test
+ ocamlPackages.ppx_deriving
+ ocamlPackages.ppx_sexp_conv
+ legacyPackages.cmake
+ legacyPackages.gcc
+ # legacyPackages.nixfmt-classic
+ ocamlPackages.lwt
+ ocamlPackages.lwt-exit
+ ppx_protocol_conv
+ ppx_protocol_conv_xml_light
+ ocamlPackages.earlybird
+ ];
+
- # Formatter setup for Nix files
- formatter = treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
+ shellHook = ''
+ # echo MERKLECPP_INCLUDE_PATH=$MERKLECPP_INCLUDE_PATH
+ echo LIBRESSL_INCLUDE_PATH=$LIBRESSL_INCLUDE_PATH
+ echo LIBRESSL_LIB_PATH=$LIBRESSL_LIB_PATH
+ # echo OS_LIB_EXTENSION=$OS_LIB_EXTENSION
+ echo LIBRELATIONAL_ENGINE_LIB_PATH=$LIBRELATIONAL_ENGINE_LIB_PATH
+ echo LIBRELATIONAL_ENGINE_INCLUDE_PATH=$LIBRELATIONAL_ENGINE_INCLUDE_PATH
+ '';
- # nix flake check --all-systems
- checks = {
- formatting = treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
+ # Tools from packages
+ inputsFrom = [ self.packages.${system}.relational_engine ];
};
};
- };
+ });
}