{ nixpkgs ? import ./Bild/Nixpkgs.nix }: rec { constants = import ./Bild/Constants.nix; # internal usage private = { inherit nixpkgs; # provided by .envrc root = builtins.getEnv "BIZ_ROOT"; selectAttrs = deps: packageSet: nixpkgs.lib.attrsets.attrVals deps packageSet; # 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; # 44 = lib.strings.stringLength "/nix/store/gia2r9mxhc900y1m97dlmr1g3rm3ich3-" dropNixStore = s: nixpkgs.lib.strings.substring 44 (nixpkgs.lib.strings.stringLength s) s; haskellDeps = import ./Bild/Deps/Haskell.nix; ghcWith = nixpkgs.haskell.packages.${constants.ghcCompiler}.ghcWithHoogle; sbclWith = nixpkgs.lispPackages_new.sbclWithPackages; ghcPackageSetFull = private.ghcWith private.haskellDeps; ghcPackageSetBild = private.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 neat-interpolation wai # can remove when removed from Biz.Log ]); ghcPackageSetMin = private.ghcWith (hpkgs: with hpkgs; []); }; # generally-useful things from nixpkgs inherit (nixpkgs) lib stdenv sources; # expose some packages for inclusion in os/image builds pkgs = with nixpkgs.pkgs; [ git ]; # remove this when I switch to all-nix builds bildRuntimeDeps = with nixpkgs; [ pkg-config private.ghcPackageSetMin gnutls rustc # c deps gcc gdb valgrind argp-standalone SDL # lisp deps guile (private.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 { name = "bild"; src = ../.; nativeBuildInputs = [ private.ghcPackageSetBild ]; buildInputs = [ nixpkgs.makeWrapper ]; propagatedBuildInputs = bildRuntimeDeps; strictDeps = true; buildPhase = '' mkdir -p $out/bin $out/lib/ghc-${private.ghcPackageSetFull.version} cp -r \ ${private.ghcPackageSetFull}/lib/ghc-${private.ghcPackageSetFull.version}/package.conf.d \ $out/lib/ghc-${private.ghcPackageSetFull.version} ghc \ -Werror \ -i. \ --make Biz/Bild.hs \ -main-is Biz.Bild \ -o $out/bin/bild ''; installPhase = '' wrapProgram $out/bin/bild \ --prefix PATH : ${lib.makeBinPath [ private.ghcPackageSetBild ]} \ --set GHC_PACKAGE_PATH \ $out/lib/ghc-${private.ghcPackageSetFull.version}/package.conf.d ''; }; # wrapper around bild runBildAnalyze = main: stdenv.mkDerivation rec { name = "bild-analysis"; src = ../.; USER = "nixbld"; HOSTNAME = "nix-sandbox"; # this is the default sandbox path where bild will be working: BIZ_ROOT = "/build/biz"; # we need to remove the $src root because bild expects paths relative to the # working directory: MAIN = "." + lib.strings.removePrefix (toString src) (toString main); buildPhase = '' mkdir $out ${bild}/bin/bild --json "$MAIN" 1> $out/analysis.json \ 2> >(tee -a $out/stderr >&2) ''; 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")); # 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; }; env = let linters = with nixpkgs.pkgs; [ ormolu hlint deadnix indent ]; in nixpkgs.pkgs.mkShell { name = "bizdev"; # this should just be dev tools buildInputs = with nixpkgs.pkgs; linters ++ bildRuntimeDeps ++ [ bild ctags figlet git haskell.packages.${constants.ghcCompiler}.fast-tags hlint lolcat #nixops # fails to build ormolu (private.nixpkgs.python3.withPackages(p: with p; [ transformers pytorch private.nixpkgs.python3Packages.bitsandbytes private.nixpkgs.python3Packages.accelerate # lint tools: black pylint ])) shellcheck wemux ]; shellHook = '' export GHC_PACKAGE_PATH=${bild}/lib/ghc-${private.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; }