diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 6659e1b2..c02a14db 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -6,6 +6,7 @@ using System.Diagnostics; using Beefy; using IDE.util; using IDE.Util; +using Beefy.theme.dark; namespace IDE { @@ -680,7 +681,9 @@ namespace IDE } UpdateCacheStr(project, linkLine, workspaceOptions, options, depPaths, libPaths); - + + String emsdkPath = scope .(gApp.mSettings.mEmscriptenPath); + if (project.mNeedsTargetRebuild) { if (File.Delete(targetPath) case .Err) @@ -692,25 +695,67 @@ namespace IDE String compilerExePath = scope String(); if (gApp.mSettings.mEmscriptenPath.IsEmpty) { - gApp.OutputErrorLine("Emscripten path not configured. Check Wasm configuration in File\\Preferences\\Settings."); - return false; - } - else - { - compilerExePath.Append(gApp.mSettings.mEmscriptenPath); - if ((!compilerExePath.EndsWith('\\')) && (!compilerExePath.EndsWith('/'))) - compilerExePath.Append("/"); - } + // Set for auto-install without prompting + gApp.mSettings.mEmscriptenPendingInstall = true; - if (!File.Exists(scope $"{gApp.mInstallDir}/Beef{IDEApp.sRTVersionStr}RT32_wasm.a")) - { - gApp.OutputErrorLine("Wasm runtime libraries not found. Build with 'wasm/build_wasm.bat'."); +#if CLI + gApp.Fail("Emscripten path not configured. Check Wasm configuration in File\\Preferences\\Settings."); return false; +#else + if (gApp.mSettings.mEmscriptenPendingInstall) + { + String wasmPath = Path.GetAbsolutePath("../../wasm", gApp.mInstallDir, .. scope .()); + IDEUtils.FixFilePath(wasmPath); + + var runCmd = gApp.QueueRun(scope $"{wasmPath}/fetch_wasm.bat", "", wasmPath, .UTF8); + runCmd.mOnlyIfNotFailed = true; + + var installedCmd = new IDEApp.EmsdkInstalledCmd(); + installedCmd.mPath = new $"{wasmPath}/emsdk"; + IDEUtils.FixFilePath(installedCmd.mPath); + installedCmd.mOnlyIfNotFailed = true; + gApp.mExecutionQueue.Add(installedCmd); + + emsdkPath.Set(installedCmd.mPath); + } + else + { + DarkDialog dlg = new DarkDialog("Install Emscripten", "Beef uses Emscripten for WASM support. Would you like to have that installed or would you like to set it up yourself?", DarkTheme.sDarkTheme.mIconError); + dlg.mWindowFlags |= .Modal; + dlg.AddOkCancelButtons(new (dlg) => + { + gApp.mSettings.mEmscriptenPendingInstall = true; + gApp.[Friend]Compile(); + }, + new (dlg) => + { + gApp.OutputErrorLine("Emscripten path not configured. Check Wasm configuration in File\\Preferences\\Settings."); + }); + ((DarkButton)dlg.mButtons[0]).Label = "Install"; + ((DarkButton)dlg.mButtons[1]).Label = "Cancel"; + dlg.PopupWindow(gApp.GetActiveWindow()); + IDEApp.Beep(.Error); + return false; + } +#endif + } + + compilerExePath.Append(emsdkPath); + if ((!compilerExePath.EndsWith('\\')) && (!compilerExePath.EndsWith('/'))) + compilerExePath.Append("/"); + + if (!gApp.mSettings.mEmscriptenPendingInstall) + { + if (!File.Exists(scope $"{gApp.mInstallDir}/Beef{IDEApp.sRTVersionStr}RT32_wasm.a")) + { + gApp.OutputErrorLine("Wasm runtime libraries not found. Build with 'wasm/build_wasm.bat'."); + return false; + } } compilerExePath.Append(@"/upstream/emscripten/emcc.bat"); //linkLine.Append(" c:\\Beef\\wasm\\BeefRT.a -s STRICT=1 -s USE_PTHREADS=1 -s ALIASING_FUNCTION_POINTERS=1 -s ASSERTIONS=0 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=0 -s EVAL_CTORS=1 -s WASM=1 -s \"EXPORTED_FUNCTIONS=['_BeefMain','_BeefDone','_pthread_mutexattr_init','_pthread_mutex_init','_emscripten_futex_wake','_calloc','_sbrk']\""); - linkLine.Append("-s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=0"); + linkLine.Append("-s DISABLE_EXCEPTION_CATCHING=0"); if (project.mWasmOptions.mEnableThreads) linkLine.Append(" -pthread"); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 97c3f218..83b14379 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -394,6 +394,11 @@ namespace IDE public String mPath ~ delete _; } + public class EmsdkInstalledCmd : ExecutionCmd + { + public String mPath ~ delete _; + } + public class BuildCompletedCmd : ExecutionCmd { public Stopwatch mStopwatch ~ delete _; @@ -9520,6 +9525,11 @@ namespace IDE delete filePath; }); } + else if (var emsdkCmd = next as EmsdkInstalledCmd) + { + gApp.mSettings.mEmscriptenPath.Set(emsdkCmd.mPath); + gApp.mSettings.Save(); + } else { Runtime.FatalError("Unknown command"); diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index 7fc911c7..934543e2 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -1124,6 +1124,7 @@ namespace IDE public bool mAlwaysEnableConsole; public bool mKeepNativeConsoleOpen; public String mEmscriptenPath = new .() ~ delete _; + public bool mEmscriptenPendingInstall; public bool mEnableDevMode; public TutorialsFinished mTutorialsFinished = .(); diff --git a/wasm/fetch_wasm.bat b/wasm/fetch_wasm.bat new file mode 100644 index 00000000..0f92ce21 --- /dev/null +++ b/wasm/fetch_wasm.bat @@ -0,0 +1,21 @@ +@ECHO OFF + +@ECHO Downloading Emscripten... +..\bin\curl.exe -O https://www.beeflang.org/EmsdkDep0.zip +@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR +@ECHO Extracting Emscripten... +cd .. +bin\tar.exe -xf wasm\EmsdkDep0.zip +@IF %ERRORLEVEL% NEQ 0 GOTO +del wasm\EmsdkDep0.zip +@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR + +:SUCCESS +@ECHO Emscripten Installed! +@POPD +@EXIT /b 0 + +:HADERROR +@ECHO =================FAILED================= +@POPD +@EXIT /b %ERRORLEVEL%