From e5a6175e044d69b8f598a2c2acb9bcfd77b9001c Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Mon, 21 Aug 2023 20:36:12 -0400 Subject: Refactor the build system for readability Lots of changes here but the code is much improved. The nix code is clearer and structured better. The Haskell code improved in response to the nix changes. I needed to use a qualified path instead of the abspath because the BIZ_ROOT changes based on whether bild runs in nix or runs in the user environment. Rather than passing every argument into Builder.nix, now I just pass the json from bild and deconstruct it in nix. This is obviously a much better design and it only came to be after sleeping on it the other night. --- Biz/Bild.nix | 156 +++++++++++++++++++++-------------------------------------- 1 file changed, 56 insertions(+), 100 deletions(-) (limited to 'Biz/Bild.nix') diff --git a/Biz/Bild.nix b/Biz/Bild.nix index ee0b1fe..1955d2c 100644 --- a/Biz/Bild.nix +++ b/Biz/Bild.nix @@ -1,79 +1,79 @@ { nixpkgs ? import ./Bild/Nixpkgs.nix }: -rec { +let constants = import ./Bild/Constants.nix; + lib = nixpkgs.lib; +# put all of our stuff in the 'bild' namespace +in nixpkgs // { bild = rec { + # provided by .envrc + root = builtins.getEnv "BIZ_ROOT"; - # internal usage - private = { - inherit nixpkgs; + inherit (nixpkgs) sources; - # provided by .envrc - root = builtins.getEnv "BIZ_ROOT"; + haskell = rec { + inherit (constants) ghcCompiler; - selectAttrs = deps: packageSet: - nixpkgs.lib.attrsets.attrVals deps packageSet; + # all available packages + deps = import ./Bild/Deps/Haskell.nix; + packages = lib.attrsets.getAttrs deps nixpkgs.haskellPackages; - # returns true if a is a subset of b, where a and b are attrsets - subset = a: b: builtins.all - (x: builtins.elem x b) a; + # make a ghc with dependencies + ghcWith = nixpkgs.haskell.packages.${ghcCompiler}.ghcWithHoogle; - # 44 = lib.strings.stringLength "/nix/store/gia2r9mxhc900y1m97dlmr1g3rm3ich3-" - dropNixStore = s: nixpkgs.lib.strings.substring 44 (nixpkgs.lib.strings.stringLength s) s; + # ghc with all packages, used for generating bild's package database + ghcPackageSetFull = ghcWith (p: lib.attrsets.attrVals deps p); - haskellDeps = import ./Bild/Deps/Haskell.nix; - - ghcPackages = nixpkgs.haskellPackages; - ghcWith = nixpkgs.haskell.packages.${constants.ghcCompiler}.ghcWithHoogle; - - sbclWith = nixpkgs.lispPackages_new.sbclWithPackages; - - pythonPackages = nixpkgs.python3Packages; - pythonWith = nixpkgs.python3.withPackages; - - cPackages = nixpkgs.pkgs; - - ghcPackageSetFull = private.ghcWith private.haskellDeps; - ghcPackageSetBild = private.ghcWith (hpkgs: with hpkgs; [ + # 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 = nixpkgs.lispPackages_new.sbclWithPackages; }; - # generally-useful things from nixpkgs - inherit (nixpkgs) lib stdenv sources; + python = { + packages = nixpkgs.python3Packages; + pythonWith = nixpkgs.python3.withPackages; + buildPythonApplication = nixpkgs.python3.pkgs.buildPythonApplication; + }; + + # c packages are just nixpkgs, filtered to just the list of deps i want + c.packages = lib.attrsets.getAttrs (import ./Bild/Deps/C.nix) nixpkgs.pkgs; # expose some packages for inclusion in os/image builds pkgs = with nixpkgs.pkgs; { inherit git; }; - # remove this when I switch to all-nix builds + # this is needed to do builds without calling out to nix, remove this when I + # switch to all-nix builds bildRuntimeDeps = with nixpkgs; [ pkg-config # this is just to get access to ghc-pkg in bild - (private.ghcWith (hpkgs: with hpkgs; [])) + (haskell.ghcWith (hpkgs: with hpkgs; [])) - /* disable until nixified builds are complete */ # lisp deps guile - (private.sbclWith (p: with p; [asdf alexandria])) # just enough to build Example.lisp + (lisp.sbclWith (p: with p; [asdf alexandria])) # just enough to build Example.lisp ]; # a standard nix build for `bild` - this should be the only hand-written # builder we need - bild = stdenv.mkDerivation { + bild = nixpkgs.stdenv.mkDerivation { name = "bild"; src = ../.; - nativeBuildInputs = [ private.ghcPackageSetBild ]; + nativeBuildInputs = [ haskell.ghcPackageSetBild ]; buildInputs = [ nixpkgs.makeWrapper ]; propagatedBuildInputs = bildRuntimeDeps; strictDeps = true; buildPhase = '' - mkdir -p $out/bin $out/lib/ghc-${private.ghcPackageSetFull.version} + mkdir -p $out/bin $out/lib/ghc-${haskell.ghcPackageSetFull.version} cp -r \ - ${private.ghcPackageSetFull}/lib/ghc-${private.ghcPackageSetFull.version}/package.conf.d \ - $out/lib/ghc-${private.ghcPackageSetFull.version} + ${haskell.ghcPackageSetFull}/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d \ + $out/lib/ghc-${haskell.ghcPackageSetFull.version} ghc \ -threaded \ -Werror \ @@ -84,14 +84,14 @@ rec { ''; installPhase = '' wrapProgram $out/bin/bild \ - --prefix PATH : ${lib.makeBinPath [ private.ghcPackageSetBild ]} \ + --prefix PATH : ${lib.makeBinPath [ haskell.ghcPackageSetBild ]} \ --set GHC_PACKAGE_PATH \ - $out/lib/ghc-${private.ghcPackageSetFull.version}/package.conf.d + $out/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d ''; }; # wrapper around bild - runBildAnalyze = main: stdenv.mkDerivation rec { + runBildAnalyze = main: nixpkgs.stdenv.mkDerivation rec { name = "bild-analysis"; src = ../.; USER = "nixbld"; @@ -109,43 +109,19 @@ rec { installPhase = "exit 0"; }; - # gather data needed for compiling by analyzing the main module - analyze = main: - let - path = lib.strings.removePrefix (builtins.getEnv "BIZ_ROOT" + "/") (toString main); - in - lib.attrsets.getAttrFromPath [path] - (lib.trivial.importJSON - (runBildAnalyze main + "/analysis.json")); - - buildPythonApplication = nixpkgs.python310.pkgs.buildPythonApplication; - - # build a ghc executable - ghc = main: - let - data = analyze main; - ghc = private.ghcWith (hp: private.selectAttrs data.langdeps hp); - module = lib.strings.concatStringsSep "." data.namespace.path; - in stdenv.mkDerivation { - name = module; - src = ../.; - nativeBuildInputs = [ ghc ] ++ private.selectAttrs data.sysdeps nixpkgs.pkgs; - strictDeps = true; - buildPhase = '' - set -eux - mkdir -p $out/bin - : compiling with ghc - ${ghc}/bin/ghc \ - -Werror \ - -i. \ - --make ${main} \ - -main-is ${module} \ - -o $out/bin/${data.out} - ''; - # the install process was handled above - installPhase = "exit 0"; - } // { env = ghc; }; + # gather data needed for compiling by analyzing the main module. returns the + # json object of the build + analyze = main: builtins.readFile (runBildAnalyze main + "/analysis.json"); + + # i think this isn't going to work because we have a nix-in-nix problem. + # instead: + # - get the store path some other way. if i can pass that to bild.os, then nix + # should automatically get all the deps required + # - just do runBildAnalyze, pass the args to Bild/Builder.nix, should continue + # no problem + run = main: import ./Bild/Builder.nix { analysisJSON = analyze main; }; + # the main development environment env = let linters = with nixpkgs.pkgs; [ ormolu hlint deadnix indent black]; in nixpkgs.pkgs.mkShell { @@ -156,7 +132,7 @@ rec { ctags figlet git - haskell.packages.${constants.ghcCompiler}.fast-tags + nixpkgs.haskell.packages.${constants.ghcCompiler}.fast-tags hlint lolcat #nixops # fails to build @@ -165,34 +141,14 @@ rec { wemux ]; shellHook = '' - export GHC_PACKAGE_PATH=${bild}/lib/ghc-${private.ghcPackageSetFull.version}/package.conf.d + export GHC_PACKAGE_PATH=${bild}/lib/ghc-${haskell.ghcPackageSetFull.version}/package.conf.d ''; }; # build an operating system. 'cfg' is the NixOS config os = cfg: (nixpkgs.nixos (_args: cfg)).toplevel; - # build a rust executable - rust = main: - let - data = analyze main; - rustc = nixpkgs.pkgs.rustc; - in stdenv.mkDerivation { - name = lib.string.concatStringsSep "::" data.namespace.path; - src = ../.; - nativeBuildInputs = [ rustc ]; - strictDeps = true; - buildPhase = '' - set -eux - mkdir -p $out/bin - : compiling with rustc - ${rustc}/bin/rustc \ - ${main} \ - -o $out/bin/${data.out} - ''; - installPhase = "exit 0"; - }; - # build a docker image image = nixpkgs.pkgs.dockerTools.buildImage; +}; } -- cgit v1.2.3