From bb90117dd5729a662ed68e83e3cdfa2b5c9856dd Mon Sep 17 00:00:00 2001 From: Rune Date: Sat, 21 Mar 2026 21:48:58 +0100 Subject: [PATCH 01/20] logic is executing --- BeefLibs/corlib/src/Compiler.bf | 21 ++++++-- IDE/src/BuildContext.bf | 16 +++++++ IDE/src/Compiler/BfCompiler.bf | 24 ++++++++++ IDE/src/IDEApp.bf | 56 ++++++++++++++++++++++ IDE/src/Project.bf | 4 ++ IDE/src/ui/ProjectProperties.bf | 1 + IDEHelper/Compiler/BfCompiler.cpp | 79 +++++++++++++++++++++++++++++-- IDEHelper/Compiler/BfCompiler.h | 6 ++- 8 files changed, 197 insertions(+), 10 deletions(-) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 230a4d8d9..8ee77fc66 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -258,6 +258,15 @@ namespace System public abstract class BuildLogic { + public String mCmdInfo = new .() ~ delete _; + + public void AddLibPath(StringView lib) + { + mCmdInfo.Append("addLibPath\t"); + lib.QuoteString(mCmdInfo); + mCmdInfo.Append('\n'); + } + public virtual void PreBuild() { } @@ -265,13 +274,17 @@ namespace System { } - static void PreBuild() where T : BuildLogic + static String PreBuild() where T : BuildLogic { - scope T().PreBuild(); + T val = scope T(); + val.PreBuild(); + return val.mCmdInfo; } - static void PostBuild() where T : BuildLogic + static String PostBuild() where T : BuildLogic { - scope T().PostBuild(); + T val = scope T(); + val.PostBuild(); + return val.mCmdInfo; } } diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 24706b8d3..b54860854 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -173,6 +173,18 @@ namespace IDE return didCommands ? .HadCommands : .NoCommands; } + public void QueueBuildLogic(Project project, IDEApp.BuildLogicCmd.Stage stage) + { + if (project.mBeefGlobalOptions.mBuildLogicObject.IsEmpty) + return; + + gApp.mExecutionQueue.Add(new IDEApp.BuildLogicCmd() + { + mObject = new String(project.mBeefGlobalOptions.mBuildLogicObject), + mStage = stage, + }); + } + bool QueueProjectGNUArchive(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg) { #if BF_PLATFORM_WINDOWS @@ -1505,6 +1517,8 @@ namespace IDE case .Failed: completedCompileCmd.mFailed = true; } + + QueueBuildLogic(project, .PreBuild); } if (project.mGeneralOptions.mTargetType == .CustomBuild) @@ -1701,6 +1715,8 @@ namespace IDE if (targetPath == null) return false; + QueueBuildLogic(project, .PostBuild); + switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds)) { case .NoCommands: diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 29b92133e..664677ee7 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -123,6 +123,15 @@ namespace IDE.Compiler [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetGeneratorGenData(void* bfCompiler, char8* typeDefName, char8* args); + [CallingConvention(.Stdcall), CLink] + static extern bool BfCompiler_ValidateBuildLogic(void* bfCompiler, char8* typeDefName); + + [CallingConvention(.Stdcall), CLink] + static extern char8* BfCompiler_ExecuteBuildLogicPreBuild(void* bfCompiler, char8* typeDefName); + + [CallingConvention(.Stdcall), CLink] + static extern char8* BfCompiler_ExecuteBuildLogicPostBuild(void* bfCompiler, char8* typeDefName); + [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetTypeDefList(void* bfCompiler, bool includeLocation); @@ -851,6 +860,21 @@ namespace IDE.Compiler outStr.Append(BfCompiler_GetGeneratorGenData(mNativeBfCompiler, typeDefName, args)); } + public bool ValidateBuildLogic(String typeDefName) + { + return BfCompiler_ValidateBuildLogic(mNativeBfCompiler, typeDefName); + } + + public void ExecuteBuildLogicPreBuild(String typeDefName, String outStr) + { + outStr.Append(BfCompiler_ExecuteBuildLogicPreBuild(mNativeBfCompiler, typeDefName)); + } + + public void ExecuteBuildLogicPostBuild(String typeDefName, String outStr) + { + outStr.Append(BfCompiler_ExecuteBuildLogicPostBuild(mNativeBfCompiler, typeDefName)); + } + public void GetTypeDefList(String outStr, bool includeLocation = false) { outStr.Append(BfCompiler_GetTypeDefList(mNativeBfCompiler, includeLocation)); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 50784a9f2..c1fa61b8d 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -476,6 +476,14 @@ namespace IDE public String mPath ~ delete _; } + public class BuildLogicCmd : ExecutionCmd + { + public enum Stage { PreBuild, PostBuild } + + public String mObject ~ delete _; + public Stage mStage; + } + public enum ArgsFileKind { None, @@ -9861,6 +9869,54 @@ namespace IDE // Already handled (void)scriptCmd; } + else if (var buildLogicCmd = next as BuildLogicCmd) do + { + mBfBuildSystem.Lock(0); + defer mBfBuildSystem.Unlock(); + + Stopwatch stopwatch = scope .()..Start(); + + if (!mBfBuildCompiler.ValidateBuildLogic(buildLogicCmd.mObject)) + { + OutputErrorLine($"Invalid Compiler.BuildLogic object: {buildLogicCmd.mObject}"); + buildFailed = true; + break; + } + + String output = scope .(); + switch (buildLogicCmd.mStage) + { + case .PreBuild: mBfBuildCompiler.ExecuteBuildLogicPreBuild(buildLogicCmd.mObject, output); + case .PostBuild: mBfBuildCompiler.ExecuteBuildLogicPostBuild(buildLogicCmd.mObject, output); + } + + for (let line in output.Split('\n', .RemoveEmptyEntries)) + { + int index = line.IndexOf('\t'); + if (index < 0) + { + OutputErrorLine($"Malformed build logic execution result: {line}"); + buildFailed = true; + continue; + } + + switch (line[.. mPreprocessorMacros = new List() ~ DeleteContainerAndItems!(_); @@ -1657,6 +1659,7 @@ namespace IDE data.ConditionalAdd("Version", mGeneralOptions.mVersion.mVersion); data.ConditionalAdd("TargetType", mGeneralOptions.mTargetType, GetDefaultTargetType()); data.ConditionalAdd("StartupObject", mBeefGlobalOptions.mStartupObject, IsSingleFile ? "Program" : ""); + data.ConditionalAdd("BuildLogicObject", mBeefGlobalOptions.mBuildLogicObject); var defaultNamespace = scope String(); GetSanitizedName(mProjectName, defaultNamespace, true); data.ConditionalAdd("DefaultNamespace", mBeefGlobalOptions.mDefaultNamespace, defaultNamespace); @@ -2014,6 +2017,7 @@ namespace IDE data.GetString("Version", mGeneralOptions.mVersion.mVersion); ReadStrings("Aliases", mGeneralOptions.mAliases); data.GetString("StartupObject", mBeefGlobalOptions.mStartupObject, IsSingleFile ? "Program" : ""); + data.GetString("BuildLogicObject", mBeefGlobalOptions.mBuildLogicObject); var defaultNamespace = scope String(); GetSanitizedName(mProjectName, defaultNamespace, true); data.GetString("DefaultNamespace", mBeefGlobalOptions.mDefaultNamespace, defaultNamespace); diff --git a/IDE/src/ui/ProjectProperties.bf b/IDE/src/ui/ProjectProperties.bf index 091dbe157..376b769c7 100644 --- a/IDE/src/ui/ProjectProperties.bf +++ b/IDE/src/ui/ProjectProperties.bf @@ -985,6 +985,7 @@ namespace IDE.ui category.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, 0xFFE8E8E8); AddPropertiesItem(category, "Startup Object", "mStartupObject"); + AddPropertiesItem(category, "Build Logic Object", "mBuildLogicObject"); AddPropertiesItem(category, "Default Namespace", "mDefaultNamespace"); AddPropertiesItem(category, "Preprocessor Macros", "mPreprocessorMacros"); DistinctOptionBuilder dictinctOptionBuilder = scope .(this); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 50a2b9144..66c7448bd 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -436,6 +436,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mPlatformTypeDef = NULL; mCompilerTypeDef = NULL; mCompilerGeneratorTypeDef = NULL; + mCompilerBuildLogicTypeDef = NULL; mDiagnosticsDebugTypeDef = NULL; mIDisposableTypeDef = NULL; mIIntegerTypeDef = NULL; @@ -7321,6 +7322,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mPlatformTypeDef = _GetRequiredType("System.Platform"); mCompilerTypeDef = _GetRequiredType("System.Compiler"); mCompilerGeneratorTypeDef = _GetRequiredType("System.Compiler.Generator"); + mCompilerBuildLogicTypeDef = _GetRequiredType("System.Compiler.BuildLogic"); mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); mIIntegerTypeDef = _GetRequiredType("System.IInteger"); @@ -9081,7 +9083,7 @@ String BfCompiler::GetTypeDefList(bool includeLocation) return result; } -String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args) +String BfCompiler::ExecuteUserDefinedMethod(BfTypeDef* typeDef, BfTypeInstance* typeInst, BfTypeDef* parentClass, const StringImpl& generatorMethodName, const StringImpl* args) { if (typeInst == NULL) { @@ -9095,7 +9097,7 @@ String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeIn BfTypeVector typeVector; typeVector.Add(typeInst); - auto generatorTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompilerGeneratorTypeDef)->ToTypeInstance(); + auto generatorTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(parentClass)->ToTypeInstance(); auto methodDef = generatorTypeInst->mTypeDef->GetMethodByName(generatorMethodName); auto moduleMethodInstance = mContext->mUnreifiedModule->GetMethodInstance(generatorTypeInst, methodDef, typeVector); @@ -9165,7 +9167,7 @@ String BfCompiler::GetGeneratorTypeDefList() result += typeDef->mProject->mName; result += ":"; result += BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName); - String nameString = GetGeneratorString(typeDef, typeInst, "GetName", NULL); + String nameString = ExecuteUserDefinedMethod(typeDef, typeInst, mCompilerGeneratorTypeDef, "GetName", NULL); if (!nameString.IsEmpty()) result += "\t" + nameString; result += "\n"; @@ -9191,7 +9193,7 @@ String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const String String result; for (auto typeDef : typeDefs) { - result += GetGeneratorString(typeDef, NULL, "InitUI", &args); + result += ExecuteUserDefinedMethod(typeDef, NULL, mCompilerGeneratorTypeDef, "InitUI", &args); if (!result.IsEmpty()) break; } @@ -9214,7 +9216,7 @@ String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringI String result; for (auto typeDef : typeDefs) { - result += GetGeneratorString(typeDef, NULL, "Generate", &args); + result += ExecuteUserDefinedMethod(typeDef, NULL, mCompilerGeneratorTypeDef, "Generate", &args); if (!result.IsEmpty()) break; } @@ -9224,6 +9226,49 @@ String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringI return result; } +bool BfCompiler::ValidateBuildLogic(const StringImpl& typeName) +{ + BfType* type = GetType(typeName); + + BfTypeInstance* typeInst = NULL; + if (type != NULL) + typeInst = type->ToTypeInstance(); + + return ((typeInst != NULL) && + (typeInst->mBaseType != NULL) && + (typeInst->mBaseType->IsInstanceOf(mCompilerBuildLogicTypeDef))); +} + +String BfCompiler::ExecuteBuildLogicPreBuild(const StringImpl& typeName) +{ + BfResolvePassData resolvePassData; + SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); + BfPassInstance passInstance(mSystem); + SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); + + BfTypeInstance* typeInst = GetType(typeName)->ToTypeInstance(); + + String result = ExecuteUserDefinedMethod(typeInst->mTypeDef, typeInst, mCompilerBuildLogicTypeDef, "PreBuild", NULL); + + HandleGeneratorErrors(result); + return result; +} + +String BfCompiler::ExecuteBuildLogicPostBuild(const StringImpl& typeName) +{ + BfResolvePassData resolvePassData; + SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); + BfPassInstance passInstance(mSystem); + SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); + + BfTypeInstance* typeInst = GetType(typeName)->ToTypeInstance(); + + String result = ExecuteUserDefinedMethod(typeInst->mTypeDef, typeInst, mCompilerBuildLogicTypeDef, "PostBuild", NULL); + + HandleGeneratorErrors(result); + return result; +} + String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr, bool includeLocation) { String result; @@ -10682,6 +10727,30 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGeneratorGenData(BfCompiler* bfC return outString.c_str(); } +BF_EXPORT bool BF_CALLTYPE BfCompiler_ValidateBuildLogic(BfCompiler* bfCompiler, char* typeDefName) +{ + String name(typeDefName); + return bfCompiler->ValidateBuildLogic(name); +} + +BF_EXPORT const char* BF_CALLTYPE BfCompiler_ExecuteBuildLogicPreBuild(BfCompiler* bfCompiler, char* typeDefName) +{ + String name(typeDefName); + String& outString = *gTLStrReturn.Get(); + outString.clear(); + outString = bfCompiler->ExecuteBuildLogicPreBuild(name); + return outString.c_str(); +} + +BF_EXPORT const char* BF_CALLTYPE BfCompiler_ExecuteBuildLogicPostBuild(BfCompiler* bfCompiler, char* typeDefName) +{ + String name(typeDefName); + String& outString = *gTLStrReturn.Get(); + outString.clear(); + outString = bfCompiler->ExecuteBuildLogicPostBuild(name); + return outString.c_str(); +} + BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefList(BfCompiler* bfCompiler, bool includeLocation) { String& outString = *gTLStrReturn.Get(); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index fc39436ce..09e606b01 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -393,6 +393,7 @@ class BfCompiler BfTypeDef* mPlatformTypeDef; BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerGeneratorTypeDef; + BfTypeDef* mCompilerBuildLogicTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIIntegerTypeDef; @@ -550,11 +551,14 @@ class BfCompiler void RequestFastFinish(); void RequestExtraCompile(); String GetTypeDefList(bool includeLocation); - String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args); + String ExecuteUserDefinedMethod(BfTypeDef* typeDef, BfTypeInstance* typeInst, BfTypeDef* parentClass, const StringImpl& generatorMethodName, const StringImpl* args); void HandleGeneratorErrors(StringImpl& result); String GetGeneratorTypeDefList(); String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args); String GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args); + bool ValidateBuildLogic(const StringImpl& typeName); + String ExecuteBuildLogicPreBuild(const StringImpl& typeName); + String ExecuteBuildLogicPostBuild(const StringImpl& typeName); String GetTypeDefMatches(const StringImpl& searchSrc, bool includeLocation); void GetTypeDefs(const StringImpl& typeName, Array& typeDefs); String GetTypeDefInfo(const StringImpl& typeName); From 50cff8c3367bde3929c4562af367520321f2debe Mon Sep 17 00:00:00 2001 From: Rune Date: Sun, 22 Mar 2026 15:08:46 +0100 Subject: [PATCH 02/20] debugging support --- IDE/src/IDEApp.bf | 80 +++++++++++++++++++++++---------- IDEHelper/Compiler/BfModule.cpp | 2 +- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 4573f4584..8ce1525f0 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -476,7 +476,7 @@ namespace IDE public String mPath ~ delete _; } - public class BuildLogicCmd : ExecutionCmd + public class StartCustomBuildLogicCmd : ExecutionCmd { public enum Stage { PreBuild, PostBuild } @@ -484,6 +484,16 @@ namespace IDE public Stage mStage; } + public class ProcessCustomBuildLogicCmd : ExecutionCmd + { + public String mTypeName ~ delete _; + public StartCustomBuildLogicCmd.Stage mStage; + + public String mOutput ~ delete _; + public Thread mThread ~ delete _; + public Stopwatch mStopwatch ~ delete _; + } + public enum ArgsFileKind { None, @@ -9628,6 +9638,12 @@ namespace IDE } } + if (var processBuildLogicCmd = next as ProcessCustomBuildLogicCmd) + { + if (processBuildLogicCmd.mThread.IsAlive) + return; + } + #if BF_PLATFORM_WINDOWS if (let startDebugCmd = next as StartDebugCmd) { @@ -9876,34 +9892,49 @@ namespace IDE // Already handled (void)scriptCmd; } - else if (var buildLogicCmd = next as BuildLogicCmd) do + else if (var cmd = next as StartCustomBuildLogicCmd) do { - mBfBuildSystem.Lock(0); - defer mBfBuildSystem.Unlock(); - - Stopwatch stopwatch = scope .()..Start(); - - if (!mBfBuildCompiler.ValidateBuildLogic(buildLogicCmd.mObject)) + if (!mBfBuildCompiler.ValidateBuildLogic(cmd.mObject)) { - OutputErrorLine($"Invalid Compiler.BuildLogic object: {buildLogicCmd.mObject}"); - buildFailed = true; + OutputErrorLine($"Invalid Compiler.BuildLogic: {cmd.mObject}"); + ClearAndDeleteItems(mExecutionQueue); break; } - String output = scope .(); - switch (buildLogicCmd.mStage) - { - case .PreBuild: mBfBuildCompiler.ExecuteBuildLogicPreBuild(buildLogicCmd.mObject, output); - case .PostBuild: mBfBuildCompiler.ExecuteBuildLogicPostBuild(buildLogicCmd.mObject, output); - } + ProcessCustomBuildLogicCmd process = new .(); + process.mOutput = new .(); + process.mTypeName = new .(cmd.mObject); + process.mStage = cmd.mStage; + process.mStopwatch = new .(); - for (let line in output.Split('\n', .RemoveEmptyEntries)) + process.mThread = new .(new () => + { + mBfBuildSystem.Lock(0); + switch (process.mStage) + { + case .PreBuild: mBfBuildCompiler.ExecuteBuildLogicPreBuild(process.mTypeName, process.mOutput); + case .PostBuild: mBfBuildCompiler.ExecuteBuildLogicPostBuild(process.mTypeName, process.mOutput); + } + mBfBuildSystem.Unlock(); + }); + process.mThread.AutoDelete = false; + process.mThread.SetJoinOnDelete(true); + + process.mStopwatch.Start(); + process.mThread.Start(); + mExecutionQueue.AddFront(process); + } + else if (var cmd = next as ProcessCustomBuildLogicCmd) + { + // thread has ended + bool failed = false; + for (let line in cmd.mOutput.Split('\n', .RemoveEmptyEntries)) { int index = line.IndexOf('\t'); if (index < 0) { OutputErrorLine($"Malformed build logic execution result: {line}"); - buildFailed = true; + CancelBuild(); continue; } @@ -9914,15 +9945,18 @@ namespace IDE //line[(index+1)...].UnQuoteString(path); //mDynamicallyAddedLibPaths.Add(path); case "!error": - OutputLine($"{line[(index+1)...]}"); - buildFailed = true; + OutputLineSmart($"{line[(index+1)...]}"); + failed = true; default: OutputErrorLine($"Invalid build logic execution command: {_}"); - buildFailed = true; + failed = true; } - - OutputLineSmart($"Build logic '{buildLogicCmd.mObject}.{buildLogicCmd.mStage}' finished in {stopwatch.ElapsedMilliseconds / 1000.0f:0.00}s"); } + + if (failed) + ClearAndDeleteItems(mExecutionQueue); + else + OutputLine($"{cmd.mTypeName}.{cmd.mStage} finished in {cmd.mStopwatch.ElapsedMilliseconds / 1000.0f:0.00}s"); } else if (var writeEmitCmd = next as WriteEmitCmd) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 4acbb6deb..6753f5d74 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -15703,7 +15703,7 @@ void BfModule::HadSlotCountDependency() BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) { BfProject* project = mProject; - if ((project == NULL) && (mCurMethodState != NULL)) + if ((project == NULL) && (mCurMethodState != NULL) && (mCurMethodState->mMethodInstance != NULL)) project = mCurMethodState->mMethodInstance->mMethodDef->mDeclaringType->mProject; if (str == "#IsComptime") From 3444edfc0b7cc8217ef9b74f7a03049d63ea9466 Mon Sep 17 00:00:00 2001 From: Rune Date: Sun, 22 Mar 2026 15:13:22 +0100 Subject: [PATCH 03/20] update naming --- IDE/src/BuildContext.bf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 655c548ac..a5f3905b7 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -185,12 +185,12 @@ namespace IDE return didCommands ? .HadCommands : .NoCommands; } - public void QueueBuildLogic(Project project, IDEApp.BuildLogicCmd.Stage stage) + public void QueueBuildLogic(Project project, IDEApp.StartCustomBuildLogicCmd.Stage stage) { if (project.mBeefGlobalOptions.mBuildLogicObject.IsEmpty) return; - gApp.mExecutionQueue.Add(new IDEApp.BuildLogicCmd() + gApp.mExecutionQueue.Add(new IDEApp.StartCustomBuildLogicCmd() { mObject = new String(project.mBeefGlobalOptions.mBuildLogicObject), mStage = stage, From 875ea7404446fd2e741ceec4c93816f0977a9437 Mon Sep 17 00:00:00 2001 From: Rune Date: Sun, 22 Mar 2026 20:21:28 +0100 Subject: [PATCH 04/20] comptime output --- BeefBoot/BootApp.cpp | 9 +++++++++ BeefLibs/corlib/src/Compiler.bf | 17 +++++++++++++++++ IDE/src/Compiler/BfCompiler.bf | 16 ++++++++++++++++ IDEHelper/Compiler/BfCompiler.cpp | 6 ++++++ IDEHelper/Compiler/CeMachine.cpp | 21 +++++++++++++++++++++ IDEHelper/Compiler/CeMachine.h | 5 +++++ 6 files changed, 74 insertions(+) diff --git a/BeefBoot/BootApp.cpp b/BeefBoot/BootApp.cpp index c2f33536a..d45e2f1ac 100644 --- a/BeefBoot/BootApp.cpp +++ b/BeefBoot/BootApp.cpp @@ -28,6 +28,8 @@ BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler); BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx, const char* targetTriple, const char* targetCPU, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads, Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName); +BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, + void (BF_CALLTYPE* callback)(void* userdata, char* ptr, int len)); BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler); BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath); BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler); @@ -790,6 +792,12 @@ void BootApp::DoLinkGNU() auto runCmd = QueueRun(linkerPath, linkLine, mWorkingDir, BfpSpawnFlag_UseArgsFile); } +static void BF_CALLTYPE ComptimeWriteToOutputCallback(void* userdata, char* ptr, int len) +{ + String text(ptr, len); + gApp->OutputLine(text, OutputPri_Normal); +} + bool BootApp::Compile() { DWORD startTick = BFTickCount(); @@ -813,6 +821,7 @@ bool BootApp::Compile() BfProjectFlags flags = BfProjectFlags_None; BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags); + BfCompiler_SetComptimeWriteToOutputCallback(mCompiler, NULL, ComptimeWriteToOutputCallback); } if (!mDefines.IsEmpty()) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 8ee77fc66..c04a9fc2d 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -267,9 +267,12 @@ namespace System mCmdInfo.Append('\n'); } + [Comptime] public virtual void PreBuild() { } + + [Comptime] public virtual void PostBuild() { } @@ -447,6 +450,7 @@ namespace System static extern void Comptime_EmitMethodExit(int64 methodHandle, StringView text); static extern void Comptime_EmitMixin(StringView text); static extern String Comptime_GetStringById(int32 id); + static extern void Comptime_WriteToOutput(StringView text); [Comptime(OnlyFromComptime=true)] public static MethodBuilder CreateMethod(Type owner, StringView methodName, Type returnType, MethodFlags methodFlags) @@ -492,6 +496,19 @@ namespace System Comptime_EmitMethodExit(methodHandle.[Friend]mData.mComptimeMethodInstance, text); } + [Comptime(OnlyFromComptime=true)] + public static void Write(StringView text) + { + Comptime_WriteToOutput(text); + } + + [Comptime(OnlyFromComptime=true)] + public static void WriteLine(StringView text) + { + Comptime_WriteToOutput(text); + Comptime_WriteToOutput("\n"); + } + [Comptime(ConstEval=true)] public static void Mixin(StringView text) { diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 664677ee7..731cab4df 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -155,6 +155,11 @@ namespace IDE.Compiler void* hotProject, int32 hotIdx, char8* targetTriple, char8* targetCPU, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads, OptionFlags optionsFlags, char8* mallocName, char8* freeName); + [CallingConvention(.Stdcall)] + public function void ComptimeWriteToOutputCallback(void* userdata, char8* ptr, int32 len); + [CallingConvention(.Stdcall), CLink] + static extern void BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, ComptimeWriteToOutputCallback callback); + [CallingConvention(.Stdcall), CLink] static extern void BfCompiler_ForceRebuild(void* bfCompiler); @@ -352,6 +357,11 @@ namespace IDE.Compiler targetTriple, targetCPU, toolsetType, simdSetting, allocStackCount, maxWorkerThreads, optionFlags, mallocFuncName, freeFuncName); } + public void SetComptimeWriteToOutputCallback(void* userdata, ComptimeWriteToOutputCallback callback) + { + BfCompiler_SetComptimeWriteToOutputCallback(mNativeBfCompiler, userdata, callback); + } + public void ForceRebuild() { BfCompiler_ForceRebuild(mNativeBfCompiler); @@ -792,6 +802,12 @@ namespace IDE.Compiler mBfSystem.AddTypeOptions(typeOption); for (let typeOption in options.mDistinctBuildOptions) mBfSystem.AddTypeOptions(typeOption); + + SetComptimeWriteToOutputCallback(Internal.UnsafeCastToPtr(IDEApp.sApp), (userdata, ptr, len) => + { + IDEApp app = (.)Internal.UnsafeCastToObject(userdata); + app.Output(scope String(ptr, len)); + }); } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 66c7448bd..8caa504dd 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -11333,6 +11333,12 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje } } +BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(BfCompiler* bfCompiler, void* userdata, CeWriteToOutputCallback callback) +{ + bfCompiler->mCeMachine->mWriteToOutputUserData = userdata; + bfCompiler->mCeMachine->mWriteToOutputCallback = callback; +} + BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler) { bfCompiler->mOptions.mForceRebuildIdx++; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index f22064fb5..e72d9db06 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -7049,6 +7049,21 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeSetAddrVal(stackPtr + 0, GetString(string), ptrSize); _FixVariables(); } + else if (checkFunction->mFunctionKind == CeFunctionKind_WriteToOutput) + { + if (mCeMachine->mWriteToOutputCallback != NULL) + { + addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr); + String text; + if (!GetStringFromStringView(strViewPtr, text)) + { + _Fail("Invalid StringView"); + return false; + } + + mCeMachine->mWriteToOutputCallback(mCeMachine->mWriteToOutputUserData, text.GetPtr(), text.GetLength()); + } + } else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep) { int32 sleepMS = *(int32*)((uint8*)stackPtr); @@ -9639,6 +9654,8 @@ CeMachine::CeMachine(BfCompiler* compiler) mRevisionExecuteTime = 0; mCurBuilder = NULL; mPreparingFunction = NULL; + mWriteToOutputUserData = NULL; + mWriteToOutputCallback = NULL; mCurEmitContext = NULL; @@ -10335,6 +10352,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_GetStringById; } + else if (methodDef->mName == "Comptime_WriteToOutput") + { + ceFunction->mFunctionKind = CeFunctionKind_WriteToOutput; + } } else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef)) { diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 7445989ab..232f0ad16 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -469,6 +469,7 @@ enum CeFunctionKind CeFunctionKind_EmitMethodExit, CeFunctionKind_EmitMixin, CeFunctionKind_GetStringById, + CeFunctionKind_WriteToOutput, CeFunctionKind_BfpDirectory_Create, CeFunctionKind_BfpDirectory_Rename, @@ -1239,6 +1240,8 @@ class CeStepState } }; +typedef void (BF_CALLTYPE* CeWriteToOutputCallback)(void* userdata, const char* ptr, int len); + class CeMachine { public: @@ -1266,6 +1269,8 @@ class CeMachine CeCallSource* mCurCallSource; CeBuilder* mCurBuilder; CeFunction* mPreparingFunction; + void* mWriteToOutputUserData; + CeWriteToOutputCallback mWriteToOutputCallback; BfParser* mTempParser; BfReducer* mTempReducer; From 2807d8cc0b377cc02d990c76833ce68071bafa3b Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 23 Mar 2026 15:12:42 +0100 Subject: [PATCH 05/20] comptime console output --- BeefLibs/corlib/src/Compiler.bf | 14 ------------- BeefLibs/corlib/src/Console.bf | 1 + IDEHelper/Compiler/BfCompiler.cpp | 2 ++ IDEHelper/Compiler/BfCompiler.h | 1 + IDEHelper/Compiler/CeMachine.cpp | 34 +++++++++++++++---------------- IDEHelper/Compiler/CeMachine.h | 2 +- 6 files changed, 22 insertions(+), 32 deletions(-) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index c04a9fc2d..72b459e45 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -450,7 +450,6 @@ namespace System static extern void Comptime_EmitMethodExit(int64 methodHandle, StringView text); static extern void Comptime_EmitMixin(StringView text); static extern String Comptime_GetStringById(int32 id); - static extern void Comptime_WriteToOutput(StringView text); [Comptime(OnlyFromComptime=true)] public static MethodBuilder CreateMethod(Type owner, StringView methodName, Type returnType, MethodFlags methodFlags) @@ -496,19 +495,6 @@ namespace System Comptime_EmitMethodExit(methodHandle.[Friend]mData.mComptimeMethodInstance, text); } - [Comptime(OnlyFromComptime=true)] - public static void Write(StringView text) - { - Comptime_WriteToOutput(text); - } - - [Comptime(OnlyFromComptime=true)] - public static void WriteLine(StringView text) - { - Comptime_WriteToOutput(text); - Comptime_WriteToOutput("\n"); - } - [Comptime(ConstEval=true)] public static void Mixin(StringView text) { diff --git a/BeefLibs/corlib/src/Console.bf b/BeefLibs/corlib/src/Console.bf index d00c379c1..5c1872eeb 100644 --- a/BeefLibs/corlib/src/Console.bf +++ b/BeefLibs/corlib/src/Console.bf @@ -185,6 +185,7 @@ namespace System public static this() { + if (Compiler.IsComptime) return; let handle = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO consoleInfo = .(); if (GetConsoleScreenBufferInfo(handle, out consoleInfo) != 0) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 8caa504dd..3405a86d6 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -437,6 +437,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mCompilerTypeDef = NULL; mCompilerGeneratorTypeDef = NULL; mCompilerBuildLogicTypeDef = NULL; + mConsoleTypeDef = NULL; mDiagnosticsDebugTypeDef = NULL; mIDisposableTypeDef = NULL; mIIntegerTypeDef = NULL; @@ -7323,6 +7324,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mCompilerTypeDef = _GetRequiredType("System.Compiler"); mCompilerGeneratorTypeDef = _GetRequiredType("System.Compiler.Generator"); mCompilerBuildLogicTypeDef = _GetRequiredType("System.Compiler.BuildLogic"); + mConsoleTypeDef = _GetRequiredType("System.Console"); mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); mIIntegerTypeDef = _GetRequiredType("System.IInteger"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 09e606b01..f18c58ce0 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -394,6 +394,7 @@ class BfCompiler BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerGeneratorTypeDef; BfTypeDef* mCompilerBuildLogicTypeDef; + BfTypeDef* mConsoleTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIIntegerTypeDef; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index e72d9db06..e0377f990 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6159,6 +6159,18 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Dynamic cast check failed"); return false; } + else if (checkFunction->mFunctionKind == CeFunctionKind_Console_PutChars) + { + if (mCeMachine->mWriteToOutputCallback != NULL) + { + int32 ptrVal = *(int32*)((uint8*)stackPtr + 0); + int32 size = *(int32*)(stackPtr + ceModule->mSystem->mPtrSize); + CE_CHECKADDR(ptrVal, size); + char* strPtr = (char*)(ptrVal + memStart); + + mCeMachine->mWriteToOutputCallback(mCeMachine->mWriteToOutputUserData, strPtr, size); + } + } else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite) { int32 ptrVal = *(int32*)((uint8*)stackPtr + 0); @@ -7049,21 +7061,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeSetAddrVal(stackPtr + 0, GetString(string), ptrSize); _FixVariables(); } - else if (checkFunction->mFunctionKind == CeFunctionKind_WriteToOutput) - { - if (mCeMachine->mWriteToOutputCallback != NULL) - { - addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr); - String text; - if (!GetStringFromStringView(strViewPtr, text)) - { - _Fail("Invalid StringView"); - return false; - } - - mCeMachine->mWriteToOutputCallback(mCeMachine->mWriteToOutputUserData, text.GetPtr(), text.GetLength()); - } - } else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep) { int32 sleepMS = *(int32*)((uint8*)stackPtr); @@ -10352,9 +10349,12 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_GetStringById; } - else if (methodDef->mName == "Comptime_WriteToOutput") + } + else if (owner->IsInstanceOf(mCeModule->mCompiler->mConsoleTypeDef)) + { + if (methodDef->mName == "PutChars") { - ceFunction->mFunctionKind = CeFunctionKind_WriteToOutput; + ceFunction->mFunctionKind = CeFunctionKind_Console_PutChars; } } else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef)) diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 232f0ad16..b54ff0dac 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -428,6 +428,7 @@ enum CeFunctionKind CeFunctionKind_Free, CeFunctionKind_DynCheckFailed, CeFunctionKind_FatalError, + CeFunctionKind_Console_PutChars, CeFunctionKind_DebugWrite, CeFunctionKind_DebugWrite_Int, CeFunctionKind_GetReflectTypeDeclById, @@ -469,7 +470,6 @@ enum CeFunctionKind CeFunctionKind_EmitMethodExit, CeFunctionKind_EmitMixin, CeFunctionKind_GetStringById, - CeFunctionKind_WriteToOutput, CeFunctionKind_BfpDirectory_Create, CeFunctionKind_BfpDirectory_Rename, From d03cc39346d7e09ecc87c375884359831a51577f Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 23 Mar 2026 17:03:03 +0100 Subject: [PATCH 06/20] shell commands from comptime --- BeefLibs/corlib/src/Compiler.bf | 3 --- BeefLibs/corlib/src/Console.bf | 3 +++ IDE/src/Compiler/BfCompiler.bf | 16 ++++++++++++++++ IDEHelper/Compiler/BfCompiler.cpp | 6 ++++++ IDEHelper/Compiler/CeMachine.cpp | 27 +++++++++++++++++++++++++++ IDEHelper/Compiler/CeMachine.h | 5 +++++ 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 72b459e45..8ee77fc66 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -267,12 +267,9 @@ namespace System mCmdInfo.Append('\n'); } - [Comptime] public virtual void PreBuild() { } - - [Comptime] public virtual void PostBuild() { } diff --git a/BeefLibs/corlib/src/Console.bf b/BeefLibs/corlib/src/Console.bf index 5c1872eeb..f9a7e71b6 100644 --- a/BeefLibs/corlib/src/Console.bf +++ b/BeefLibs/corlib/src/Console.bf @@ -468,5 +468,8 @@ namespace System Write("\x1B[H\x1B[J"); #endif } + + [LinkName("system")] + public static extern int32 RunShellCommand(char8* command); } } diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 731cab4df..7e16e22e2 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -160,6 +160,11 @@ namespace IDE.Compiler [CallingConvention(.Stdcall), CLink] static extern void BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, ComptimeWriteToOutputCallback callback); + [CallingConvention(.Stdcall)] + public function Platform.BfpSpawn* ComptimeRunShellCommandCallback(void* userdata, char8* cmd, int32* outExitCode); + [CallingConvention(.Stdcall), CLink] + static extern void BfCompiler_SetComptimeRunShellCommandCallback(void* bfCompiler, void* userdata, ComptimeRunShellCommandCallback callback); + [CallingConvention(.Stdcall), CLink] static extern void BfCompiler_ForceRebuild(void* bfCompiler); @@ -362,6 +367,11 @@ namespace IDE.Compiler BfCompiler_SetComptimeWriteToOutputCallback(mNativeBfCompiler, userdata, callback); } + public void SetComptimeRunShellCommandCallback(void* userdata, ComptimeRunShellCommandCallback callback) + { + BfCompiler_SetComptimeRunShellCommandCallback(mNativeBfCompiler, userdata, callback); + } + public void ForceRebuild() { BfCompiler_ForceRebuild(mNativeBfCompiler); @@ -808,6 +818,12 @@ namespace IDE.Compiler IDEApp app = (.)Internal.UnsafeCastToObject(userdata); app.Output(scope String(ptr, len)); }); + SetComptimeRunShellCommandCallback(Internal.UnsafeCastToPtr(IDEApp.sApp), (userdata, cmd, outExitCode) => + { + IDEApp app = (.)Internal.UnsafeCastToObject(userdata); + let inst = app.DoRun("", StringView(cmd), app.mWorkspace.mDir, .None, null, null, .ShellCommand); + return inst.mProcess.[Friend]mSpawn; + }); } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 3405a86d6..6415f4003 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -11341,6 +11341,12 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(BfCompile bfCompiler->mCeMachine->mWriteToOutputCallback = callback; } +BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(BfCompiler* bfCompiler, void* userdata, CeRunShellCommandCallback callback) +{ + bfCompiler->mCeMachine->mRunShellCommandUserData = userdata; + bfCompiler->mCeMachine->mRunShellCommandCallback = callback; +} + BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler) { bfCompiler->mOptions.mForceRebuildIdx++; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index e0377f990..340aef3fd 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6171,6 +6171,26 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* mCeMachine->mWriteToOutputCallback(mCeMachine->mWriteToOutputUserData, strPtr, size); } } + else if (checkFunction->mFunctionKind == CeFunctionKind_Console_RunShellCommand) + { + if (mCeMachine->mRunShellCommandCallback == NULL) + { + _Fail("Console.RunShellCommand is only avaliable when building"); + } + else + { + int32 ptrVal = *(int32*)(stackPtr + 4); + char* strPtr = (char*)(ptrVal + memStart); + + int32 exitCode; + auto waitEvent = mCeMachine->mRunShellCommandCallback(mCeMachine->mRunShellCommandUserData, strPtr, &exitCode); + + if (waitEvent != NULL) + BfpSpawn_WaitFor(waitEvent, -1, &exitCode, NULL); + + *((int32*)stackPtr) = exitCode; + } + } else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite) { int32 ptrVal = *(int32*)((uint8*)stackPtr + 0); @@ -9651,8 +9671,11 @@ CeMachine::CeMachine(BfCompiler* compiler) mRevisionExecuteTime = 0; mCurBuilder = NULL; mPreparingFunction = NULL; + mWriteToOutputUserData = NULL; mWriteToOutputCallback = NULL; + mRunShellCommandUserData = NULL; + mRunShellCommandCallback = NULL; mCurEmitContext = NULL; @@ -10356,6 +10379,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_Console_PutChars; } + else if (methodDef->mName == "RunShellCommand") + { + ceFunction->mFunctionKind = CeFunctionKind_Console_RunShellCommand; + } } else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef)) { diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index b54ff0dac..ba18a2ec4 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -429,6 +429,7 @@ enum CeFunctionKind CeFunctionKind_DynCheckFailed, CeFunctionKind_FatalError, CeFunctionKind_Console_PutChars, + CeFunctionKind_Console_RunShellCommand, CeFunctionKind_DebugWrite, CeFunctionKind_DebugWrite_Int, CeFunctionKind_GetReflectTypeDeclById, @@ -1241,6 +1242,7 @@ class CeStepState }; typedef void (BF_CALLTYPE* CeWriteToOutputCallback)(void* userdata, const char* ptr, int len); +typedef BfpSpawn* (BF_CALLTYPE* CeRunShellCommandCallback)(void* userdata, const char* cmd, int* outExitcode); class CeMachine { @@ -1269,8 +1271,11 @@ class CeMachine CeCallSource* mCurCallSource; CeBuilder* mCurBuilder; CeFunction* mPreparingFunction; + void* mWriteToOutputUserData; CeWriteToOutputCallback mWriteToOutputCallback; + void* mRunShellCommandUserData; + CeRunShellCommandCallback mRunShellCommandCallback; BfParser* mTempParser; BfReducer* mTempReducer; From 7415a8fae549f457f4528b038b4623f105f070d7 Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 23 Mar 2026 17:45:15 +0100 Subject: [PATCH 07/20] getenv, setenv in comptime --- BeefBoot/BootApp.cpp | 9 +++++++++ IDEHelper/Compiler/CeMachine.cpp | 34 +++++++++++++++++++++++++++++--- IDEHelper/Compiler/CeMachine.h | 2 ++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/BeefBoot/BootApp.cpp b/BeefBoot/BootApp.cpp index d45e2f1ac..d5b701d49 100644 --- a/BeefBoot/BootApp.cpp +++ b/BeefBoot/BootApp.cpp @@ -30,6 +30,8 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProj Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName); BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, void (BF_CALLTYPE* callback)(void* userdata, char* ptr, int len)); +BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(void* bfCompiler, void* userdata, + void* (BF_CALLTYPE* callback)(void* userdata, char* cmd, int* outExitcode)); BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler); BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath); BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler); @@ -798,6 +800,12 @@ static void BF_CALLTYPE ComptimeWriteToOutputCallback(void* userdata, char* ptr, gApp->OutputLine(text, OutputPri_Normal); } +static void* BF_CALLTYPE ComptimeRunShellCommandCallback(void* userdata, char* cmd, int* outExitcode) +{ + *outExitcode = system(cmd); + return NULL; +} + bool BootApp::Compile() { DWORD startTick = BFTickCount(); @@ -822,6 +830,7 @@ bool BootApp::Compile() BfProjectFlags flags = BfProjectFlags_None; BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags); BfCompiler_SetComptimeWriteToOutputCallback(mCompiler, NULL, ComptimeWriteToOutputCallback); + BfCompiler_SetComptimeRunShellCommandCallback(mCompiler, NULL, ComptimeRunShellCommandCallback); } if (!mDefines.IsEmpty()) diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 340aef3fd..859e7f1ad 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -2085,6 +2085,7 @@ void CeBuilder::Build() auto beModule = irCodeGen->mBeModule; mCeFunction->mFailed = true; + mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64); auto methodInstance = mCeFunction->mMethodInstance; @@ -2130,8 +2131,6 @@ void CeBuilder::Build() return; } - mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64); - for (int funcIdx = startFunctionCount; funcIdx < (int)beModule->mFunctions.size(); funcIdx++) { auto beFunction = beModule->mFunctions[funcIdx]; @@ -7104,6 +7103,31 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* int64& result = *(int64*)((uint8*)stackPtr + 0); result = BfpSystem_GetTimeStamp(); } + else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetEnvironmentVariable) + { + intptr offset = 0; +#define CE_NEXT_PTR_ARG(type, name) \ + int32 name##PtrVal = *(int32*)((intptr)stackPtr + offset); \ + type name = (type)(name##PtrVal + memStart); \ + offset += ptrSize + + CE_NEXT_PTR_ARG(char*, varName); + CE_NEXT_PTR_ARG(char*, outStr); + CE_NEXT_PTR_ARG(int32*, inOutStrSize); + CE_NEXT_PTR_ARG(BfpSystemResult*, outResult); + + BfpSystem_GetEnvironmentVariable(varName, outStr, inOutStrSize, outResult); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_SetEnvironmentVariable) + { + intptr offset = 0; + CE_NEXT_PTR_ARG(char*, varName); + CE_NEXT_PTR_ARG(char*, value); + CE_NEXT_PTR_ARG(BfpSystemResult*, outResult); +#undef CE_NEXT_PTR_ARG + + BfpSystem_SetEnvironmentVariable(varName, value, outResult); + } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower) { int32& result = *(int32*)((uint8*)stackPtr + 0); @@ -10503,7 +10527,11 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_Release; else if (methodDef->mName == "BfpSystem_GetTimeStamp") - ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp; + ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp; + else if (methodDef->mName == "BfpSystem_GetEnvironmentVariable") + ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetEnvironmentVariable; + else if (methodDef->mName == "BfpSystem_SetEnvironmentVariable") + ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_SetEnvironmentVariable; } else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef)) { diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index ba18a2ec4..951eecf93 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -518,6 +518,8 @@ enum CeFunctionKind CeFunctionKind_BfpSpawn_WaitFor, CeFunctionKind_BfpSystem_GetTimeStamp, + CeFunctionKind_BfpSystem_GetEnvironmentVariable, + CeFunctionKind_BfpSystem_SetEnvironmentVariable, CeFunctionKind_Sleep, CeFunctionKind_Char32_ToLower, From 432011276629b447e205c847cede0339e288aa07 Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 23 Mar 2026 18:42:35 +0100 Subject: [PATCH 08/20] make enum globs eval to enum type instead of int32 --- IDEHelper/Compiler/BfCompiler.cpp | 9 +++++++++ IDEHelper/Compiler/BfCompiler.h | 5 +++++ IDEHelper/Compiler/BfModule.cpp | 8 ++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 6415f4003..73950313a 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -449,6 +449,10 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mIOnTypeDoneTypeDef = NULL; mIOnFieldInitTypeDef = NULL; mIOnMethodInitTypeDef = NULL; + mCompilerOptionsPlatformTypeTypeDef = NULL; + mCompilerOptionsMachineTypeTypeDef = NULL; + mCompilerOptionsToolsetTypeTypeDef = NULL; + mCompilerOptionsOptLevelTypeDef = NULL; mLinkNameAttributeTypeDef = NULL; mCallingConventionAttributeTypeDef = NULL; mMethodRefTypeDef = NULL; @@ -7337,6 +7341,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mIOnFieldInitTypeDef = _GetRequiredType("System.IOnFieldInit"); mIOnMethodInitTypeDef = _GetRequiredType("System.IOnMethodInit"); + mCompilerOptionsPlatformTypeTypeDef = _GetRequiredType("System.Compiler.Options.PlatformType"); + mCompilerOptionsMachineTypeTypeDef = _GetRequiredType("System.Compiler.Options.MachineType"); + mCompilerOptionsToolsetTypeTypeDef = _GetRequiredType("System.Compiler.Options.ToolsetType"); + mCompilerOptionsOptLevelTypeDef = _GetRequiredType("System.Compiler.Options.OptLevel"); + mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute"); mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute"); mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index f18c58ce0..845677cc8 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -407,6 +407,11 @@ class BfCompiler BfTypeDef* mIOnFieldInitTypeDef; BfTypeDef* mIOnMethodInitTypeDef; + BfTypeDef* mCompilerOptionsPlatformTypeTypeDef; + BfTypeDef* mCompilerOptionsMachineTypeTypeDef; + BfTypeDef* mCompilerOptionsToolsetTypeTypeDef; + BfTypeDef* mCompilerOptionsOptLevelTypeDef; + BfTypeDef* mMethodRefTypeDef; BfTypeDef* mNullableTypeDef; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 6753f5d74..b1675a7fa 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -15750,15 +15750,15 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) } if (str == "#Platform") { - return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mPlatformType), GetPrimitiveType(BfTypeCode_Int32)); + return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mPlatformType), ResolveTypeDef(mCompiler->mCompilerOptionsPlatformTypeTypeDef)); } if (str == "#Architecture") { - return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mMachineType), GetPrimitiveType(BfTypeCode_Int32)); + return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mMachineType), ResolveTypeDef(mCompiler->mCompilerOptionsMachineTypeTypeDef)); } if (str == "#Toolset") { - return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mToolsetType), GetPrimitiveType(BfTypeCode_Int32)); + return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mToolsetType), ResolveTypeDef(mCompiler->mCompilerOptionsToolsetTypeTypeDef)); } if (str == "#TargetTriple") { @@ -15766,7 +15766,7 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) } if (str == "#OptimizationLevel") { - return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, project->mCodeGenOptions.mOptLevel), GetPrimitiveType(BfTypeCode_Int32)); + return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, project->mCodeGenOptions.mOptLevel), ResolveTypeDef(mCompiler->mCompilerOptionsOptLevelTypeDef)); } if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)) From 49bbcd3483b33b954e5489a04708025b901eddeb Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 23 Mar 2026 19:05:48 +0100 Subject: [PATCH 09/20] remove AddLibPath --- BeefLibs/corlib/src/Compiler.bf | 4 ++-- IDE/src/IDEApp.bf | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 8ee77fc66..edec8ab7b 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -260,12 +260,12 @@ namespace System { public String mCmdInfo = new .() ~ delete _; - public void AddLibPath(StringView lib) + /*public void AddLibPath(StringView lib) { mCmdInfo.Append("addLibPath\t"); lib.QuoteString(mCmdInfo); mCmdInfo.Append('\n'); - } + }*/ public virtual void PreBuild() { diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index a0776ab55..fe949a4e0 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -9940,10 +9940,10 @@ namespace IDE switch (line[.. Date: Wed, 25 Mar 2026 16:09:21 +0100 Subject: [PATCH 10/20] remove build logic --- BeefDep1_Done.txt | 1 + BeefLibs/corlib/src/Compiler.bf | 32 ----------- BeefLibs/corlib/src/Platform.bf | 5 +- IDE/src/BuildContext.bf | 4 -- IDE/src/Compiler/BfCompiler.bf | 24 --------- IDE/src/IDEApp.bf | 90 ------------------------------- IDE/src/Program.bf | 4 ++ IDEHelper/Compiler/BfCompiler.cpp | 77 ++------------------------ IDEHelper/Compiler/BfCompiler.h | 2 +- 9 files changed, 14 insertions(+), 225 deletions(-) create mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt new file mode 100644 index 000000000..8ad96f878 --- /dev/null +++ b/BeefDep1_Done.txt @@ -0,0 +1 @@ +Done \ No newline at end of file diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index edec8ab7b..80492dfc1 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -256,38 +256,6 @@ namespace System } } - public abstract class BuildLogic - { - public String mCmdInfo = new .() ~ delete _; - - /*public void AddLibPath(StringView lib) - { - mCmdInfo.Append("addLibPath\t"); - lib.QuoteString(mCmdInfo); - mCmdInfo.Append('\n'); - }*/ - - public virtual void PreBuild() - { - } - public virtual void PostBuild() - { - } - - static String PreBuild() where T : BuildLogic - { - T val = scope T(); - val.PreBuild(); - return val.mCmdInfo; - } - static String PostBuild() where T : BuildLogic - { - T val = scope T(); - val.PostBuild(); - return val.mCmdInfo; - } - } - public struct MethodBuilder { void* mNative; diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf index 854e257b4..1c0c3112f 100644 --- a/BeefLibs/corlib/src/Platform.bf +++ b/BeefLibs/corlib/src/Platform.bf @@ -106,8 +106,9 @@ namespace System public static extern void BfpSystem_GetExecutablePath(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); [CallingConvention(.Stdcall), CLink] public static extern void BfpSystem_GetEnvironmentStrings(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); - [CallingConvention(.Stdcall), CLink] - public static extern void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); + /*[CallingConvention(.Stdcall), CLink] + public static extern void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult);*/ + public static void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult) => Runtime.NotImplemented(); [CallingConvention(.Stdcall), CLink] public static extern void BfpSystem_SetEnvironmentVariable(char8* varName, char8* value, BfpSystemResult* outResult); [CallingConvention(.Stdcall), CLink] diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 70074699b..01a2b353d 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -1559,8 +1559,6 @@ namespace IDE case .Failed: completedCompileCmd.mFailed = true; } - - QueueBuildLogic(project, .PreBuild); } if (project.mGeneralOptions.mTargetType == .CustomBuild) @@ -1759,8 +1757,6 @@ namespace IDE if (WantsProjectBuild(project, compileKind)) { - QueueBuildLogic(project, .PostBuild); - switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds)) { case .NoCommands: diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 7e16e22e2..5496e1ae0 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -123,15 +123,6 @@ namespace IDE.Compiler [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetGeneratorGenData(void* bfCompiler, char8* typeDefName, char8* args); - [CallingConvention(.Stdcall), CLink] - static extern bool BfCompiler_ValidateBuildLogic(void* bfCompiler, char8* typeDefName); - - [CallingConvention(.Stdcall), CLink] - static extern char8* BfCompiler_ExecuteBuildLogicPreBuild(void* bfCompiler, char8* typeDefName); - - [CallingConvention(.Stdcall), CLink] - static extern char8* BfCompiler_ExecuteBuildLogicPostBuild(void* bfCompiler, char8* typeDefName); - [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetTypeDefList(void* bfCompiler, bool includeLocation); @@ -892,21 +883,6 @@ namespace IDE.Compiler outStr.Append(BfCompiler_GetGeneratorGenData(mNativeBfCompiler, typeDefName, args)); } - public bool ValidateBuildLogic(String typeDefName) - { - return BfCompiler_ValidateBuildLogic(mNativeBfCompiler, typeDefName); - } - - public void ExecuteBuildLogicPreBuild(String typeDefName, String outStr) - { - outStr.Append(BfCompiler_ExecuteBuildLogicPreBuild(mNativeBfCompiler, typeDefName)); - } - - public void ExecuteBuildLogicPostBuild(String typeDefName, String outStr) - { - outStr.Append(BfCompiler_ExecuteBuildLogicPostBuild(mNativeBfCompiler, typeDefName)); - } - public void GetTypeDefList(String outStr, bool includeLocation = false) { outStr.Append(BfCompiler_GetTypeDefList(mNativeBfCompiler, includeLocation)); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index fe949a4e0..7a1f14490 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -476,24 +476,6 @@ namespace IDE public String mPath ~ delete _; } - public class StartCustomBuildLogicCmd : ExecutionCmd - { - public enum Stage { PreBuild, PostBuild } - - public String mObject ~ delete _; - public Stage mStage; - } - - public class ProcessCustomBuildLogicCmd : ExecutionCmd - { - public String mTypeName ~ delete _; - public StartCustomBuildLogicCmd.Stage mStage; - - public String mOutput ~ delete _; - public Thread mThread ~ delete _; - public Stopwatch mStopwatch ~ delete _; - } - public enum ArgsFileKind { None, @@ -9638,12 +9620,6 @@ namespace IDE } } - if (var processBuildLogicCmd = next as ProcessCustomBuildLogicCmd) - { - if (processBuildLogicCmd.mThread.IsAlive) - return; - } - #if BF_PLATFORM_WINDOWS if (let startDebugCmd = next as StartDebugCmd) { @@ -9892,72 +9868,6 @@ namespace IDE // Already handled (void)scriptCmd; } - else if (var cmd = next as StartCustomBuildLogicCmd) do - { - if (!mBfBuildCompiler.ValidateBuildLogic(cmd.mObject)) - { - OutputErrorLine($"Invalid Compiler.BuildLogic: {cmd.mObject}"); - ClearAndDeleteItems(mExecutionQueue); - break; - } - - ProcessCustomBuildLogicCmd process = new .(); - process.mOutput = new .(); - process.mTypeName = new .(cmd.mObject); - process.mStage = cmd.mStage; - process.mStopwatch = new .(); - - process.mThread = new .(new () => - { - mBfBuildSystem.Lock(0); - switch (process.mStage) - { - case .PreBuild: mBfBuildCompiler.ExecuteBuildLogicPreBuild(process.mTypeName, process.mOutput); - case .PostBuild: mBfBuildCompiler.ExecuteBuildLogicPostBuild(process.mTypeName, process.mOutput); - } - mBfBuildSystem.Unlock(); - }); - process.mThread.AutoDelete = false; - process.mThread.SetJoinOnDelete(true); - - process.mStopwatch.Start(); - process.mThread.Start(); - mExecutionQueue.AddFront(process); - } - else if (var cmd = next as ProcessCustomBuildLogicCmd) - { - // thread has ended - bool failed = false; - for (let line in cmd.mOutput.Split('\n', .RemoveEmptyEntries)) - { - int index = line.IndexOf('\t'); - if (index < 0) - { - OutputErrorLine($"Malformed build logic execution result: {line}"); - CancelBuild(); - continue; - } - - switch (line[.. Runtime.NotImplemented(); } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 73950313a..de5a0c89d 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -9094,7 +9094,7 @@ String BfCompiler::GetTypeDefList(bool includeLocation) return result; } -String BfCompiler::ExecuteUserDefinedMethod(BfTypeDef* typeDef, BfTypeInstance* typeInst, BfTypeDef* parentClass, const StringImpl& generatorMethodName, const StringImpl* args) +String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args) { if (typeInst == NULL) { @@ -9108,7 +9108,7 @@ String BfCompiler::ExecuteUserDefinedMethod(BfTypeDef* typeDef, BfTypeInstance* BfTypeVector typeVector; typeVector.Add(typeInst); - auto generatorTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(parentClass)->ToTypeInstance(); + auto generatorTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompilerGeneratorTypeDef)->ToTypeInstance(); auto methodDef = generatorTypeInst->mTypeDef->GetMethodByName(generatorMethodName); auto moduleMethodInstance = mContext->mUnreifiedModule->GetMethodInstance(generatorTypeInst, methodDef, typeVector); @@ -9178,7 +9178,7 @@ String BfCompiler::GetGeneratorTypeDefList() result += typeDef->mProject->mName; result += ":"; result += BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName); - String nameString = ExecuteUserDefinedMethod(typeDef, typeInst, mCompilerGeneratorTypeDef, "GetName", NULL); + String nameString = GetGeneratorString(typeDef, typeInst, "GetName", NULL); if (!nameString.IsEmpty()) result += "\t" + nameString; result += "\n"; @@ -9204,7 +9204,7 @@ String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const String String result; for (auto typeDef : typeDefs) { - result += ExecuteUserDefinedMethod(typeDef, NULL, mCompilerGeneratorTypeDef, "InitUI", &args); + result += GetGeneratorString(typeDef, NULL, "InitUI", &args); if (!result.IsEmpty()) break; } @@ -9227,7 +9227,7 @@ String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringI String result; for (auto typeDef : typeDefs) { - result += ExecuteUserDefinedMethod(typeDef, NULL, mCompilerGeneratorTypeDef, "Generate", &args); + result += GetGeneratorString(typeDef, NULL, "Generate", &args); if (!result.IsEmpty()) break; } @@ -9237,49 +9237,6 @@ String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringI return result; } -bool BfCompiler::ValidateBuildLogic(const StringImpl& typeName) -{ - BfType* type = GetType(typeName); - - BfTypeInstance* typeInst = NULL; - if (type != NULL) - typeInst = type->ToTypeInstance(); - - return ((typeInst != NULL) && - (typeInst->mBaseType != NULL) && - (typeInst->mBaseType->IsInstanceOf(mCompilerBuildLogicTypeDef))); -} - -String BfCompiler::ExecuteBuildLogicPreBuild(const StringImpl& typeName) -{ - BfResolvePassData resolvePassData; - SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); - BfPassInstance passInstance(mSystem); - SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); - - BfTypeInstance* typeInst = GetType(typeName)->ToTypeInstance(); - - String result = ExecuteUserDefinedMethod(typeInst->mTypeDef, typeInst, mCompilerBuildLogicTypeDef, "PreBuild", NULL); - - HandleGeneratorErrors(result); - return result; -} - -String BfCompiler::ExecuteBuildLogicPostBuild(const StringImpl& typeName) -{ - BfResolvePassData resolvePassData; - SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); - BfPassInstance passInstance(mSystem); - SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); - - BfTypeInstance* typeInst = GetType(typeName)->ToTypeInstance(); - - String result = ExecuteUserDefinedMethod(typeInst->mTypeDef, typeInst, mCompilerBuildLogicTypeDef, "PostBuild", NULL); - - HandleGeneratorErrors(result); - return result; -} - String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr, bool includeLocation) { String result; @@ -10738,30 +10695,6 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGeneratorGenData(BfCompiler* bfC return outString.c_str(); } -BF_EXPORT bool BF_CALLTYPE BfCompiler_ValidateBuildLogic(BfCompiler* bfCompiler, char* typeDefName) -{ - String name(typeDefName); - return bfCompiler->ValidateBuildLogic(name); -} - -BF_EXPORT const char* BF_CALLTYPE BfCompiler_ExecuteBuildLogicPreBuild(BfCompiler* bfCompiler, char* typeDefName) -{ - String name(typeDefName); - String& outString = *gTLStrReturn.Get(); - outString.clear(); - outString = bfCompiler->ExecuteBuildLogicPreBuild(name); - return outString.c_str(); -} - -BF_EXPORT const char* BF_CALLTYPE BfCompiler_ExecuteBuildLogicPostBuild(BfCompiler* bfCompiler, char* typeDefName) -{ - String name(typeDefName); - String& outString = *gTLStrReturn.Get(); - outString.clear(); - outString = bfCompiler->ExecuteBuildLogicPostBuild(name); - return outString.c_str(); -} - BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefList(BfCompiler* bfCompiler, bool includeLocation) { String& outString = *gTLStrReturn.Get(); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 845677cc8..670c12cbd 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -557,7 +557,7 @@ class BfCompiler void RequestFastFinish(); void RequestExtraCompile(); String GetTypeDefList(bool includeLocation); - String ExecuteUserDefinedMethod(BfTypeDef* typeDef, BfTypeInstance* typeInst, BfTypeDef* parentClass, const StringImpl& generatorMethodName, const StringImpl* args); + String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args); void HandleGeneratorErrors(StringImpl& result); String GetGeneratorTypeDefList(); String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args); From b26db56da44cdf89d521ab78210e67dfe111b74b Mon Sep 17 00:00:00 2001 From: Rune Date: Wed, 25 Mar 2026 16:10:03 +0100 Subject: [PATCH 11/20] remove BeefDep1_Done.txt --- BeefDep1_Done.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt deleted file mode 100644 index 8ad96f878..000000000 --- a/BeefDep1_Done.txt +++ /dev/null @@ -1 +0,0 @@ -Done \ No newline at end of file From 931e2a816a9f0e7ef37462b6678470908b9fffc1 Mon Sep 17 00:00:00 2001 From: Rune Date: Wed, 25 Mar 2026 16:54:25 +0100 Subject: [PATCH 12/20] forgor to save --- IDE/src/BuildContext.bf | 12 ------------ IDE/src/Program.bf | 4 ---- 2 files changed, 16 deletions(-) diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 01a2b353d..1044e3b47 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -185,18 +185,6 @@ namespace IDE return didCommands ? .HadCommands : .NoCommands; } - public void QueueBuildLogic(Project project, IDEApp.StartCustomBuildLogicCmd.Stage stage) - { - if (project.mBeefGlobalOptions.mBuildLogicObject.IsEmpty) - return; - - gApp.mExecutionQueue.Add(new IDEApp.StartCustomBuildLogicCmd() - { - mObject = new String(project.mBeefGlobalOptions.mBuildLogicObject), - mStage = stage, - }); - } - bool QueueProjectGNUArchive(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg) { #if BF_PLATFORM_WINDOWS diff --git a/IDE/src/Program.bf b/IDE/src/Program.bf index 4fef716fb..30c1b00da 100644 --- a/IDE/src/Program.bf +++ b/IDE/src/Program.bf @@ -64,10 +64,6 @@ namespace IDE #endif return retVal; } - - [CallingConvention(.Stdcall), CLink] - public static void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, Platform.BfpSystemResult* outResult) - => Runtime.NotImplemented(); } } From 5fdca82371dad139e0c41dda45639428214cc9a5 Mon Sep 17 00:00:00 2001 From: Rune Date: Wed, 25 Mar 2026 19:48:35 +0100 Subject: [PATCH 13/20] remove build logic but real --- BeefDep1_Done.txt | 1 + BeefLibs/corlib/src/Platform.bf | 5 ++--- IDE/src/Project.bf | 4 ---- IDE/src/ui/ProjectProperties.bf | 1 - IDEHelper/Compiler/BfCompiler.cpp | 2 -- IDEHelper/Compiler/BfCompiler.h | 4 ---- 6 files changed, 3 insertions(+), 14 deletions(-) create mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt new file mode 100644 index 000000000..8ad96f878 --- /dev/null +++ b/BeefDep1_Done.txt @@ -0,0 +1 @@ +Done \ No newline at end of file diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf index 1c0c3112f..854e257b4 100644 --- a/BeefLibs/corlib/src/Platform.bf +++ b/BeefLibs/corlib/src/Platform.bf @@ -106,9 +106,8 @@ namespace System public static extern void BfpSystem_GetExecutablePath(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); [CallingConvention(.Stdcall), CLink] public static extern void BfpSystem_GetEnvironmentStrings(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); - /*[CallingConvention(.Stdcall), CLink] - public static extern void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult);*/ - public static void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult) => Runtime.NotImplemented(); + [CallingConvention(.Stdcall), CLink] + public static extern void BfpSystem_GetEnvironmentVariable(char8* varName, char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); [CallingConvention(.Stdcall), CLink] public static extern void BfpSystem_SetEnvironmentVariable(char8* varName, char8* value, BfpSystemResult* outResult); [CallingConvention(.Stdcall), CLink] diff --git a/IDE/src/Project.bf b/IDE/src/Project.bf index 9c4bb91ff..c88b2ead8 100644 --- a/IDE/src/Project.bf +++ b/IDE/src/Project.bf @@ -1105,8 +1105,6 @@ namespace IDE [Reflect] public String mStartupObject = new String("") ~ delete _; [Reflect] - public String mBuildLogicObject = new String() ~ delete _; - [Reflect] public String mDefaultNamespace = new String() ~ delete _; [Reflect] public List mPreprocessorMacros = new List() ~ DeleteContainerAndItems!(_); @@ -1659,7 +1657,6 @@ namespace IDE data.ConditionalAdd("Version", mGeneralOptions.mVersion.mVersion); data.ConditionalAdd("TargetType", mGeneralOptions.mTargetType, GetDefaultTargetType()); data.ConditionalAdd("StartupObject", mBeefGlobalOptions.mStartupObject, IsSingleFile ? "Program" : ""); - data.ConditionalAdd("BuildLogicObject", mBeefGlobalOptions.mBuildLogicObject); var defaultNamespace = scope String(); GetSanitizedName(mProjectName, defaultNamespace, true); data.ConditionalAdd("DefaultNamespace", mBeefGlobalOptions.mDefaultNamespace, defaultNamespace); @@ -2017,7 +2014,6 @@ namespace IDE data.GetString("Version", mGeneralOptions.mVersion.mVersion); ReadStrings("Aliases", mGeneralOptions.mAliases); data.GetString("StartupObject", mBeefGlobalOptions.mStartupObject, IsSingleFile ? "Program" : ""); - data.GetString("BuildLogicObject", mBeefGlobalOptions.mBuildLogicObject); var defaultNamespace = scope String(); GetSanitizedName(mProjectName, defaultNamespace, true); data.GetString("DefaultNamespace", mBeefGlobalOptions.mDefaultNamespace, defaultNamespace); diff --git a/IDE/src/ui/ProjectProperties.bf b/IDE/src/ui/ProjectProperties.bf index 1a566beda..e221b663f 100644 --- a/IDE/src/ui/ProjectProperties.bf +++ b/IDE/src/ui/ProjectProperties.bf @@ -985,7 +985,6 @@ namespace IDE.ui category.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, 0xFFE8E8E8); AddPropertiesItem(category, "Startup Object", "mStartupObject"); - AddPropertiesItem(category, "Build Logic Object", "mBuildLogicObject"); AddPropertiesItem(category, "Default Namespace", "mDefaultNamespace"); AddPropertiesItem(category, "Preprocessor Macros", "mPreprocessorMacros"); DistinctOptionBuilder dictinctOptionBuilder = scope .(this); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index de5a0c89d..76bac3bcc 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -436,7 +436,6 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mPlatformTypeDef = NULL; mCompilerTypeDef = NULL; mCompilerGeneratorTypeDef = NULL; - mCompilerBuildLogicTypeDef = NULL; mConsoleTypeDef = NULL; mDiagnosticsDebugTypeDef = NULL; mIDisposableTypeDef = NULL; @@ -7327,7 +7326,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mPlatformTypeDef = _GetRequiredType("System.Platform"); mCompilerTypeDef = _GetRequiredType("System.Compiler"); mCompilerGeneratorTypeDef = _GetRequiredType("System.Compiler.Generator"); - mCompilerBuildLogicTypeDef = _GetRequiredType("System.Compiler.BuildLogic"); mConsoleTypeDef = _GetRequiredType("System.Console"); mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 670c12cbd..dccb55f47 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -393,7 +393,6 @@ class BfCompiler BfTypeDef* mPlatformTypeDef; BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerGeneratorTypeDef; - BfTypeDef* mCompilerBuildLogicTypeDef; BfTypeDef* mConsoleTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mIDisposableTypeDef; @@ -562,9 +561,6 @@ class BfCompiler String GetGeneratorTypeDefList(); String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args); String GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args); - bool ValidateBuildLogic(const StringImpl& typeName); - String ExecuteBuildLogicPreBuild(const StringImpl& typeName); - String ExecuteBuildLogicPostBuild(const StringImpl& typeName); String GetTypeDefMatches(const StringImpl& searchSrc, bool includeLocation); void GetTypeDefs(const StringImpl& typeName, Array& typeDefs); String GetTypeDefInfo(const StringImpl& typeName); From 89bfc97cb4ac1a37149236ac6f997b37198d54fc Mon Sep 17 00:00:00 2001 From: Rune Date: Wed, 25 Mar 2026 19:49:02 +0100 Subject: [PATCH 14/20] remove BeefDep1_Done.txt (again) --- BeefDep1_Done.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt deleted file mode 100644 index 8ad96f878..000000000 --- a/BeefDep1_Done.txt +++ /dev/null @@ -1 +0,0 @@ -Done \ No newline at end of file From c960faa8fef9ad3a223076133b95fb1461226de0 Mon Sep 17 00:00:00 2001 From: Rune Date: Thu, 26 Mar 2026 15:12:33 +0100 Subject: [PATCH 15/20] works on my machine tm --- IDE/BeefProj.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index 2cb040ecf..2b400e2ea 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -9,7 +9,6 @@ StartupObject = "IDE.Program" Beefy2D = "*" corlib = "*" curl = "*" -IDEHelper = "*" [Platform.Windows] IconFile = "$(ProjectDir)/Resources/Beef.ico" From c5fc38ff8298484b42d193dc3c8b5c3f3d61561d Mon Sep 17 00:00:00 2001 From: Rune Date: Thu, 26 Mar 2026 15:20:41 +0100 Subject: [PATCH 16/20] remove write to output --- BeefBoot/BootApp.cpp | 9 --------- IDE/src/Compiler/BfCompiler.bf | 15 --------------- IDEHelper/Compiler/BfCompiler.cpp | 6 ------ IDEHelper/Compiler/CeMachine.cpp | 2 -- IDEHelper/Compiler/CeMachine.h | 3 --- 5 files changed, 35 deletions(-) diff --git a/BeefBoot/BootApp.cpp b/BeefBoot/BootApp.cpp index d5b701d49..769956fa1 100644 --- a/BeefBoot/BootApp.cpp +++ b/BeefBoot/BootApp.cpp @@ -28,8 +28,6 @@ BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler); BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx, const char* targetTriple, const char* targetCPU, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads, Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName); -BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, - void (BF_CALLTYPE* callback)(void* userdata, char* ptr, int len)); BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(void* bfCompiler, void* userdata, void* (BF_CALLTYPE* callback)(void* userdata, char* cmd, int* outExitcode)); BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler); @@ -794,12 +792,6 @@ void BootApp::DoLinkGNU() auto runCmd = QueueRun(linkerPath, linkLine, mWorkingDir, BfpSpawnFlag_UseArgsFile); } -static void BF_CALLTYPE ComptimeWriteToOutputCallback(void* userdata, char* ptr, int len) -{ - String text(ptr, len); - gApp->OutputLine(text, OutputPri_Normal); -} - static void* BF_CALLTYPE ComptimeRunShellCommandCallback(void* userdata, char* cmd, int* outExitcode) { *outExitcode = system(cmd); @@ -829,7 +821,6 @@ bool BootApp::Compile() BfProjectFlags flags = BfProjectFlags_None; BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags); - BfCompiler_SetComptimeWriteToOutputCallback(mCompiler, NULL, ComptimeWriteToOutputCallback); BfCompiler_SetComptimeRunShellCommandCallback(mCompiler, NULL, ComptimeRunShellCommandCallback); } diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 5496e1ae0..c4b474211 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -146,11 +146,6 @@ namespace IDE.Compiler void* hotProject, int32 hotIdx, char8* targetTriple, char8* targetCPU, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads, OptionFlags optionsFlags, char8* mallocName, char8* freeName); - [CallingConvention(.Stdcall)] - public function void ComptimeWriteToOutputCallback(void* userdata, char8* ptr, int32 len); - [CallingConvention(.Stdcall), CLink] - static extern void BfCompiler_SetComptimeWriteToOutputCallback(void* bfCompiler, void* userdata, ComptimeWriteToOutputCallback callback); - [CallingConvention(.Stdcall)] public function Platform.BfpSpawn* ComptimeRunShellCommandCallback(void* userdata, char8* cmd, int32* outExitCode); [CallingConvention(.Stdcall), CLink] @@ -353,11 +348,6 @@ namespace IDE.Compiler targetTriple, targetCPU, toolsetType, simdSetting, allocStackCount, maxWorkerThreads, optionFlags, mallocFuncName, freeFuncName); } - public void SetComptimeWriteToOutputCallback(void* userdata, ComptimeWriteToOutputCallback callback) - { - BfCompiler_SetComptimeWriteToOutputCallback(mNativeBfCompiler, userdata, callback); - } - public void SetComptimeRunShellCommandCallback(void* userdata, ComptimeRunShellCommandCallback callback) { BfCompiler_SetComptimeRunShellCommandCallback(mNativeBfCompiler, userdata, callback); @@ -804,11 +794,6 @@ namespace IDE.Compiler for (let typeOption in options.mDistinctBuildOptions) mBfSystem.AddTypeOptions(typeOption); - SetComptimeWriteToOutputCallback(Internal.UnsafeCastToPtr(IDEApp.sApp), (userdata, ptr, len) => - { - IDEApp app = (.)Internal.UnsafeCastToObject(userdata); - app.Output(scope String(ptr, len)); - }); SetComptimeRunShellCommandCallback(Internal.UnsafeCastToPtr(IDEApp.sApp), (userdata, cmd, outExitCode) => { IDEApp app = (.)Internal.UnsafeCastToObject(userdata); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 76bac3bcc..b5831b532 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -11275,12 +11275,6 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje } } -BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeWriteToOutputCallback(BfCompiler* bfCompiler, void* userdata, CeWriteToOutputCallback callback) -{ - bfCompiler->mCeMachine->mWriteToOutputUserData = userdata; - bfCompiler->mCeMachine->mWriteToOutputCallback = callback; -} - BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(BfCompiler* bfCompiler, void* userdata, CeRunShellCommandCallback callback) { bfCompiler->mCeMachine->mRunShellCommandUserData = userdata; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 6ccb2646b..1534966c9 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -9728,8 +9728,6 @@ CeMachine::CeMachine(BfCompiler* compiler) mCurBuilder = NULL; mPreparingFunction = NULL; - mWriteToOutputUserData = NULL; - mWriteToOutputCallback = NULL; mRunShellCommandUserData = NULL; mRunShellCommandCallback = NULL; diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 9eb3e41f6..ed5f801ba 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -1244,7 +1244,6 @@ class CeStepState } }; -typedef void (BF_CALLTYPE* CeWriteToOutputCallback)(void* userdata, const char* ptr, int len); typedef BfpSpawn* (BF_CALLTYPE* CeRunShellCommandCallback)(void* userdata, const char* cmd, int* outExitcode); class CeMachine @@ -1275,8 +1274,6 @@ class CeMachine CeBuilder* mCurBuilder; CeFunction* mPreparingFunction; - void* mWriteToOutputUserData; - CeWriteToOutputCallback mWriteToOutputCallback; void* mRunShellCommandUserData; CeRunShellCommandCallback mRunShellCommandCallback; From 1cc7aaa9b3222c7818f42e4941542d7fb8c87376 Mon Sep 17 00:00:00 2001 From: Rune Date: Thu, 26 Mar 2026 15:34:17 +0100 Subject: [PATCH 17/20] remove BeefDep1_Done --- BeefDep1_Done.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt deleted file mode 100644 index 8ad96f878..000000000 --- a/BeefDep1_Done.txt +++ /dev/null @@ -1 +0,0 @@ -Done \ No newline at end of file From c13c7bd03a1a576020ba486fc9c5c02c8bbe2cb9 Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 30 Mar 2026 12:34:17 +0200 Subject: [PATCH 18/20] change RunCommand impl to have nothing to do with the IDE --- BeefBoot/BootApp.cpp | 11 +------- BeefDep1_Done.txt | 1 + BeefLibs/corlib/src/Console.bf | 44 +++++++++++++++++++++++++++++-- IDE/BeefProj.toml | 1 + IDE/src/Compiler/BfCompiler.bf | 17 ------------ IDEHelper/Compiler/BfCompiler.cpp | 8 ------ IDEHelper/Compiler/BfCompiler.h | 1 - IDEHelper/Compiler/CeMachine.cpp | 30 --------------------- IDEHelper/Compiler/CeMachine.h | 4 --- 9 files changed, 45 insertions(+), 72 deletions(-) create mode 100644 BeefDep1_Done.txt diff --git a/BeefBoot/BootApp.cpp b/BeefBoot/BootApp.cpp index 769956fa1..3ceb24a46 100644 --- a/BeefBoot/BootApp.cpp +++ b/BeefBoot/BootApp.cpp @@ -28,8 +28,6 @@ BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler); BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx, const char* targetTriple, const char* targetCPU, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads, Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName); -BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(void* bfCompiler, void* userdata, - void* (BF_CALLTYPE* callback)(void* userdata, char* cmd, int* outExitcode)); BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler); BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath); BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler); @@ -792,12 +790,6 @@ void BootApp::DoLinkGNU() auto runCmd = QueueRun(linkerPath, linkLine, mWorkingDir, BfpSpawnFlag_UseArgsFile); } -static void* BF_CALLTYPE ComptimeRunShellCommandCallback(void* userdata, char* cmd, int* outExitcode) -{ - *outExitcode = system(cmd); - return NULL; -} - bool BootApp::Compile() { DWORD startTick = BFTickCount(); @@ -820,8 +812,7 @@ bool BootApp::Compile() mCELibProject = BfSystem_CreateProject(mSystem, "BeefLib", GetFileDir(mTargetPath).c_str()); BfProjectFlags flags = BfProjectFlags_None; - BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags); - BfCompiler_SetComptimeRunShellCommandCallback(mCompiler, NULL, ComptimeRunShellCommandCallback); + BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, flags); } if (!mDefines.IsEmpty()) diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt new file mode 100644 index 000000000..8ad96f878 --- /dev/null +++ b/BeefDep1_Done.txt @@ -0,0 +1 @@ +Done \ No newline at end of file diff --git a/BeefLibs/corlib/src/Console.bf b/BeefLibs/corlib/src/Console.bf index dba0daad0..d47ee3c8d 100644 --- a/BeefLibs/corlib/src/Console.bf +++ b/BeefLibs/corlib/src/Console.bf @@ -2,6 +2,7 @@ using System.Text; using System.IO; using System.Threading; using System.Threading.Tasks; +using System.Diagnostics; namespace System { @@ -479,7 +480,46 @@ namespace System #endif } - [LinkName("system")] - public static extern int32 RunShellCommand(char8* command); + [CLink] + private static extern int32 system(char8* cmd); + + public static Result RunCommand(StringView command) + { + if (!Compiler.IsComptime) + { + int exitcode = system(command.ToScopeCStr!()); + return exitcode == 0 ? .Ok : .Err(exitcode); + } + + ProcessStartInfo startInfo = scope .(); + startInfo.SetFileNameAndArguments(command); + startInfo.UseShellExecute = false; + startInfo.RedirectStandardOutput = true; + startInfo.RedirectStandardError = true; + startInfo.CreateNoWindow = true; + + SpawnedProcess proc = scope .(); + if (proc.Start(startInfo) case .Err) + return .Err(0); + + FileStream output = scope .(); + FileStream error = scope .(); + StreamReader outputReader = scope .(output); + StreamReader errorReader = scope .(output); + proc.AttachStandardOutput(output); + proc.AttachStandardError(error); + + String buffer = scope .(1024); + while (!proc.HasExited) + { + outputReader.ReadToEnd(buffer).IgnoreError(); + errorReader.ReadToEnd(buffer).IgnoreError(); + if (!buffer.IsEmpty) + OutString(buffer); + } + + int exitcode = proc.ExitCode; + return exitcode == 0 ? .Ok : .Err(exitcode); + } } } diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index 2b400e2ea..2cb040ecf 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -9,6 +9,7 @@ StartupObject = "IDE.Program" Beefy2D = "*" corlib = "*" curl = "*" +IDEHelper = "*" [Platform.Windows] IconFile = "$(ProjectDir)/Resources/Beef.ico" diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index c4b474211..29b92133e 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -146,11 +146,6 @@ namespace IDE.Compiler void* hotProject, int32 hotIdx, char8* targetTriple, char8* targetCPU, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads, OptionFlags optionsFlags, char8* mallocName, char8* freeName); - [CallingConvention(.Stdcall)] - public function Platform.BfpSpawn* ComptimeRunShellCommandCallback(void* userdata, char8* cmd, int32* outExitCode); - [CallingConvention(.Stdcall), CLink] - static extern void BfCompiler_SetComptimeRunShellCommandCallback(void* bfCompiler, void* userdata, ComptimeRunShellCommandCallback callback); - [CallingConvention(.Stdcall), CLink] static extern void BfCompiler_ForceRebuild(void* bfCompiler); @@ -348,11 +343,6 @@ namespace IDE.Compiler targetTriple, targetCPU, toolsetType, simdSetting, allocStackCount, maxWorkerThreads, optionFlags, mallocFuncName, freeFuncName); } - public void SetComptimeRunShellCommandCallback(void* userdata, ComptimeRunShellCommandCallback callback) - { - BfCompiler_SetComptimeRunShellCommandCallback(mNativeBfCompiler, userdata, callback); - } - public void ForceRebuild() { BfCompiler_ForceRebuild(mNativeBfCompiler); @@ -793,13 +783,6 @@ namespace IDE.Compiler mBfSystem.AddTypeOptions(typeOption); for (let typeOption in options.mDistinctBuildOptions) mBfSystem.AddTypeOptions(typeOption); - - SetComptimeRunShellCommandCallback(Internal.UnsafeCastToPtr(IDEApp.sApp), (userdata, cmd, outExitCode) => - { - IDEApp app = (.)Internal.UnsafeCastToObject(userdata); - let inst = app.DoRun("", StringView(cmd), app.mWorkspace.mDir, .None, null, null, .ShellCommand); - return inst.mProcess.[Friend]mSpawn; - }); } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index b5831b532..89b5febf1 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -436,7 +436,6 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mPlatformTypeDef = NULL; mCompilerTypeDef = NULL; mCompilerGeneratorTypeDef = NULL; - mConsoleTypeDef = NULL; mDiagnosticsDebugTypeDef = NULL; mIDisposableTypeDef = NULL; mIIntegerTypeDef = NULL; @@ -7326,7 +7325,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mPlatformTypeDef = _GetRequiredType("System.Platform"); mCompilerTypeDef = _GetRequiredType("System.Compiler"); mCompilerGeneratorTypeDef = _GetRequiredType("System.Compiler.Generator"); - mConsoleTypeDef = _GetRequiredType("System.Console"); mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); mIIntegerTypeDef = _GetRequiredType("System.IInteger"); @@ -11275,12 +11273,6 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje } } -BF_EXPORT void BF_CALLTYPE BfCompiler_SetComptimeRunShellCommandCallback(BfCompiler* bfCompiler, void* userdata, CeRunShellCommandCallback callback) -{ - bfCompiler->mCeMachine->mRunShellCommandUserData = userdata; - bfCompiler->mCeMachine->mRunShellCommandCallback = callback; -} - BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler) { bfCompiler->mOptions.mForceRebuildIdx++; diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index dccb55f47..471fc6cba 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -393,7 +393,6 @@ class BfCompiler BfTypeDef* mPlatformTypeDef; BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerGeneratorTypeDef; - BfTypeDef* mConsoleTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIIntegerTypeDef; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 1534966c9..f7129a367 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -6160,26 +6160,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Dynamic cast check failed"); return false; } - else if (checkFunction->mFunctionKind == CeFunctionKind_Console_RunShellCommand) - { - if (mCeMachine->mRunShellCommandCallback == NULL) - { - _Fail("Console.RunShellCommand is only avaliable when building"); - } - else - { - int32 ptrVal = *(int32*)(stackPtr + 4); - char* strPtr = (char*)(ptrVal + memStart); - - int32 exitCode; - auto waitEvent = mCeMachine->mRunShellCommandCallback(mCeMachine->mRunShellCommandUserData, strPtr, &exitCode); - - if (waitEvent != NULL) - BfpSpawn_WaitFor(waitEvent, -1, &exitCode, NULL); - - *((int32*)stackPtr) = exitCode; - } - } else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite) { int32 ptrVal = *(int32*)((uint8*)stackPtr + 0); @@ -9728,9 +9708,6 @@ CeMachine::CeMachine(BfCompiler* compiler) mCurBuilder = NULL; mPreparingFunction = NULL; - mRunShellCommandUserData = NULL; - mRunShellCommandCallback = NULL; - mCurEmitContext = NULL; mAppendAllocInfo = NULL; @@ -10431,13 +10408,6 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) ceFunction->mFunctionKind = CeFunctionKind_Output; } } - else if (owner->IsInstanceOf(mCeModule->mCompiler->mConsoleTypeDef)) - { - if (methodDef->mName == "RunShellCommand") - { - ceFunction->mFunctionKind = CeFunctionKind_Console_RunShellCommand; - } - } else if (owner->IsInstanceOf(mCeModule->mCompiler->mDiagnosticsDebugTypeDef)) { if (methodDef->mName == "Write") diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index ed5f801ba..a96cc4770 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -428,7 +428,6 @@ enum CeFunctionKind CeFunctionKind_Free, CeFunctionKind_DynCheckFailed, CeFunctionKind_FatalError, - CeFunctionKind_Console_RunShellCommand, CeFunctionKind_DebugWrite, CeFunctionKind_DebugWrite_Int, CeFunctionKind_GetReflectTypeDeclById, @@ -1274,9 +1273,6 @@ class CeMachine CeBuilder* mCurBuilder; CeFunction* mPreparingFunction; - void* mRunShellCommandUserData; - CeRunShellCommandCallback mRunShellCommandCallback; - BfParser* mTempParser; BfReducer* mTempReducer; BfPassInstance* mTempPassInstance; From f1909e1f1c408c1e156bf762d4cd8e5d104f14cc Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 30 Mar 2026 12:35:17 +0200 Subject: [PATCH 19/20] remove BeefDep1_Done.txt --- BeefDep1_Done.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 BeefDep1_Done.txt diff --git a/BeefDep1_Done.txt b/BeefDep1_Done.txt deleted file mode 100644 index 8ad96f878..000000000 --- a/BeefDep1_Done.txt +++ /dev/null @@ -1 +0,0 @@ -Done \ No newline at end of file From c6968819bd07390f8b293c06352fcd9448067ec1 Mon Sep 17 00:00:00 2001 From: Rune Date: Mon, 30 Mar 2026 12:41:30 +0200 Subject: [PATCH 20/20] remove pfn from old impl --- IDEHelper/Compiler/CeMachine.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index a96cc4770..ea215c9a1 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -1243,8 +1243,6 @@ class CeStepState } }; -typedef BfpSpawn* (BF_CALLTYPE* CeRunShellCommandCallback)(void* userdata, const char* cmd, int* outExitcode); - class CeMachine { public: