Errors attempting to build a docker image from a flake

I have been trying to configure a flake to build the Google HEIR project with certain dependencies like my local nvim nvf configuration and some preconfigured LSP setup. I’m new to this and have mainly been using Sonnet 4.5 to slowly build the flake. I understand at a high level what is being done but I am not yet fully comfortable with the syntax and inner workings.

I tried to make it work with bazelBuildPackage and mkDerivation but wasn’t able to get it to builld completely. I am posting here requesting some guidance about the best way to get this flake to output a docker image I can use.

I am also wondering if my flake could be improved and if there are standard practices I could be using to do things the Nix way.

Now for the error I’m facing. nix build .#docker returns:

# Execution platform: @@platforms//host:host
In file included from external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_neon.c:1:
external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h:5:10: error: module +_repo_rules+llvm-project//llvm:Suppo>
    5 | #include <stdbool.h>
      |          ^
external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h:6:10: error: module +_repo_rules+llvm-project//llvm:Suppo>
    6 | #include <stddef.h>
      |          ^
external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h:7:10: error: module +_repo_rules+llvm-project//llvm:Suppo>
    7 | #include <stdint.h>
      |          ^
In file included from external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_neon.c:1:
In file included from external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h:10:
external/+_repo_rules+llvm-project/llvm/include/llvm-c/blake3.h:21:10: error: module +_repo_rules+llvm-project//llvm:Support does >
   21 | #include <stddef.h>
      |          ^
external/+_repo_rules+llvm-project/llvm/include/llvm-c/blake3.h:22:10: error: module +_repo_rules+llvm-project//llvm:Support does >
   22 | #include <stdint.h>
      |          ^
In file included from external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_neon.c:1:
In file included from external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h:12:
external/+_repo_rules+llvm-project/llvm/include/llvm/Support/Compiler.h:20:10: error: module +_repo_rules+llvm-project//llvm:Suppo>
   20 | #include <stddef.h>
      |          ^
external/+_repo_rules+llvm-project/llvm/lib/Support/BLAKE3/blake3_neon.c:5:10: error: module +_repo_rules+llvm-project//llvm:Suppo>
    5 | #include <arm_neon.h>
      |          ^
7 errors generated.
Analyzing: 3 targets (395 packages loaded, 29912 targets configured)
[549 / 2,631] 12 actions running
    Compiling llvm/lib/Remarks/YAMLRemarkParser.cpp [for tool]; 1s local
    Compiling llvm/lib/Demangle/RustDemangle.cpp [for tool]; 1s local
    Compiling llvm/lib/Demangle/MicrosoftDemangle.cpp [for tool]; 1s local
    Compiling llvm/lib/Demangle/ItaniumDemangle.cpp [for tool]; 1s local
    Compiling lib/compress/zstd_lazy.c; 0s local
    Compiling llvm/lib/Support/DeltaAlgorithm.cpp [for tool]; 0s local
    Compiling llvm/lib/Support/BLAKE3/blake3_neon.c [for tool]; 0s local
    Compiling llvm/lib/Demangle/DLangDemangle.cpp; 0s local ...
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting
    Fetching https://github.com/.../archive/refs/tags/boost-1.87.0.tar.gz
^M^M^M^M^M^M^M^M^M^M^M^M^M^M^MWARNING: Download from https://github.com/boostorg/spirit/archive/refs/tags/boost-1.87.0.tar.gz fail>
Analyzing: 3 targets (395 packages loaded, 29912 targets configured)
[561 / 2,631] checking cached actions
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting
^M^M^M^M^M^MINFO: Elapsed time: 84.917s, Critical Path: 2.03s
Analyzing: 3 targets (395 packages loaded, 29912 targets configured)
[561 / 2,631] checking cached actions
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting
^M^M^M^M^M^MINFO: 561 processes: 485 internal, 76 local.
Analyzing: 3 targets (395 packages loaded, 29912 targets configured)
[561 / 2,631] checking cached actions
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting
^M^M^M^M^M^MERROR: Build did NOT complete successfully
FAILED:
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting
^M^M^M^M^MFAILED:
    Fetching repository @@boost.spirit+; starting
    Fetching repository @@boost.smart_ptr+; starting
    Fetching repository @@boost.container_hash+; starting
    Fetching repository @@boost.preprocessor+; starting

flake.nix

