diff --git a/CxxBuilder/.gitignore b/CxxBuilder/.gitignore deleted file mode 100644 index e39ba07..0000000 --- a/CxxBuilder/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -build -recovery -test -BeefSpace_User.toml - -dist/* diff --git a/CxxBuilder/BeefProj.toml b/CxxBuilder/BeefProj.toml deleted file mode 100644 index ac03748..0000000 --- a/CxxBuilder/BeefProj.toml +++ /dev/null @@ -1,29 +0,0 @@ -FileVersion = 1 - -[Project] -Name = "CxxBuilder" -StartupObject = "CxxBuilder.Program" - -[Configs.Debug.Win32] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Debug.Win64] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Release.Win32] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Release.Win64] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Paranoid.Win32] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Paranoid.Win64] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Test.Win32] -TargetDirectory = "$(ProjectDir)/dist" - -[Configs.Test.Win64] -TargetDirectory = "$(ProjectDir)/dist" diff --git a/CxxBuilder/BeefSpace.toml b/CxxBuilder/BeefSpace.toml deleted file mode 100644 index 0a4bbc5..0000000 --- a/CxxBuilder/BeefSpace.toml +++ /dev/null @@ -1,5 +0,0 @@ -FileVersion = 1 -Projects = {CxxBuilder = {Path = "."}} - -[Workspace] -StartupProject = "CxxBuilder" diff --git a/CxxBuilder/src/FileMatcher.bf b/CxxBuilder/src/FileMatcher.bf deleted file mode 100644 index 7d704f6..0000000 --- a/CxxBuilder/src/FileMatcher.bf +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Diagnostics; - -namespace CxxBuilder; - -static class FileMatcher -{ - public enum Error - { - ExpectedEscapeSequence, - CharacterClassNotClosed, - } - - public static Result HandleMatches(Span patterns, StringView directory, delegate void(StringView match) callback) - { - Runtime.Assert(Directory.Exists(directory), scope $"No such directory {directory}"); - void Dir(StringView dir) - { - dir: for (let element in Directory.Enumerate(dir)) - { - let path = element.GetFilePath(..scope .()); - path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - if (element.IsDirectory) - { - Dir(path); - continue; - } - let relpath = Path.GetRelativePath(path, directory, ..scope .()); - for (let pattern in patterns) - { - if (!pattern.StartsWith('^') && !pattern.StartsWith('!')) continue; - if (IsMatch(pattern[1...], relpath)) - continue dir; - } - for (let pattern in patterns) - { - if (pattern.StartsWith('^') || pattern.StartsWith('!')) continue; - if (!IsMatch(pattern, relpath)) continue; - callback(relpath); - break; - } - } - } - Dir(directory); - return .Ok; - } - - public static Result IsMatch(StringView pattern, StringView path) - { - var pattern, path; - - Result Matches(StringView pattern, char8 c) - { - if (pattern.IsEmpty) return false; - - switch (pattern[0]) - { - case '*': - if (pattern.Length > 1 && pattern[1] == '*') - return true; - return !Path.IsDirectorySeparatorChar(c); - case '?': return true; - case '\\': - if (pattern.Length <= 1) return .Err(.ExpectedEscapeSequence); - return c == pattern[1]; - case '/': return Path.IsDirectorySeparatorChar(c); - case '[': - int i = 0; - char8 Next() - { - if (pattern.Length <= ++i) - return (.)7; - return pattern[i]; - } - bool negated = false; - char8 current; - switch (Next()) - { - case (.)7: return .Err(.CharacterClassNotClosed); - case '^', '!': negated = true; fallthrough; - case '\\': current = Next(); - case ']': return false; - default: current = _; - } - while (true) - { - if (c == current) return !negated; - switch (Next()) - { - case ']': return negated; - case '-': - let end = Next(); - if (c >= current && c <= end) - return !negated; - current = Next(); - case '\\': current = Next(); - default: current = _; - } - } - default: - return c == _; - } - } - - reduce: while (true) - { - if (path.IsEmpty) return true; - if (pattern.IsEmpty) return false; - switch (Matches(pattern, path[0])) - { - case .Err: return _; - case .Ok(false): return false; - case .Ok: - } - switch (pattern[0]) - { - case '*': - StringView lazy; - if (pattern.Length > 1) - { - lazy = pattern; - lazy.RemoveFromStart(pattern[1] == '*' ? 2 : 1); - } - else lazy = .(); - defer { pattern = lazy; } - while (true) - { - if (Try!(IsMatch(lazy, path))) continue reduce; - if (!Try!(Matches(pattern, path[0]))) continue reduce; - path.RemoveFromStart(1); - if (path.IsEmpty) return lazy.IsEmpty; - } - case '[': - bool escaped = false; - while (true) - { - let c = pattern[0]; - pattern.RemoveFromStart(1); - if (c == ']' && !escaped) - { - path.RemoveFromStart(1); - continue reduce; - } - escaped = c == '\\'; - } - case '\\': - pattern.RemoveFromStart(2); - path.RemoveFromStart(1); - default: - pattern.RemoveFromStart(1); - path.RemoveFromStart(1); - } - } - } -} \ No newline at end of file diff --git a/CxxBuilder/src/Program.bf b/CxxBuilder/src/Program.bf deleted file mode 100644 index 1affc07..0000000 --- a/CxxBuilder/src/Program.bf +++ /dev/null @@ -1,301 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Diagnostics; - -namespace CxxBuilder; - -static class Program -{ - [CLink] static extern int32 system(char8*); - - public static int Main(String[] args) - { - if (args.Count == 3 && args[0] == "---__defsyms__") - { - GenerateAliases(args); - return 0; - } - - mixin PrintUsage() - { - Console.WriteLine(""" - Simple and fast build tool using clang and ninja. - - Usage: $(Var CxxBuilderExe) [] -- src=<> target=<> config=<> builddir=<> output=<> [cflags=<>] - Example: $(Var CxxBuilderExe) **.c vk_*.cpp -- "src=$(ProjectDir)/MyLib/src" target=$(TargetTriple) config=$(Configuration) "builddir=$(BuildDir)" output=MyLib cflags=-Isome/dir - - --cmake - builds $src/CMakeLists.txt to build, patterns and output are ignored - ! --template - TODO - ! --cpp-aliases - creates aliases from the mangled c++ symbols to the symbols queried by Cpp2Beef-generated c++ bindigs - - $src - The source dir, all patterns are rooted here - $target - the llvm target triple passed to clang - $config - the build configuration - $builddir - contains build artifacts and ninja files - $output - the name of the output object archive $builddir/$output.lib on windows and $builddir/$output.a elsewhere - $cflags - additional flags passed to clang - """); - return 1; - } - - mixin Assert(bool condition, StringView str) - { - if (!condition) - { - Console.Error.WriteLine(str); - return 1; - } - } - - enum { Default, CMake, Template } mode = .Default; - enum { None, CppAliases } actions = .None; - StringView src = null, target = null, config = null, builddir = null, output = null, cflags = null; - var iter = args.GetEnumerator(); - skipPatterns: do - { - for (let arg in iter) - { - if (!arg.StartsWith("--")) continue; - switch (arg) - { - case "--": break skipPatterns; - case "--cmake": - Assert!(mode == .Default, "Conflicting options"); - mode = .CMake; - /*case "--cpp-aliases": - actions |= .CppAliases;*/ - default: - Console.Error.WriteLine($"Invalid option {_}"); - return 1; - } - } - PrintUsage!(); - } - Assert!(!(mode == .CMake && actions.HasFlag(.CppAliases)), "Comflicting options --cmake and --cpp-aliases"); - for (let arg in iter) - { - var parts = arg.Split('=', 2); - StringView key = parts.GetNext().Value; - StringView value; - switch (parts.GetNext()) - { - case .Err: PrintUsage!(); - case .Ok(out value): - } - key.Trim(); - value.Trim(); - switch (key) - { - case "src": Assert!(src.IsNull, "Duplicate var 'src'"); src = value; - case "target": Assert!(target.IsNull, "Duplicate var 'target'"); target = value; - case "config": Assert!(config.IsNull, "Duplicate var 'config'"); config = value; - case "builddir": Assert!(builddir.IsNull, "Duplicate var 'builddir'"); builddir = value; - case "output": Assert!(output.IsNull, "Duplicate var 'output'"); output = value; - case "cflags": Assert!(cflags.IsNull, "Duplicate var 'cflags'"); cflags = value; - default: PrintUsage!(); - } - } - Assert!(!src.IsNull, "Missing var 'src'"); - Assert!(!target.IsNull, "Missing var 'target'"); - Assert!(!config.IsNull, "Missing var 'config'"); - Assert!(!builddir.IsNull, "Missing var 'builddir'"); - Assert!(!output.IsNull || (mode == .CMake && !actions.HasFlag(.CppAliases)), "Missing var 'output'"); - - switch (mode) - { - case .Default: - StreamWriter writer = scope .()..Create(scope $"{builddir}/build.ninja"); - { - String buffer = scope .(1024); - let currentDir = Directory.GetCurrentDirectory(..scope .(128)); - void WriteVarPath(StringView key, StringView value) - { - buffer.Append(key); - buffer.Append(" = "); - Path.GetAbsolutePath(value, currentDir, buffer); - buffer.Append('\n'); - } - WriteVarPath("src", src); - WriteVarPath("builddir", builddir); - buffer.AppendF($""" - target = {target} - cflags = {(config == "Release") ? "-O3" : "-O2 -g"} {cflags} - """); - writer.Write(buffer); - } - writer.Write(""" - \n - cc = clang - ar = llvm-ar - - rule cc - command = $cc $cflags -target $target -MD -MF $out.d -c -o $out $in - deps = gcc - depfile = $out.d - description = Building $in - - rule ar - command = $ar crs $out $in - description = Creating static lib $out - - - """); - String ar = scope .(1024); - StringView libExtension = target.Contains("windows") ? "lib" : "a"; - ar.AppendF($"\nbuild $builddir/{output}.{libExtension}: ar"); - - int pcount = 0; - for (let arg in args) - { - if (arg == "--") break; - pcount++; - } - StringView[] patterns = scope .[pcount]; - for (var pattern in ref patterns) - { - pattern = args[@pattern]; - } - - void HandleMatch(StringView match) - { - writer.Write($"build $builddir/{match}.o: cc $src/{match}\n"); - ar.Append(" $builddir/", match, ".o"); - } - let abssrc = Path.GetAbsolutePath(src, Directory.GetCurrentDirectory(..scope .(128)), ..scope .(128)); - if (FileMatcher.HandleMatches(patterns, abssrc, scope => HandleMatch) case .Err(let err)) - { - Console.Error.WriteLine($"Syntax Error in Pattern: {err}"); - return 1; - } - - writer.WriteLine(ar); - - if (actions.HasFlag(.CppAliases)) - { - const String exec = .Empty -#if BF_PLATFORM_WINDOWS - + "cmd /c "; -#endif - writer.Write($""" - - nm = llvm-nm - ld = {exec}ld - - rule nm - command = {exec}$nm --demangle $in > $out - description = Exporting symbols from $in - - rule generate_aliases - command = "{Environment.GetExecutableFilePath(..scope .(64))}" ---__defsyms__ $in $out - description = Generating aliases - - rule ld_aliases - command = $ld -r -o $out @$in "$builddir/{output}.{libExtension}" - description = Creating aliases - - rule ar_add - command = $ar qs $builddir/{output}.{libExtension} $in - - build $builddir/_symbols__.txt: nm $builddir/{output}.{libExtension} - build $builddir/_aliases__.txt: generate_aliases $builddir/_symbols__.txt - build $builddir/_aliases__.o: ld_aliases $builddir/_aliases__.txt - build add_to_output: ar_add $builddir/_aliases__.o - - """); - } - case .CMake: -#if !DEBUG - if (File.Exists(scope $"{builddir}/build.ninja")) - break; -#endif - String cmd = scope .(512); - cmd.Append("cmake -S \"", src, "\" -B \"", builddir, "\" -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ "); - cmd.Append("-DCMAKE_C_FLAGS=\"-target ", target, " ", cflags, "\" -DCMAKE_CXX_FLAGS=\"-target ", target, " ", cflags, "\" -DCMAKE_BUILD_TYPE="); - if (config == "Release") cmd.Append("Release"); - else cmd.Append("RelWithDebInfo"); - Assert!(system(cmd) == 0, "Build file generation failed"); - case .Template: //TODO - } - - var ret = system(scope $"ninja -C {builddir}"); - mixin CheckRetCode(StringView fmt) - { - if (ret != 0) - { - Console.Error.WriteLine(fmt, output); - return ret; - } - } - CheckRetCode!("Failed to build {}"); - - /*if (actions.HasFlag(.CppAliases)) - { - let aliasesDir = scope $"{builddir}/cpp2beef_aliases"; - Directory.CreateDirectory(aliasesDir); - { - StreamWriter writer = scope .()..Create(scope $"{aliasesDir}/aliases.c"); - ret = system(scope $"llvm-nm --export-symbols \"{builddir}/{output}.{target.Contains("windows") ? "lib" : "a"}\" > {aliasesDir}/mangled.txt"); - CheckRetCode!("Failed to fetch symbols from {}"); - ret = system(scope $"cat {aliasesDir}/mangled.txt | llvm-undname >{aliasesDir}/demangled.txt 2>{ -#if BF_PLATFORM_WINDOWS - ("nul") -#else - ("/dev/null") -#endif - }"); - CheckRetCode!("Failed to demangle symbols from {}"); - var mangled = scope StreamReader()..Open(scope $"{aliasesDir}/magled.txt").Lines; - var demangled = scope StreamReader()..Open(scope $"{aliasesDir}/demangled.txt").Lines; - for (let dline in demangled) - { - if (dline->IsEmpty) continue; - let mline = mangled.GetNext().Value; - if (mline == dline) continue; - String identifier = scope .(dline); - for (let i < identifier.Length) - if (!identifier[i].IsLetterOrDigit) - identifier[i] = '_'; - writer.Write($"extern void {identifier}() __attribute__((weak, alias(\"{mline.Value}\")));\n"); - } - } - File.WriteAllText(scope $"{aliasesDir}/build.ninja", scope $""" - rule cc - command = clang -x c -target {target} -c -o $out $in - description = Compiling aliases for {output} - - build aliases.o: cc aliases.c - - """); - ret = system(scope $"ninja -C {aliasesDir}"); - CheckRetCode!("Failed to build aliases for {}"); - }*/ - - return 0; - } - - static void GenerateAliases(String[] args) - { - StreamReader reader = scope .()..Open(args[1]); - StreamWriter writer = scope .()..Create(args[2]); - String str = scope .(256); - for (var line in reader.Lines) - { - line->Trim(); - if (line->IsEmpty || line->EndsWith(':')) continue; - var split = line->Split(' ', 3); - if (split.GetNext().Value == "U") continue; - int addr = int.Parse(split.Current, .Hex); - let kind = split.GetNext().Value; - if (kind != "T" || addr == 0) continue; - let sym = split.GetNext().Value; - if (!str.IsEmpty) str..Clear()..Append(' '); - str.Append("--defsym="); - for (let i < sym.Length) - str.Append(sym[i].IsLetterOrDigit ? sym[i] : '_'); - str.Append('='); - addr.ToString(str); - writer.Write(str); - } - } -} \ No newline at end of file diff --git a/Setup/.gitignore b/Setup/.gitignore deleted file mode 100644 index 8043483..0000000 --- a/Setup/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -build -recovery -BeefSapce_user.toml diff --git a/Setup/BeefProj.toml b/Setup/BeefProj.toml deleted file mode 100644 index 4bb5965..0000000 --- a/Setup/BeefProj.toml +++ /dev/null @@ -1,5 +0,0 @@ -FileVersion = 1 - -[Project] -Name = "Cpp2Beef.Setup" -StartupObject = "Cpp2Beef.Setup.Program" diff --git a/Setup/BeefSpace.toml b/Setup/BeefSpace.toml deleted file mode 100644 index f354dc7..0000000 --- a/Setup/BeefSpace.toml +++ /dev/null @@ -1,5 +0,0 @@ -FileVersion = 1 -Projects = {"Cpp2Beef.Setup" = {Path = "."}} - -[Workspace] -StartupProject = "Cpp2Beef.Setup" diff --git a/Setup/src/Program.bf b/Setup/src/Program.bf deleted file mode 100644 index 2ffe7bb..0000000 --- a/Setup/src/Program.bf +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.IO; - -namespace Cpp2Beef.Setup; - -static class Program -{ - [CLink] static extern int32 system(char8*); - static void RunCommand(char8* cmd) - { - Console.WriteLine($"> {StringView(cmd)}"); - if (system(cmd) != 0) - Runtime.FatalError("Command failed"); - } - - public static int Main(String[] args) - { - RunCommand("beefbuild -workspace=\"../CxxBuilder\" -config=Release"); - String setCxxBuilderExe = scope .(512); - Path.GetAbsolutePath("../CxxBuilder/dist/CxxBuilder", Directory.GetCurrentDirectory(..scope .(128)), setCxxBuilderExe); -#if BF_PLATFORM_WINDOWS - setCxxBuilderExe.Append(".exe"); -#endif - File.WriteAllText("../CxxBuilder/dist/CxxBuilderPath.txt", setCxxBuilderExe); - return 0; - } -} \ No newline at end of file