diff options
-rw-r--r-- | Biz/Bild.hs | 150 | ||||
-rw-r--r-- | Biz/Bild.nix | 7 | ||||
-rw-r--r-- | Biz/Bild/Meta.hs | 8 |
3 files changed, 124 insertions, 41 deletions
diff --git a/Biz/Bild.hs b/Biz/Bild.hs index 0747cf5..96203a4 100644 --- a/Biz/Bild.hs +++ b/Biz/Bild.hs @@ -155,8 +155,8 @@ main = Cli.main <| Cli.Plan help move test_ pure [Exit.ExitFailure _] -> Test.assertFailure "can't bild bild" _ -> - pure (), - test_toNixExpr + pure () + -- test_toNixExpr ] move :: Cli.Arguments -> IO () @@ -270,16 +270,50 @@ toNixExpr :: String -> Target -> Text toNixExpr root (Target {..}) = [NeatInterpolation.trimming| with import $troot/Biz/Bild.nix {}; -runCommand "foo" { +with builtins; +let + skip = ["_" ".direnv"]; + filter = name: type: + if elem (baseNameOf name) skip then false + # TODO: this means any new directory will cause a rebuild. this bad. + # i should recurse into the directory and match against the srcFiles + else if type == "directory" then true + else if type == "regular" then builtins.elem name [$srcFiles] + else false; +in stdenv.mkDerivation { + name = "$outname_"; + src = lib.sources.cleanSourceWith {inherit filter; src = lib.sources.cleanSource ./.;}; buildInputs = [ (private.ghcWith (p: with p; [$nixLangdeps])) ]; -} "$compilerCommand $compilerArgs" -|] + buildPhase = "$compilerCommand $compilerArgs"; + installPhase = "mkdir -p $$out/bin && cp $outname_ $$out/bin"; +}|] where - troot, compilerCommand, compilerArgs, nixLangdeps :: Text + troot, compilerCommand, compilerArgs, nixLangdeps, outname_, srcFiles :: Text troot = Text.pack root compilerCommand = compilerExe compiler compilerArgs = str <| unwords compilerFlags nixLangdeps = str <| String.unwords <| Set.toList langdeps + outname_ = str <| outname out + srcFiles = + ((root </> path) : Set.toList srcs) + |> map (\p -> "\"" <> p <> "\"\n") + |> String.unwords + |> str + +-- | Use this to just get a target to play with at the repl. +dev_getTarget :: IO Target +dev_getTarget = do + root <- Env.getEnv "BIZ_ROOT" + path <- Dir.makeAbsolute "Biz/Bild.hs" + Namespace.fromPath root path + |> \case + Nothing -> panic "Could not get namespace from path" + Just ns -> + analyze mempty ns + /> Map.lookup ns + /> \case + Nothing -> panic "Could not retrieve target from analysis" + Just t -> t test_toNixExpr :: Test.Tree test_toNixExpr = @@ -287,23 +321,8 @@ test_toNixExpr = "toNixExpr" [ Test.unit "produces corect result" <| do root <- Env.getEnv "BIZ_ROOT" - path <- Dir.makeAbsolute "Biz/Bild/Example.hs" - Namespace.fromPath root path - |> \case - Nothing -> panic "Could not get namespace from path" - Just ns -> - analyze mempty ns - /> Map.lookup ns - +> \case - Nothing -> panic "Could not retrieve target from analysis" - Just t -> toNixExpr root t @?= actual - where - troot = Text.pack root - actual = - [NeatInterpolation.trimming|with import $troot/Biz/Bild.nix {}; - runCommand "foo" { - buildInputs = [ (private.ghcWith (p: with p; [])) ]; - } "ghc -Werror -i$troot -odir $troot/_/int -hidir $troot/_/int --make $troot/Biz/Bild/Example.hs -main-is Biz.Bild.Example -o /home/ben/biz/_/bin/example"|] + t <- dev_getTarget + toNixExpr root t @?= [NeatInterpolation.trimming|TODO|] ] data Builder @@ -366,7 +385,14 @@ outToPath = \case Meta.Lib o -> cab </> "lib" </> o Meta.None -> mempty -intdir, nixdir, vardir :: FilePath +outname :: Meta.Out -> FilePath +outname = \case + Meta.Bin o -> o + Meta.Lib o -> o + Meta.None -> mempty + +bindir, intdir, nixdir, vardir :: FilePath +bindir = cab </> "bin" intdir = cab </> "int" nixdir = cab </> "nix" vardir = cab </> "var" @@ -471,22 +497,22 @@ analyze hmap ns = case Map.lookup ns hmap of compiler = Ghc, compilerFlags = [ "-Werror", - "-i" <> root, + "-i$src", "-odir", - root </> intdir, + ".", "-hidir", - root </> intdir, + ".", "--make", - absPath + "$src" </> path ] - ++ (out /= Meta.None) - ?: ( [ "-main-is", - Namespace.toHaskellModule namespace, - "-o", - root </> outToPath out - ], - [] - ) + ++ case out of + Meta.Bin o -> + [ "-main-is", + Namespace.toHaskellModule namespace, + "-o", + o + ] + _ -> [] |> map Text.pack, sysdeps = Meta.detect (Meta.sys "--") contentLines, outPath = outToPath out, @@ -690,8 +716,8 @@ build andTest loud analysis = Ghc -> case out of Meta.None -> pure (Exit.ExitSuccess, mempty) Meta.Bin _ -> do - Log.info ["bild", "dev", "ghc-exe", nschunk namespace] - result <- proc loud namespace (toNixFlag compiler) compilerFlags + Log.info ["bild", "nixBuild", "ghc", nschunk namespace] + result <- nixBuild loud target if andTest && (isSuccess <| fst result) then test loud target else pure result @@ -820,3 +846,51 @@ lispRequires = where isQuote :: Char -> Bool isQuote c = c `elem` ['\'', ':'] + +nixBuild :: Bool -> Target -> IO (Exit.ExitCode, ByteString) +nixBuild loud target@(Target {..}) = + Env.getEnv "BIZ_ROOT" +> \root -> + instantiate root |> run +> \case + (Exit.ExitSuccess, drv) -> + drv + |> str + |> chomp + |> str + |> realise + |> run + >> run symlink + x -> pure x + where + instantiate root = + Proc + { loud = loud, + ns = namespace, + cmd = "nix-instantiate", + args = map Text.unpack ["--expr", toNixExpr root target], + onFailure = Log.fail ["bild", "instantiate", nschunk namespace] >> Log.br, + onSuccess = pure () + } + realise drv = + Proc + { loud = loud, + ns = namespace, + cmd = "nix-store", + args = ["--realise", drv, "--add-root", nixdir </> outname out], + onFailure = Log.fail ["bild", "realise", nschunk namespace] >> Log.br, + onSuccess = Log.good ["bild", nschunk namespace] >> Log.br + } + symlink = + Proc + { loud = loud, + ns = namespace, + cmd = "ln", + args = + [ "--relative", + "--force", + "--symbolic", + nixdir </> outname out </> "bin" </> outname out, + bindir </> outname out + ], + onFailure = Log.fail ["bild", "symlink", nschunk namespace] >> Log.br, + onSuccess = pure () + } diff --git a/Biz/Bild.nix b/Biz/Bild.nix index 2a049b0..34d8174 100644 --- a/Biz/Bild.nix +++ b/Biz/Bild.nix @@ -30,13 +30,14 @@ rec { 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 + 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 runCommand; + inherit (nixpkgs) lib stdenv sources; # expose some packages for inclusion in os/image builds pkgs = with nixpkgs.pkgs; [ git ]; @@ -44,8 +45,8 @@ rec { # remove this when I switch to all-nix builds bildRuntimeDeps = with nixpkgs; [ pkg-config + private.ghcPackageSetMin gnutls - private.ghcPackageSetBild rustc # c deps gcc gdb valgrind argp-standalone SDL diff --git a/Biz/Bild/Meta.hs b/Biz/Bild/Meta.hs index 75242a5..5549cb3 100644 --- a/Biz/Bild/Meta.hs +++ b/Biz/Bild/Meta.hs @@ -12,10 +12,18 @@ import qualified Data.Set as Set import qualified Data.Text as Text import qualified Text.Regex.Applicative as Regex +-- | A third-party dependency. This gets mapped to some name in nixpkgs, +-- prefixed by package set like @haskellPackages@ or +-- @python3Packages@. Currently this prefix is implicit, but it should be added +-- here as part of a tuple or something. type Dep = String +-- | This is a system-level requirement, the string gets mapped to a name in +-- nixpkgs at the top level, like @pkgs.thing@. If I add the package set prefix to 'Dep', then this can just become literally @(Sys, "thing")@. type Sys = String +-- | An arbitrary compiler argument that may get added to the compilation +-- command. Should be used sparingly, and not all builds will support this. type Arg = String data Out = Lib String | Bin String | None |