{
  description = "HEIR FHE Compiler Development Environment";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    nvf = {
      url = "github:notashelf/nvf";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    heir-src = {
      url = "github:google/heir";
      flake = false;
    };
  };

  outputs =
    {
      self,
      nixpkgs,
      flake-utils,
      nvf,
      heir-src,
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        pkgs = import nixpkgs {
          inherit system;
          config.allowUnfree = true;
        };

        # Build HEIR with network access (fixed-output derivation)
        heir-compiler = pkgs.stdenv.mkDerivation {
          pname = "heir";
          version = "git-${builtins.substring 0 7 (heir-src.rev or "dirty")}";
          src = heir-src;

          nativeBuildInputs =
            with pkgs;
            [
              bazel_8
              python3
              git
              which
              cacert
            ]
            ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
              pkgs.darwin.cctools
            ];

          buildInputs = with pkgs; [
            llvmPackages.llvm
            llvmPackages.clang
          ];

          # Patch .bazelversion to match available Bazel
          patchPhase = ''
            echo "${pkgs.bazel_8.version}" > .bazelversion
          '';

          buildPhase = ''
            export HOME=$TMPDIR
            export USER=nixbld
            export SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
            export GIT_SSL_CAINFO=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt

            # Set CC and LIBTOOL for Bazel's C++ toolchain
            export CC=${pkgs.llvmPackages.clang}/bin/clang
            export CXX=${pkgs.llvmPackages.clang}/bin/clang++
            ${pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
              export LIBTOOL=${pkgs.darwin.cctools}/bin/libtool
            ''}

            # Build with Bazel - disable C++ modules correctly using -Xclang
            bazel \
              --output_user_root=$HOME/.bazel \
              build \
              --verbose_failures \
              --spawn_strategy=standalone \
              --loading_phase_threads=4 \
              --http_timeout_scaling=3.0 \
              --cxxopt=-Xclang \
              --cxxopt=-fno-cxx-modules \
              --host_cxxopt=-Xclang \
              --host_cxxopt=-fno-cxx-modules \
              --repository_cache=$HOME/.bazel-cache \
              //tools:heir-opt \
              //tools:heir-translate \
              //tools:heir-lsp
          '';

          installPhase = ''
            mkdir -p $out/bin
            install -Dm755 bazel-bin/tools/heir-opt $out/bin/
            install -Dm755 bazel-bin/tools/heir-translate $out/bin/
            install -Dm755 bazel-bin/tools/heir-lsp $out/bin/
          '';

          # Make this a fixed-output derivation
          outputHashMode = "recursive";
          outputHashAlgo = "sha256";
          outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Replace after first build
        };

        mlir-lsp = pkgs.llvmPackages.llvm;

        nvim-configured = nvf.lib.neovimConfiguration {
          inherit pkgs;
          modules = [
            ../../modules/shared/nvim.nix
            {
              config.vim = {
                extraPackages = [
                  heir-compiler
                  mlir-lsp
                ];

                luaConfigRC.mlir-heir-setup = pkgs.lib.mkAfter ''
                  vim.filetype.add({ extension = { mlir = 'mlir' } })

                  local lspconfig = require('lspconfig')

                  lspconfig.mlir_lsp_server.setup{
                    cmd = { '${mlir-lsp}/bin/mlir-lsp-server' },
                    filetypes = { 'mlir' },
                    root_dir = function() return vim.fn.getcwd() end,
                  }

                  if not lspconfig.heir_lsp then
                    lspconfig.configs.heir_lsp = {
                      default_config = {
                        cmd = { '${heir-compiler}/bin/heir-lsp' },
                        filetypes = { 'mlir' },
                        root_dir = function() return vim.fn.getcwd() end,
                      },
                    }
                  end
                  lspconfig.heir_lsp.setup{}

                  vim.api.nvim_create_autocmd('FileType', {
                    pattern = 'mlir',
                    callback = function()
                      vim.bo.commentstring = '// %s'
                      vim.bo.shiftwidth = 2
                      vim.bo.tabstop = 2
                    end,
                  })
                '';
              };
            }
          ];
        };

        entrypoint = pkgs.writeShellScriptBin "entrypoint" ''
          cd /workspace
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "  HEIR Development Environment"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo ""
          echo "Tools: nvim, heir-opt, heir-translate"
          echo "LSP: mlir-lsp-server, heir-lsp-server"
          echo ""
          exec ${pkgs.bash}/bin/bash
        '';

      in
      {
        packages = {
          default = heir-compiler;

          docker = pkgs.dockerTools.buildLayeredImage {
            name = "heir-dev";
            tag = "latest";

            contents = pkgs.buildEnv {
              name = "heir-env";
              paths = [
                pkgs.bashInteractive
                pkgs.coreutils
                pkgs.findutils
                pkgs.git
                heir-compiler
                mlir-lsp
                nvim-configured.neovim
                pkgs.ripgrep
                pkgs.fd
                entrypoint
              ];
              pathsToLink = [
                "/bin"
                "/share"
              ];
            };

            config = {
              Cmd = [ "${entrypoint}/bin/entrypoint" ];
              WorkingDir = "/workspace";
              Env = [ "PATH=/bin" ];
              Volumes = {
                "/workspace" = { };
              };
            };
          };
        };

        devShells.default = pkgs.mkShell {
          buildInputs = [
            heir-compiler
            mlir-lsp
            nvim-configured.neovim
          ];
        };
      }
    );
}