~jonsterling/forester-devel

Nix-based static forester build

Details
Message ID
<87wmg7f7aj.fsf@owenlynch.org>
DKIM signature
pass
Download raw message
Patch: +94 -129
Hi Jon,

I've finally managed to figure out the right incantations to build
forester statically through nix.

Notes:

1. It doesn't work to simply build this with a statically-linked OCaml compiler;
in fact the OCaml compiler itself must be dynamically linked for ppx_deriving
to be supported.
2. I've also managed to figure out how to not do the janky thing with applying
the patch to change the compiler options; instead I do that with a dune profile
now.
3. I removed "open Eio.Std" because ocaml complained that it was unused.

Now that I've managed to get the 5.0 prerelease compiled statically, I'm excited
to play around with the new features for forest exports and cross-forest
transclusion!

- Owen

---
 Dockerfile            |  29 ------------
 bin/forester/dune     |   4 +-
 bin/forester/main.ml  |   1 -
 build-static-linux.sh |  11 -----
 dune                  |   3 ++
 flake.lock            | 108 +++++++++++++++++++-----------------------
 flake.nix             |  54 +++++++++++++++------
 static.patch          |  13 -----
 8 files changed, 94 insertions(+), 129 deletions(-)
 delete mode 100644 Dockerfile
 delete mode 100755 build-static-linux.sh
 create mode 100644 dune
 delete mode 100644 static.patch

diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 025a995..0000000
--- a/Dockerfile
@@ -1,29 +0,0 @@
# SPDX-FileCopyrightText: 2024 The Forester Project Contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later

FROM ocaml/opam:alpine-3.20-ocaml-5.2-flambda AS forester-builder

RUN sudo apk update

RUN sudo apk add linux-headers

RUN mkdir forester

WORKDIR /home/opam/forester

ADD . .

RUN sudo chown -R opam .

RUN git apply static.patch

RUN opam install dune

RUN opam install --deps .

RUN eval $(opam config env) && dune build

