add tool
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
recovery
|
||||||
|
build
|
||||||
|
BeefSpace_User.toml
|
||||||
6
BeefProj.toml
Normal file
6
BeefProj.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "CxxBuildTool"
|
||||||
|
TargetType = "BeefLib"
|
||||||
|
StartupObject = "CxxBuildTool.Program"
|
||||||
7
BeefSpace.toml
Normal file
7
BeefSpace.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Workspace]
|
||||||
|
StartupProject = "CxxBuildTool"
|
||||||
|
|
||||||
|
[Projects]
|
||||||
|
CxxBuildTool = {Path = "."}
|
||||||
9
README.md
Normal file
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# CxxBuildTool
|
||||||
|
```
|
||||||
|
[OnCompile(.TypeDone)]
|
||||||
|
private static void Build()
|
||||||
|
{
|
||||||
|
CxxBuildTool.CMake(Compiler.ProjectDir + "/SDL", Compiler.BuildDir + "/" + Compiler.ProjectName + "/SDL", "-DSDL_STATIC=ON -DSDL_SHARED=OFF -DSDL_TESTS=OFF");
|
||||||
|
CxxBuildTool.Ninja(Compiler.ProjectDir, Compiler.BuildDir + "/" + Compiler.ProjectName + "/vk_mem_alloc", "vk_mem_alloc", "-Ipath/to/vulkan/include", "vk_mem_alloc.cpp");
|
||||||
|
}
|
||||||
|
```
|
||||||
124
src/BuildTool.bf
Normal file
124
src/BuildTool.bf
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace CxxBuildTool;
|
||||||
|
|
||||||
|
static class CxxBuildTool
|
||||||
|
{
|
||||||
|
public static void CMake(StringView sourceDir, StringView buildDir, StringView cmakeFlags = "", StringView clangFlags = "")
|
||||||
|
{
|
||||||
|
if (!File.Exists(scope $"{buildDir}/CMakeCache.txt"))
|
||||||
|
{
|
||||||
|
StringView buildType;
|
||||||
|
String flags = scope .(64);
|
||||||
|
switch ((Compiler.Options.OptLevel)Compiler.Options.OptimizationLevel)
|
||||||
|
{
|
||||||
|
case .Og, .OgPlus:
|
||||||
|
buildType = "RelWithDebInfo";
|
||||||
|
flags.Append("-O2");
|
||||||
|
default:
|
||||||
|
buildType = "Release";
|
||||||
|
flags.Append('-');
|
||||||
|
_.ToString(flags);
|
||||||
|
}
|
||||||
|
flags.Append(" --target=", Compiler.Options.TargetTriple);
|
||||||
|
RunCommand("cmake", scope $"-S {sourceDir} -B {buildDir} {cmakeFlags} -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE={buildType
|
||||||
|
} -DCMAKE_C_FLAGS=\"{clangFlags} {flags}\" -DCMAKE_CXX_FLAGS=\"{clangFlags} {flags}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
RunCommand("cmake", scope $"--build {buildDir}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Ninja(StringView sourceDir, StringView buildDir, StringView projectName, StringView clangFlags, params Span<StringView> sourceFiles)
|
||||||
|
{
|
||||||
|
String ninja = scope .(1024);
|
||||||
|
ninja.AppendF($"""
|
||||||
|
src = {sourceDir}
|
||||||
|
builddir = {buildDir}
|
||||||
|
cflags = {clangFlags} --target={Compiler.Options.TargetTriple}
|
||||||
|
""");
|
||||||
|
switch ((Compiler.Options.OptLevel)Compiler.Options.OptimizationLevel)
|
||||||
|
{
|
||||||
|
case .Og, .OgPlus:
|
||||||
|
ninja.Append(" -O2 -g");
|
||||||
|
default:
|
||||||
|
ninja.Append(" -");
|
||||||
|
_.ToString(ninja);
|
||||||
|
}
|
||||||
|
ninja.Append("""
|
||||||
|
|
||||||
|
|
||||||
|
cc = clang
|
||||||
|
ar = llvm-ar
|
||||||
|
|
||||||
|
rule cc
|
||||||
|
command = $cc $cflags -MD -MF $out.d -c $in -o $out
|
||||||
|
depfile = $out.d
|
||||||
|
deps = gcc
|
||||||
|
description = Building $in
|
||||||
|
|
||||||
|
rule ar
|
||||||
|
command = $ar crs $out $in
|
||||||
|
description = Linking $out
|
||||||
|
|
||||||
|
|
||||||
|
""");
|
||||||
|
for (let src in sourceFiles)
|
||||||
|
ninja.Append("build $builddir/", src, ".o: cc $src/", src, "\n");
|
||||||
|
ninja.Append("\nbuild $builddir/", projectName,
|
||||||
|
((Compiler.Options.PlatformType)Compiler.Options.Platform == .Windows) ? ".lib" : ".a",
|
||||||
|
": ar");
|
||||||
|
for (let src in sourceFiles)
|
||||||
|
ninja.Append(" $builddir/", src, ".o");
|
||||||
|
ninja.Append('\n');
|
||||||
|
|
||||||
|
Directory.CreateDirectory(buildDir);
|
||||||
|
File.WriteAllText(scope $"{buildDir}/build.ninja", ninja);
|
||||||
|
RunCommand("ninja", scope $"-C {buildDir}");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RunCommand(StringView cmd, StringView args)
|
||||||
|
{
|
||||||
|
let startInfo = scope ProcessStartInfo();
|
||||||
|
startInfo.SetFileName(cmd);
|
||||||
|
startInfo.SetArguments(args);
|
||||||
|
startInfo.UseShellExecute = false;
|
||||||
|
startInfo.RedirectStandardOutput = true;
|
||||||
|
startInfo.RedirectStandardError = true;
|
||||||
|
startInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
|
let proc = scope SpawnedProcess();
|
||||||
|
Runtime.Assert(proc.Start(startInfo) case .Ok, "starting command failed");
|
||||||
|
|
||||||
|
FileStream output = scope .();
|
||||||
|
FileStream error = scope .();
|
||||||
|
proc.AttachStandardOutput(output);
|
||||||
|
proc.AttachStandardError(error);
|
||||||
|
|
||||||
|
String str = scope .();
|
||||||
|
Span<uint8> buffer = uint8[1024]();
|
||||||
|
StringView bufferView = *(.)&buffer;
|
||||||
|
while (!proc.HasExited || !output.IsEmpty || !error.IsEmpty)
|
||||||
|
{
|
||||||
|
while (output.TryRead(buffer) case .Ok(let val) && val > 0)
|
||||||
|
str.Append(bufferView[..<val]);
|
||||||
|
if (!str.IsEmpty)
|
||||||
|
{
|
||||||
|
Console.Write(str);
|
||||||
|
str.Clear();
|
||||||
|
}
|
||||||
|
while (error.TryRead(buffer) case .Ok(let val) && val > 0)
|
||||||
|
str.Append(bufferView[..<val]);
|
||||||
|
if (!str.IsEmpty)
|
||||||
|
{
|
||||||
|
Console.Write(str);
|
||||||
|
str.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Runtime.Assert(proc.ExitCode == 0, "command failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user