diff options
author | Ben Sima <ben@bsima.me> | 2024-11-15 14:55:37 -0500 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2024-12-21 10:06:49 -0500 |
commit | 6513755670892983db88a6633b8c1ea6019c03d1 (patch) | |
tree | 44e9eccdb7a3a74ab7e96a8fee7572dd6a78dc73 /Omni/Bild.nix | |
parent | ae7b7e0186b5f2e0dcd4d5fac0a71fa264caedc2 (diff) |
Re-namespace some stuff to Omni
I was getting confused about what is a product and what is internal
infrastructure; I think it is good to keep those things separate. So I moved a
bunch of stuff to an Omni namespace, actually most stuff went there. Only things
that are explicitly external products are still in the Biz namespace.
Diffstat (limited to 'Omni/Bild.nix')
-rw-r--r-- | Omni/Bild.nix | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/Omni/Bild.nix b/Omni/Bild.nix new file mode 100644 index 0000000..1a31e1e --- /dev/null +++ b/Omni/Bild.nix @@ -0,0 +1,241 @@ +{ nixpkgs ? import ./Bild/Nixpkgs.nix }: + +let + constants = import ./Bild/Constants.nix; + + # expose some attrs from stable, keep this minimal and simple + stable = let stable = nixpkgs.nixos-24_05; + in { + inherit (stable) + sources lib makeWrapper ccacheStdenv haskell sbcl python3 nixos mkShell + dockerTools pkgs; + stdenv = stable.ccacheStdenv; + }; + + unstable = nixpkgs.nixos-unstable-small; + + # get the .src attributes of all drvs in each pkgset in the `sources` list, + # and concat them with `:` into a Unix-style search path. + # makeSourcesPath :: [pkgset] -> str + makeSourcesPath = with stable; + sources: + lib.trivial.pipe sources [ + (builtins.map lib.attrsets.attrValues) + lib.lists.flatten + (builtins.filter (pkg: pkg != null)) + (builtins.map (pkg: if pkg ? src then pkg.src else pkg)) + (lib.strings.concatStringsSep ":") + ]; + + # 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; + + ghcVersion = ghcPackageSetFull.version; + + # all available packages + deps = import ./Bild/Deps/Haskell.nix; + packages = self.lib.attrsets.getAttrs self.haskell.deps + stable.haskell.packages."${constants.ghcCompiler}"; + + # 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 Omni.Log + ]); + }; + + lisp = { sbclWith = stable.sbcl.withPackages; }; + + python = { + packages = self.lib.attrsets.getAttrs (import ./Bild/Deps/Python.nix) + 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 universal-ctags deadnix fd figlet fzf git + git-branchless gitlint groff guile hlint indent jq lolcat mypy nixfmt + ormolu pkg-config ripgrep rustc tree wemux; + llama-cpp = unstable.llama-cpp; + llm = python3.withPackages (p: with p; [ p.llm-ollama ]); + ollama = unstable.ollama; + ruff = unstable.ruff; + shellcheck = unstable.shellcheck; + }; + + # a standard nix build for bild, for bootstrapping. this should be the only + # hand-written builder we need + bild = self.stdenv.mkDerivation { + name = "bild"; + srcs = self.lib.fileset.toSource { + root = ../.; + fileset = self.lib.fileset.unions [ + ../Alpha.hs + ../Omni/Bild.hs + ../Omni/Bild/Meta.hs + ../Omni/Cli.hs + ../Omni/Log.hs + ../Omni/Namespace.hs + ../Omni/Test.hs + ]; + }; + 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; [ alexandria ])) # just enough to build Example.lisp + ]; + strictDeps = true; + ghcVersion = self.haskell.ghcVersion; + buildPhase = '' + mkdir -p $out/bin $out/lib/ghc-$ghcVersion + cp -r \ + ${self.haskell.ghcPackageSetFull}/lib/ghc-$ghcVersion/package.conf.d \ + $out/lib/ghc-$ghcVersion + ghc \ + -threaded \ + -Werror \ + -Wall \ + -Winvalid-haddock \ + -haddock \ + -i. \ + --make Omni/Bild.hs \ + -main-is Omni.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-$ghcVersion/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 = "omnidev"; + # this should just be dev tools + buildInputs = with self.pkgs; [ + bat + bc + self.bild + universal-ctags + fd + figlet + fzf + git + git-branchless + gitlint + jq + lolcat + llm + ormolu + ripgrep + tree + wemux + ]; + shellHook = '' + export GHC_PACKAGE_PATH=${self.bild}/lib/ghc-${self.haskell.ghcVersion}/package.conf.d + export ALL_SOURCES=${ + makeSourcesPath [ + self.python.packages + self.haskell.packages + self.c.packages + self.sources + ] + } + ''; + }; + + # 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 |