FROM scratch AS forester-built
COPY --from=forester-builder /home/opam/forester/_build/default/bin/forester/main.exe /bin/forester
ENTRYPOINT [ "/bin/forester" ]
diff --git a/bin/forester/dune b/bin/forester/dune
index 8267c08..3dc4189 100644
--- a/bin/forester/dune
@@ -5,8 +5,8 @@
(executable
 (public_name forester)
 (name main)
 (flags (-g))
 (link_flags (-g))
 (flags (:standard -g))
 (link_flags (:standard -g))
 (preprocess
  (pps ppx_deriving.show))
  (libraries
diff --git a/bin/forester/main.ml b/bin/forester/main.ml
index ace8079..554f6b7 100644
--- a/bin/forester/main.ml
@@ -4,7 +4,6 @@
 * SPDX-License-Identifier: GPL-3.0-or-later
 *)

open Eio.Std
open Forester_prelude
open Forester_core
open Forester_frontend
diff --git a/build-static-linux.sh b/build-static-linux.sh
deleted file mode 100755
index 1534c86..0000000
--- a/build-static-linux.sh
@@ -1,11 +0,0 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2024 The Forester Project Contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later

mkdir -p docker-build
docker buildx build . --output=forester

# TODO: figure out how to automate getting the release version here
tar -czf forester-5.0-dev-x86_64-unknown-linux-musl.tar.gz forester
diff --git a/dune b/dune
new file mode 100644
index 0000000..4cc7e13
--- /dev/null
+++ b/dune
@@ -0,0 +1,3 @@
(env
 (static
  (link_flags (-ccopt -static))))
diff --git a/flake.lock b/flake.lock
index 074c03b..094d125 100644
--- a/flake.lock
+++ b/flake.lock
@@ -3,11 +3,11 @@
    "flake-compat": {
      "flake": false,
      "locked": {
        "lastModified": 1627913399,
        "narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
        "lastModified": 1696426674,
        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
        "owner": "edolstra",
        "repo": "flake-compat",
        "rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
        "type": "github"
      },
      "original": {
@@ -21,11 +21,11 @@
        "systems": "systems"
      },
      "locked": {
        "lastModified": 1726560853,
        "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
        "lastModified": 1731533236,
        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
        "type": "github"
      },
      "original": {
@@ -35,12 +35,15 @@
      }
    },
    "flake-utils_2": {
      "inputs": {
        "systems": "systems_2"
      },
      "locked": {
        "lastModified": 1638122382,
        "narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
        "lastModified": 1726560853,
        "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
        "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
        "type": "github"
      },
      "original": {
@@ -52,11 +55,11 @@
    "mirage-opam-overlays": {
      "flake": false,
      "locked": {
        "lastModified": 1661959605,
        "narHash": "sha256-CPTuhYML3F4J58flfp3ZbMNhkRkVFKmBEYBZY5tnQwA=",
        "lastModified": 1710922379,
        "narHash": "sha256-j4QREQDUf8oHOX7qg6wAOupgsNQoYlufxoPrgagD+pY=",
        "owner": "dune-universe",
        "repo": "mirage-opam-overlays",
        "rev": "05f1c1823d891ce4d8adab91f5db3ac51d86dc0b",
        "rev": "797cb363df3ff763c43c8fbec5cd44de2878757e",
        "type": "github"
      },
      "original": {
@@ -67,11 +70,11 @@
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1729880355,
        "narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=",
        "lastModified": 1733581040,
        "narHash": "sha256-Qn3nPMSopRQJgmvHzVqPcE3I03zJyl8cSbgnnltfFDY=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "18536bf04cd71abd345f9579158841376fdd0c5a",
        "rev": "22c3f2cf41a0e70184334a958e6b124fb0ce3e01",
        "type": "github"
      },
      "original": {
@@ -81,38 +84,26 @@
        "type": "github"
      }
    },
    "nixpkgs_2": {
      "locked": {
        "lastModified": 1682362401,
        "narHash": "sha256-/UMUHtF2CyYNl4b60Z2y4wwTTdIWGKhj9H301EDcT9M=",
        "owner": "nixos",
        "repo": "nixpkgs",
        "rev": "884ac294018409e0d1adc0cae185439a44bd6b0b",
        "type": "github"
      },
      "original": {
        "owner": "nixos",
        "ref": "nixos-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "opam-nix": {
      "inputs": {
        "flake-compat": "flake-compat",
        "flake-utils": "flake-utils_2",
        "mirage-opam-overlays": "mirage-opam-overlays",
        "nixpkgs": "nixpkgs_2",
        "nixpkgs": [
          "nixpkgs"
        ],
        "opam-overlays": "opam-overlays",
        "opam-repository": "opam-repository",
        "opam-repository": [
          "opam-repository"
        ],
        "opam2json": "opam2json"
      },
      "locked": {
        "lastModified": 1716292162,
        "narHash": "sha256-UOJNCbqvxABD56JZtZkv3C9ufdqrs7/Ep4AKkCHgPuo=",
        "lastModified": 1732617437,
        "narHash": "sha256-jj25fziYrES8Ix6HkfSiLzrN6MZjiwlHUxFSIuLRjgE=",
        "owner": "tweag",
        "repo": "opam-nix",
        "rev": "1d3cbd6d3f247db77cb581c88c9a1d72e4acad60",
        "rev": "ea8b9cb81fe94e1fc45c6376fcff15f17319c445",
        "type": "github"
      },
      "original": {
@@ -124,11 +115,11 @@
    "opam-overlays": {
      "flake": false,
      "locked": {
        "lastModified": 1654162756,
        "narHash": "sha256-RV68fUK+O3zTx61iiHIoS0LvIk0E4voMp+0SwRg6G6c=",
        "lastModified": 1726822209,
        "narHash": "sha256-bwM18ydNT9fYq91xfn4gmS21q322NYrKwfq0ldG9GYw=",
        "owner": "dune-universe",
        "repo": "opam-overlays",
        "rev": "c8f6ef0fc5272f254df4a971a47de7848cc1c8a4",
        "rev": "f2bec38beca4aea9e481f2fd3ee319c519124649",
        "type": "github"
      },
      "original": {
@@ -140,27 +131,11 @@
    "opam-repository": {
      "flake": false,
      "locked": {
        "lastModified": 1705008664,
        "narHash": "sha256-TTjTal49QK2U0yVOmw6rJhTGYM7tnj3Kv9DiEEiLt7E=",
        "owner": "ocaml",
        "repo": "opam-repository",
        "rev": "fa77046c6497f8ca32926acdb7eb1e61777d4c17",
        "type": "github"
      },
      "original": {
        "owner": "ocaml",
        "repo": "opam-repository",
        "type": "github"
      }
    },
    "opam-repository_2": {
      "flake": false,
      "locked": {
        "lastModified": 1730065415,
        "narHash": "sha256-ky2HYwZMNVS1gJyQxFOWowV/lE2Itee9eLHA9lolJVw=",
        "lastModified": 1733656817,
        "narHash": "sha256-ddoiIYY6AhWLUxkgtXhPbB7Du0OcHPyR4iEF/Tm8BsY=",
        "owner": "ocaml",
        "repo": "opam-repository",
        "rev": "6383bc5431ca714c10b4e29dbf7eda9572a4ac07",
        "rev": "211ce1c3d5d6eb57dee3ca21cb1e4a16da41d01f",
        "type": "github"
      },
      "original": {
@@ -195,7 +170,7 @@
        "flake-utils": "flake-utils",
        "nixpkgs": "nixpkgs",
        "opam-nix": "opam-nix",
        "opam-repository": "opam-repository_2"
        "opam-repository": "opam-repository"
      }
    },
    "systems": {
@@ -212,6 +187,21 @@
        "repo": "default",
        "type": "github"
      }
    },
    "systems_2": {
      "locked": {
        "lastModified": 1681028828,
        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
        "owner": "nix-systems",
        "repo": "default",
        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default",
        "type": "github"
      }
    }
  },
  "root": "root",
diff --git a/flake.nix b/flake.nix
index ea57f50..7be1aec 100644
--- a/flake.nix
+++ b/flake.nix
@@ -8,7 +8,11 @@
    flake-utils.url = "github:numtide/flake-utils";
    opam-repository.url = "github:ocaml/opam-repository";
    opam-repository.flake = false;
    opam-nix.url = "github:tweag/opam-nix";
    opam-nix = {
      url = "github:tweag/opam-nix";
      inputs.nixpkgs.follows = "nixpkgs";
      inputs.opam-repository.follows = "opam-repository";
    };
  };
  outputs =
    {
@@ -25,30 +29,52 @@
      system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
        pkgsDyn = pkgs;
        isGnu64 = system == "x86_64-linux";
        pkgsStatic = if isGnu64
                     then
                       import nixpkgs {
                         localSystem = nixpkgs.lib.systems.examples.gnu64;
                         crossSystem = nixpkgs.lib.systems.examples.musl64;
                       } else pkgs;
        on = opam-nix.lib.${system};
        devPackagesQuery = {
          ocaml-base-compiler = "5.2.0";
          ocaml-lsp-server = "*";
          ocamlformat = "*";
          memtrace = "*";
        };
        query = devPackagesQuery // { };
        scope = on.buildOpamProject' { repos = [ "${opam-repository}" ]; } ./. query;
        overlay = final: prev: {
          ${package} = prev.${package}.overrideAttrs (_: {
            doNixSupport = false;
          });
        query = devPackagesQuery // {
          ocaml-system = "*";
        };
        scope' = scope.overrideScope' overlay;
        main = scope'.${package};
        devPackages = builtins.attrValues (pkgs.lib.getAttrs (builtins.attrNames devPackagesQuery) scope');
        mkScopes = pkgs: isStatic: rec {
          scope = on.buildDuneProject { inherit pkgs; } package ./. query;
          overlay = final: prev: {
            # You can add overrides here
            ${package} = prev.${package}.overrideAttrs (_: {
              doNixSupport = false;
            } // (if isStatic then {
              buildPhase = ''dune build -p ${package} --profile static -j $NIX_BUILD_CORES'';
            } else {}));
            ocamlgraph = prev.ocamlgraph.overrideAttrs (_: {
              buildPhase = ''dune build -p ocamlgraph -j $NIX_BUILD_CORES'';
            });
            conf-gmp = prev.conf-gmp.overrideAttrs (_: {
              nativeBuildInputs = [ pkgs.pkgsBuildHost.stdenv.cc ];
            });
          };
          scope' = scope.overrideScope overlay;
          main = scope'.${package};
        };
        scopes = mkScopes pkgs false;
        scopesStatic = mkScopes pkgsStatic isGnu64;
        devPackages = builtins.attrValues (pkgs.lib.getAttrs (builtins.attrNames devPackagesQuery) scopes.scope');
      in
      {
        legacyPackages = scope';
        packages.default = main;
        legacyPackages = scopes.scope';
        packages.default = scopesStatic.main;
        devShells.default = pkgs.mkShell {
          TOPIARY_LANGUAGE_DIR = "topiary";
          inputsFrom = [ main ];
          inputsFrom = [ scopes.main ];
          buildInputs = devPackages ++ [
            pkgs.topiary
            pkgs.reuse
diff --git a/static.patch b/static.patch
deleted file mode 100644
index b6208ee..0000000
--- a/static.patch
@@ -1,13 +0,0 @@
diff --git a/bin/forester/dune b/bin/forester/dune
index 8267c08..32fb7fd 100644
--- a/bin/forester/dune
+++ b/bin/forester/dune
@@ -6,7 +6,7 @@
  (public_name forester)
  (name main)
  (flags (-g))
- (link_flags (-g))
+ (link_flags (-g -ccopt -static))
  (preprocess
   (pps ppx_deriving.show))
   (libraries
--
2.47.0
Message-ID: <8734ivgm0s.fsf@owenlynch.org>
Reply to thread Export thread (mbox)