{ nixpkgs ? import ./Bild/Nixpkgs.nix }: let constants = import ./Bild/Constants.nix; stable = nixpkgs.nixos-23_05; in rec { # provided by .envrc root = builtins.getEnv "CODEROOT"; inherit (stable) sources lib makeWrapper stdenv; haskell = rec { inherit (constants) ghcCompiler; # all available packages deps = import ./Bild/Deps/Haskell.nix; packages = lib.attrsets.getAttrs deps stable.haskellPackages; # make a ghc with dependencies ghcWith = stable.haskell.packages.${ghcCompiler}.ghcWithHoogle; # ghc with all packages, used for generating bild's package database ghcPackageSetFull = ghcWith (p: lib.attrsets.attrVals deps p); # bild's dependencies, needs to be hand-written ghcPackageSetBild = ghcWith (hpkgs: with hpkgs; [ aeson async base bytestring conduit conduit-extra containers directory docopt filepath process protolude rainbow regex-applicative split tasty tasty-hunit tasty-quickcheck text hostname wai # can remove when removed from Biz.Log ]); }; lisp = { sbclWith = stable.lispPackages_new.sbclWithPackages; }; python = { packages = stable.python3.pkgs; pythonWith = stable.python3.withPackages; buildPythonApplication = stable.python3.pkgs.buildPythonApplication; }; # c packages are just stable, filtered to just the list of deps i want c.packages = lib.attrsets.getAttrs (import ./Bild/Deps/C.nix) stable.pkgs; # exposed packages for inclusion in builds pkgs = with stable.pkgs; { inherit deadnix git hlint indent ormolu shellcheck nixfmt mypy pkg-config rustc cmark; ruff = nixpkgs.nixos-unstable-small.ruff; }; # a standard nix build for bild, for bootstrapping. this should be the only # hand-written builder we need bild = stable.stdenv.mkDerivation { name = "bild"; src = ../.; nativeBuildInputs = [ haskell.ghcPackageSetBild ]; buildInputs = [ stable.makeWrapper ]; propagatedBuildInputs = with stable; [ pkg-config git # this is just to get access to ghc-pkg in bild (haskell.ghcWith (_: [ ])) # lisp deps, remove this when i implement nix builds for lisp guile (lisp.sbclWith (p: with p; [ asdf alexandria ])) # just enough to build Example.lisp ]; strictDeps = true; buildPhase = '' mkdir -p $out/bin $out/lib/ghc-${haskell.ghcPackageSetFull.version} cp -r \ ${haskell.ghcPackageSetFull}/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d \ $out/lib/ghc-${haskell.ghcPackageSetFull.version} ghc \ -threaded \ -Werror \ -i. \ --make Biz/Bild.hs \ -main-is Biz.Bild \ -o $out/bin/bild ''; installPhase = '' wrapProgram $out/bin/bild \ --prefix PATH : ${ lib.makeBinPath [ haskell.ghcPackageSetBild stable.pkgs.git ] } \ --set GHC_PACKAGE_PATH \ $out/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d ''; }; # wrapper around bild runBildAnalyze = target: stable.stdenv.mkDerivation rec { name = "bild-analysis"; src = ../.; USER = "nixbld"; HOSTNAME = "nix-sandbox"; # we need to remove the $src root because bild expects paths relative to the # working directory: TARGET = "." + lib.strings.removePrefix (toString src) (toString target); buildPhase = '' export CODEROOT=$(pwd) mkdir $out ${bild}/bin/bild --plan "$TARGET" 1> $out/analysis.json \ 2> >(tee -a $out/stderr >&2) ''; installPhase = "exit 0"; }; # gather data needed for compiling by analyzing the main module. returns the # json object of the build analyze = target: builtins.readFile (runBildAnalyze target + "/analysis.json"); # this does a bild build for the given target, but entirely in nix. its kinda # like IFD, but not as costly, i think run = target: import ./Bild/Builder.nix { analysisJSON = analyze target; }; # the main development environment env = stable.pkgs.mkShell { name = "bizdev"; # this should just be dev tools buildInputs = with stable.pkgs; [ bat bc bild ctags fd figlet fzf git git-branchless gitlint jq lolcat stable.haskell.packages.${constants.ghcCompiler}.fast-tags ormolu ripgrep tree wemux ]; shellHook = '' export GHC_PACKAGE_PATH=${bild}/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d ''; }; # build an operating system. 'cfg' is the NixOS config os = cfg: (stable.nixos (_args: cfg)).toplevel; # build a docker image image = stable.pkgs.dockerTools.buildImage; }