summaryrefslogtreecommitdiff
path: root/Omni/Bild.nix
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2024-11-15 14:55:37 -0500
committerBen Sima <ben@bsima.me>2024-12-21 10:06:49 -0500
commit6513755670892983db88a6633b8c1ea6019c03d1 (patch)
tree44e9eccdb7a3a74ab7e96a8fee7572dd6a78dc73 /Omni/Bild.nix
parentae7b7e0186b5f2e0dcd4d5fac0a71fa264caedc2 (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.nix241
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