{ nixpkgs ? import ./Bild/Nixpkgs.nix }: let constants = import ./Bild/Constants.nix; # expose some attrs from stable, keep this minimal and simple stable = { inherit (nixpkgs.nixos-23_05) sources lib makeWrapper ccacheStdenv haskellPackages haskell lispPackages_new python3 nixos mkShell dockerTools; stdenv = nixpkgs.nixos-23_05.ccacheStdenv; }; # for exposing packages as bild.pkgs stable-pkgs = nixpkgs.nixos-23_05.pkgs; # this is the main library definitions, recursive references can be made with # `self.thing`, like in Python objects self = { # 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 = self.lib.attrsets.getAttrs self.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: self.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 = self.lib.attrsets.getAttrs (import ./Bild/Deps/C.nix) stable-pkgs; # exposed packages for inclusion in builds pkgs = with stable-pkgs; { inherit bat bc cmark ctags deadnix fd figlet fzf git git-branchless gitlint guile hlint indent jq lolcat mypy nixfmt ormolu pkg-config ripgrep rustc shellcheck tree wemux; 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 = self.stdenv.mkDerivation { name = "bild"; src = ../.; nativeBuildInputs = [ self.haskell.ghcPackageSetBild ]; buildInputs = [ self.makeWrapper ]; propagatedBuildInputs = with self.pkgs; [ pkg-config git # this is just to get access to ghc-pkg in bild (self.haskell.ghcWith (_: [ ])) # lisp deps, remove this when i implement nix builds for lisp guile (self.lisp.sbclWith (p: with p; [ asdf alexandria ])) # just enough to build Example.lisp ]; strictDeps = true; buildPhase = '' mkdir -p $out/bin $out/lib/ghc-${self.haskell.ghcPackageSetFull.version} cp -r \ ${self.haskell.ghcPackageSetFull}/lib/ghc-${self.haskell.ghcPackageSetFull.version}/package.conf.d \ $out/lib/ghc-${self.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 : ${ self.lib.makeBinPath [ self.haskell.ghcPackageSetBild self.pkgs.git ] } \ --set GHC_PACKAGE_PATH \ $out/lib/ghc-${self.haskell.ghcPackageSetFull.version}/package.conf.d ''; }; # wrapper around bild runBildAnalyze = target: self.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 = "." + self.lib.strings.removePrefix (toString src) (toString target); buildPhase = '' export CODEROOT=$(pwd) mkdir $out ${self.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 (self.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 = self.analyze target; bild = self; }; # the main development environment env = stable.mkShell { name = "bizdev"; # this should just be dev tools buildInputs = with self.pkgs; [ bat bc self.bild ctags fd figlet fzf git git-branchless gitlint jq lolcat ormolu ripgrep stable.haskell.packages.${constants.ghcCompiler}.fast-tags tree wemux ]; shellHook = '' export GHC_PACKAGE_PATH=${self.bild}/lib/ghc-${self.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.dockerTools.buildImage; }; in self