summaryrefslogtreecommitdiff
path: root/Biz
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2022-07-29 10:50:41 -0400
committerBen Sima <ben@bsima.me>2022-07-29 10:50:41 -0400
commitd8fe6f7ac54f155fe5a3c33509249a70d0c816c5 (patch)
treeaccdaf7961809b231aab726314dccf0e431463b3 /Biz
parent347c5d878d064685f4c27f36f38ef20f67996417 (diff)
Implement Guile linking for C builds
In order to write Guile code against C, I need to distiguish between libs and bins, so I did that, then I got the flags that gcc needs from `guile-config` and put them in the args for any C lib build. I tested this with Bessel.c and Bessel.scm (not in this patch, because I don't really want that code in my tree, I'll come up with another way to test it later).
Diffstat (limited to 'Biz')
-rw-r--r--Biz/Bild.hs83
-rw-r--r--Biz/Bild.nix5
-rwxr-xr-xBiz/Ide/repl1
3 files changed, 68 insertions, 21 deletions
diff --git a/Biz/Bild.hs b/Biz/Bild.hs
index 602a326..c5777f9 100644
--- a/Biz/Bild.hs
+++ b/Biz/Bild.hs
@@ -198,7 +198,11 @@ exitSummary exits =
type Dep = String
-type Out = String
+data Out = Lib String | Bin String
+ deriving (Show)
+
+instance Aeson.ToJSON Out where
+ toJSON out = outdir out |> Text.pack |> Aeson.String
data Compiler
= Copy
@@ -257,8 +261,12 @@ isBuildableNs = \case
]
-- | Emulate the *nix hierarchy in the cabdir.
-bindir, intdir, nixdir, vardir :: String
-bindir = "_/bin"
+outdir :: Out -> String
+outdir = \case
+ Bin o -> "_/bin" </> o
+ Lib o -> "_/lib" </> o
+
+intdir, nixdir, vardir :: String
intdir = "_/int"
nixdir = "_/nix"
vardir = "_/var"
@@ -267,7 +275,8 @@ createHier :: String -> IO ()
createHier root =
traverse_
(Dir.createDirectoryIfMissing True)
- [ root </> bindir,
+ [ root </> (outdir <| Bin ""),
+ root </> (outdir <| Lib ""),
root </> intdir,
root </> nixdir,
root </> vardir
@@ -360,7 +369,7 @@ analyze path = do
out =
contentLines
/> Text.unpack
- /> Regex.match (metaOut "//")
+ /> Regex.match (metaOut "//" <|> metaLib "//")
|> catMaybes
|> head,
builder = user <> "@localhost",
@@ -482,10 +491,11 @@ test :: Bool -> Target -> IO Exit.ExitCode
test loud Target {..} = case compiler of
GhcExe -> do
root <- Env.getEnv "BIZ_ROOT"
+ let o = Maybe.fromJust out
run
<| Proc
{ loud = loud,
- cmd = root </> bindir </> Maybe.fromJust out,
+ cmd = root </> outdir o,
args = ["test"],
ns = namespace,
onFailure = Log.fail ["test", nschunk namespace] >> Log.br,
@@ -500,11 +510,27 @@ build :: Bool -> Bool -> Target -> IO Exit.ExitCode
build andTest loud target@Target {..} = do
root <- Env.getEnv "BIZ_ROOT"
case compiler of
- Gcc -> do
- Log.info ["bild", "dev", "gcc", nschunk namespace]
- proc loud namespace "gcc" ["-o", root </> bindir </> Maybe.fromJust out, path]
+ Gcc -> case out of
+ Just ou -> case ou of
+ Bin _ -> do
+ Log.info ["bild", "bin", "gcc", nschunk namespace]
+ let baseFlags = ["-o", root </> outdir ou, path]
+ proc loud namespace "gcc" baseFlags
+ Lib _ -> do
+ Log.info ["bild", "lib", "gcc", nschunk namespace]
+ let baseFlags = ["-o", root </> outdir ou, path]
+ if "guile_3_0" `elem` sysdeps
+ then do
+ compileFlags <-
+ Process.readProcess "guile-config" ["compile"] ""
+ /> String.words
+ compileFlags <> baseFlags <> ["-shared", "-fPIC"]
+ |> proc loud namespace "gcc"
+ else proc loud namespace "gcc" baseFlags
+ Nothing -> Exit.die "no bin or lib found"
GhcExe -> do
Log.info ["bild", "dev", "ghc-exe", nschunk namespace]
+ let o = Maybe.fromJust out
exitcode <-
proc
loud
@@ -521,7 +547,7 @@ build andTest loud target@Target {..} = do
"-main-is",
Namespace.toHaskellModule namespace,
"-o",
- root </> bindir </> Maybe.fromJust out
+ root </> outdir o
]
if andTest && isSuccess exitcode
then test loud target
@@ -557,20 +583,20 @@ build andTest loud target@Target {..} = do
when (isJust out) <| do
let o = Maybe.fromJust out
writeFile
- (root </> bindir </> o)
+ (root </> outdir o)
<| Text.pack
<| joinWith
"\n"
[ "#!/usr/bin/env bash",
"guile -C \""
<> root </> intdir
- <> "\" -c \"(use-modules "
- <> Namespace.toSchemeModule namespace
- <> ") (main (command-line))\""
+ <> "\" -e main "
+ <> "-s "
+ <> Namespace.toPath namespace
<> " \"$@\""
]
- p <- Dir.getPermissions <| root </> bindir </> o
- Dir.setPermissions (root </> bindir </> o) (Dir.setOwnerExecutable True p)
+ p <- Dir.getPermissions <| root </> outdir o
+ Dir.setPermissions (root </> outdir o) (Dir.setOwnerExecutable True p)
pure Exit.ExitSuccess
NixBuild -> do
Log.info
@@ -596,16 +622,18 @@ build andTest loud target@Target {..} = do
pure Exit.ExitSuccess
Rustc -> do
Log.info ["bild", "dev", "rust", nschunk namespace]
+ let out' = Maybe.fromJust out
proc
loud
namespace
"rustc"
[ path,
"-o",
- root </> bindir </> Maybe.fromJust out
+ root </> outdir out'
]
Sbcl -> do
Log.info ["bild", "dev", "lisp", nschunk namespace]
+ let out' = Maybe.fromJust out
proc
loud
namespace
@@ -615,7 +643,7 @@ build andTest loud target@Target {..} = do
"--eval",
"(require :asdf)",
"--eval",
- "(sb-ext:save-lisp-and-die #p\"" <> (root </> bindir </> Maybe.fromJust out) <> "\" :toplevel #'main :executable t)"
+ "(sb-ext:save-lisp-and-die #p\"" <> (root </> outdir out') <> "\" :toplevel #'main :executable t)"
]
data Proc = Proc
@@ -666,13 +694,26 @@ nschunk :: Namespace -> Text
nschunk = Namespace.toPath .> Text.pack
metaDep :: Regex.RE Char Dep
-metaDep = Regex.string "-- : dep " *> Regex.many (Regex.psym Char.isAlpha)
+metaDep =
+ Regex.string "-- : dep "
+ *> Regex.many (Regex.psym Char.isAlpha)
metaSys :: [Char] -> Regex.RE Char Dep
-metaSys comment = Regex.string (comment ++ " : sys ") *> Regex.many (Regex.psym (not <. Char.isSpace))
+metaSys comment =
+ Regex.string (comment ++ " : sys ")
+ *> Regex.many (Regex.psym (not <. Char.isSpace))
metaOut :: [Char] -> Regex.RE Char Out
-metaOut comment = Regex.string (comment ++ " : out ") *> Regex.many (Regex.psym (/= ' '))
+metaOut comment =
+ Regex.string (comment ++ " : out ")
+ *> Regex.many (Regex.psym (/= ' '))
+ /> Bin
+
+metaLib :: [Char] -> Regex.RE Char Out
+metaLib comment =
+ Regex.string (comment ++ " : lib ")
+ *> Regex.many (Regex.psym (/= ' '))
+ /> Lib
haskellImports :: Regex.RE Char String
haskellImports =
diff --git a/Biz/Bild.nix b/Biz/Bild.nix
index da0c6a8..40309a1 100644
--- a/Biz/Bild.nix
+++ b/Biz/Bild.nix
@@ -45,6 +45,11 @@ rec {
src = ../.;
nativeBuildInputs = [ private.ghcPackageSetBild ];
buildInputs = [ nixpkgs.makeWrapper ];
+ propagatedBuildInputs = with nixpkgs; [
+ pkg-config
+ guile_3_0
+ sbcl
+ ];
strictDeps = true;
buildPhase = ''
mkdir -p $out/bin $out/lib/ghc-${private.ghcPackageSetFull.version}
diff --git a/Biz/Ide/repl b/Biz/Ide/repl
index 4c77e5b..a8fc124 100755
--- a/Biz/Ide/repl
+++ b/Biz/Ide/repl
@@ -32,6 +32,7 @@ fi
BILD="(import $BIZ_ROOT/Biz/Bild.nix {})"
for lib in ${sysdeps[@]}; do
flags+=(--packages "$BILD.private.nixpkgs.${lib}")
+ flags+=(--packages "$BILD.private.nixpkgs.pkg-config")
done
case $exts in
C)