Browse Source

Wasm improvements

Brian Fiete 3 năm trước cách đây
mục cha
commit
0e579d07b9

+ 94 - 60
IDE/src/BuildContext.bf

@@ -235,6 +235,8 @@ namespace IDE
 			}
 			arCmds.AppendF("SAVE\n");
 
+			UpdateCacheStr(project, "", workspaceOptions, options, null, null);
+
 		    if (project.mNeedsTargetRebuild)
 		    {
 		        if (File.Delete(targetPath) case .Err)
@@ -468,6 +470,8 @@ namespace IDE
 			        }
 				}
 
+				UpdateCacheStr(project, linkLine, workspaceOptions, options, depPaths, libPaths);
+
 			    if (project.mNeedsTargetRebuild)
 			    {
 			        if (File.Delete(targetPath) case .Err)
@@ -596,6 +600,8 @@ namespace IDE
 					IDEUtils.AppendWithOptionalQuotes(linkLine, libPath);
 					linkLine.Append(" ");
 				}
+
+				UpdateCacheStr(project, linkLine, workspaceOptions, options, depPaths, libPaths);
 				
 			    if (project.mNeedsTargetRebuild)
 			    {
@@ -621,32 +627,40 @@ namespace IDE
 #else
 					String llvmDir = "";					
 #endif
-					if (!gApp.mSettings.mEmscriptenPath.IsEmpty)
+					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("/");
 					}
-					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(" ", gApp.mInstallDir);
-					linkLine.Append("..\\..\\wasm\\BeefRT.a -s STRICT=1 -s USE_PTHREADS=1 -s ASSERTIONS=0 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=0 -s WASM=1");
 
-					String workingDir = scope String();
-					if (!llvmDir.IsEmpty)
-					{
-						workingDir.Append(llvmDir, "bin");
-					}
-					else
+					if (!File.Exists(scope $"{gApp.mInstallDir}/Beef{IDEApp.sRTVersionStr}RT32_wasm.a"))
 					{
-						workingDir.Append(gApp.mInstallDir);
+						gApp.OutputErrorLine("Wasm runtime libraries not found. Build with bin/build_wasm.bat.");
+						return false;
 					}
 
-					linkLine.Replace('\\', '/');
+					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 -s WASM=1");
 
-					//linkLine.Append(" --no-entry --export-all");
+					if (project.mWasmOptions.mEnableThreads)
+						linkLine.Append(" -s USE_PTHREADS=1");
 
-			        var runCmd = gApp.QueueRun(compilerExePath, linkLine, workingDir, .UTF8);
+					if (workspaceOptions.mEmitDebugInfo != .No)
+						linkLine.Append(" -g");
+
+					if (workspaceOptions.mRuntimeChecks)
+						linkLine.Append(" -s ASSERTIONS=1");
+
+					linkLine.Replace('\\', '/');
+
+			        var runCmd = gApp.QueueRun(compilerExePath, linkLine, project.mProjectDir, .UTF8);
 			        runCmd.mOnlyIfNotFailed = true;
 			        var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
 			        tagetCompletedCmd.mOnlyIfNotFailed = true;
@@ -845,6 +859,67 @@ namespace IDE
 			}
 		}
 
+		void UpdateCacheStr(Project project, StringView linkLine, Workspace.Options workspaceOptions, Project.Options options, List<String> depPaths, List<String> libPaths)
+		{
+			String cacheStr = scope String();
+
+			void AddBuildFileDependency(StringView filePath, bool resolveString = false)
+			{
+				var filePath;
+
+				if ((resolveString) && (filePath.Contains('$')))
+				{
+					String resolvedFilePath = scope:: String();
+					gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, filePath, "link flags", resolvedFilePath);
+					filePath = resolvedFilePath;
+				}
+
+				int64 fileTime = 0;
+				if (!filePath.IsEmpty)
+					fileTime = File.GetLastWriteTime(filePath).GetValueOrDefault().ToFileTime();
+				cacheStr.AppendF("{}\t{}\n", filePath, fileTime);
+			}
+
+			cacheStr.AppendF("Args\t{}\n", linkLine);
+			cacheStr.AppendF("Toolset\t{}\n", workspaceOptions.mToolsetType);
+			AddBuildFileDependency(project.mWindowsOptions.mIconFile);
+			AddBuildFileDependency(project.mWindowsOptions.mManifestFile);
+
+			switch (mPlatformType)
+			{
+			case .Windows:
+				cacheStr.AppendF("Description\t{}\n", project.mWindowsOptions.mDescription);
+				cacheStr.AppendF("Comments\t{}\n", project.mWindowsOptions.mComments);
+				cacheStr.AppendF("Company\t{}\n", project.mWindowsOptions.mCompany);
+				cacheStr.AppendF("Product\t{}\n", project.mWindowsOptions.mProduct);
+				cacheStr.AppendF("Copyright\t{}\n", project.mWindowsOptions.mCopyright);
+				cacheStr.AppendF("FileVersion\t{}\n", project.mWindowsOptions.mFileVersion);
+				cacheStr.AppendF("ProductVersion\t{}\n", project.mWindowsOptions.mProductVersion);
+			case .Linux:
+				cacheStr.AppendF("Options\t{}\n", project.mLinuxOptions.mOptions);
+			case .Wasm:
+				cacheStr.AppendF("EnableThreads\t{}\n", project.mWasmOptions.mEnableThreads);
+			default:
+			}
+			if (depPaths != null)
+				for (var linkDep in depPaths)
+					AddBuildFileDependency(linkDep, true);
+			if (libPaths != null)
+				for (var linkDep in libPaths)
+					AddBuildFileDependency(linkDep, true);
+
+			String projectBuildDir = scope String();
+			gApp.GetProjectBuildDir(project, projectBuildDir);
+			String prevCacheStr = scope .();
+			gApp.mBfBuildCompiler.GetBuildValue(projectBuildDir, "Link", prevCacheStr);
+			if (prevCacheStr != cacheStr)
+			{
+				project.mNeedsTargetRebuild = true;
+				gApp.mBfBuildCompiler.SetBuildValue(projectBuildDir, "Link", cacheStr);
+				gApp.mBfBuildCompiler.WriteBuildCache(projectBuildDir);
+			}
+		}
+
 		bool QueueProjectMSLink(Project project, String targetPath, String configName, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
 		{
 			bool is64Bit = mPtrSize == 8;
@@ -1006,54 +1081,13 @@ namespace IDE
 
 				let winOptions = project.mWindowsOptions;
 
-				String cacheStr = scope String();
-
-				void AddBuildFileDependency(StringView filePath, bool resolveString = false)
-				{
-					var filePath;
-
-					if ((resolveString) && (filePath.Contains('$')))
-					{
-						String resolvedFilePath = scope:: String();
-						gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, filePath, "link flags", resolvedFilePath);
-						filePath = resolvedFilePath;
-					}
-
-					int64 fileTime = 0;
-					if (!filePath.IsEmpty)
-						fileTime = File.GetLastWriteTime(filePath).GetValueOrDefault().ToFileTime();
-					cacheStr.AppendF("{}\t{}\n", filePath, fileTime);
-				}
-
-				cacheStr.AppendF("Args\t{}\n", linkLine);
-				cacheStr.AppendF("Toolset\t{}\n", workspaceOptions.mToolsetType);
-				AddBuildFileDependency(project.mWindowsOptions.mIconFile);
-				AddBuildFileDependency(project.mWindowsOptions.mManifestFile);
-				cacheStr.AppendF("Description\t{}\n", project.mWindowsOptions.mDescription);
-				cacheStr.AppendF("Comments\t{}\n", project.mWindowsOptions.mComments);
-				cacheStr.AppendF("Company\t{}\n", project.mWindowsOptions.mCompany);
-				cacheStr.AppendF("Product\t{}\n", project.mWindowsOptions.mProduct);
-				cacheStr.AppendF("Copyright\t{}\n", project.mWindowsOptions.mCopyright);
-				cacheStr.AppendF("FileVersion\t{}\n", project.mWindowsOptions.mFileVersion);
-				cacheStr.AppendF("ProductVersion\t{}\n", project.mWindowsOptions.mProductVersion);
-				for (var linkDep in depPaths)
-					AddBuildFileDependency(linkDep, true);
-				for (var linkDep in libPaths)
-					AddBuildFileDependency(linkDep, true);
-
-				String projectBuildDir = scope String();
-				gApp.GetProjectBuildDir(project, projectBuildDir);
-				String prevCacheStr = scope .();
-				gApp.mBfBuildCompiler.GetBuildValue(projectBuildDir, "Link", prevCacheStr);
-				if (prevCacheStr != cacheStr)
-				{
-					project.mNeedsTargetRebuild = true;
-					gApp.mBfBuildCompiler.SetBuildValue(projectBuildDir, "Link", cacheStr);
-					gApp.mBfBuildCompiler.WriteBuildCache(projectBuildDir);
-				}
+				UpdateCacheStr(project, linkLine, workspaceOptions, options, depPaths, libPaths);
 
 				if (project.mNeedsTargetRebuild)
 				{
+					String projectBuildDir = scope String();
+					gApp.GetProjectBuildDir(project, projectBuildDir);
+
 					if ((!String.IsNullOrWhiteSpace(project.mWindowsOptions.mIconFile)) ||
 						(!String.IsNullOrWhiteSpace(project.mWindowsOptions.mManifestFile)) ||
 		                (winOptions.HasVersionInfo()))

+ 2 - 2
IDE/src/IDEApp.bf

@@ -9662,10 +9662,10 @@ namespace IDE
 									case .Linux:
 										newString.AppendF("./{} -lpthread -ldl -Wl,-rpath -Wl,$ORIGIN", rtName);
 									case .Wasm:
-										/*newString.Append(mInstallDir);
+										newString.Append(mInstallDir);
 										newString.Append("Beef", IDEApp.sRTVersionStr, "RT");
 										newString.Append((Workspace.PlatformType.GetPtrSizeByName(gApp.mPlatformName) == 4) ? "32" : "64");
-										newString.Append("_wasm.lib");*/
+										newString.Append("_wasm.a");
 									default:
 									}	
 

+ 31 - 3
IDE/src/Project.bf

@@ -1058,6 +1058,22 @@ namespace IDE
 			}
 		}
 
+		public class WasmOptions
+		{
+			[Reflect]
+			public bool mEnableThreads = true;
+
+			public void Deserialize(StructuredData data)
+			{
+				mEnableThreads = data.GetBool("EnableThreads", true);
+			}
+
+			public void Serialize(StructuredData data)
+			{
+				data.ConditionalAdd("EnableThreads", mEnableThreads, true);
+			}
+		}
+
         public class GeneralOptions
         {
 			[Reflect]
@@ -1338,6 +1354,7 @@ namespace IDE
 		// Platform-dependent options
 		public WindowsOptions mWindowsOptions = new WindowsOptions() ~ delete _;
 		public LinuxOptions mLinuxOptions = new LinuxOptions() ~ delete _;
+		public WasmOptions mWasmOptions = new WasmOptions() ~ delete _;
 
         public List<Dependency> mDependencies = new List<Dependency>() ~ DeleteContainerAndItems!(_);
 		public bool mLastDidBuild;
@@ -1625,6 +1642,12 @@ namespace IDE
 					data.RemoveIfEmpty();
 				}
 
+				using (data.CreateObject("Wasm"))
+				{
+				    mWasmOptions.Serialize(data);
+					data.RemoveIfEmpty();
+				}
+
 				data.RemoveIfEmpty();
 			}
 
@@ -1655,7 +1678,8 @@ namespace IDE
 								{
 								case .Linux,
 									 .Windows,
-									 .macOS:
+									 .macOS,
+									 .Wasm:
 									defaultBuildKind = isTest ? .Test : .Normal;
 								default:
 									defaultBuildKind = .StaticLib;
@@ -1942,6 +1966,8 @@ namespace IDE
 					mWindowsOptions.Deserialize(data);
 				using (data.Open("Linux"))
 					mLinuxOptions.Deserialize(data);
+				using (data.Open("Wasm"))
+					mWasmOptions.Deserialize(data);
 			}
 
 			if (!data.Contains("Dependencies"))
@@ -2009,7 +2035,8 @@ namespace IDE
 					{
 					case .Linux,
 						 .Windows,
-						 .macOS:
+						 .macOS,
+						 .Wasm:
 						defaultBuildKind = isTest ? .Test : .Normal;
 					default:
 						defaultBuildKind = .StaticLib;
@@ -2410,7 +2437,8 @@ namespace IDE
 			{
 			case .Linux,
 				 .Windows,
-				 .macOS:
+				 .macOS,
+				 .Wasm:
 				options.mBuildOptions.mBuildKind = isTest ? .Test : .Normal;
 			default:
 				options.mBuildOptions.mBuildKind = .StaticLib;

+ 13 - 0
IDE/src/ui/ProjectProperties.bf

@@ -507,6 +507,7 @@ namespace IDE.ui
 					{
 					case .Windows: mCurPropertiesTargets[0] = mProject.mWindowsOptions;
 					case .Linux: mCurPropertiesTargets[0] = mProject.mLinuxOptions;
+					case .Wasm: mCurPropertiesTargets[0] = mProject.mWasmOptions;
 					default:
 					}
 				}
@@ -594,6 +595,7 @@ namespace IDE.ui
 						{
 						case .Windows: PopulateWindowsOptions();
 						case .Linux: PopulateLinuxOptions();
+						case .Wasm: PopulateWasmOptions();
 						default:
 						}
 					}
@@ -661,6 +663,17 @@ namespace IDE.ui
 		    category.Open(true, true);
 		}
 
+		void PopulateWasmOptions()
+		{
+		    var root = (DarkListViewItem)mPropPage.mPropertiesListView.GetRoot();
+		    var (category, ?) = AddPropertiesItem(root, "General");
+		    category.mIsBold = true;
+		    category.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, 0xFFE8E8E8);
+			AddPropertiesItem(category, "Enable Threads", "mEnableThreads");
+		    //parent.MakeParent();
+		    category.Open(true, true);
+		}
+
 		void PopulateBuildOptions()
 		{
 		    var root = (DarkListViewItem)mPropPage.mPropertiesListView.GetRoot();

+ 16 - 0
IDE/src/ui/SettingsDialog.bf

@@ -17,6 +17,7 @@ namespace IDE.ui
 			Compiler,
 		    Debugger,
 		    VisualStudio,
+			Wasm,
 
 		    COUNT
 		}
@@ -60,6 +61,7 @@ namespace IDE.ui
 			AddCategoryItem(root, "Compiler");
 		    AddCategoryItem(root, "Debugger");
 			AddCategoryItem(root, "Visual Studio");
+			AddCategoryItem(root, "Wasm");
 
 			if (!gApp.mSettings.mVSSettings.IsConfigured())
 				gApp.mSettings.mVSSettings.SetDefaults();
@@ -145,6 +147,18 @@ namespace IDE.ui
 			category.Open(true, true);
 		}
 
+		void PopulateWasmOptions()
+		{
+			mCurPropertiesTarget = gApp.mSettings;
+
+			var root = (DarkListViewItem)mPropPage.mPropertiesListView.GetRoot();
+			var (category, propEntry) = AddPropertiesItem(root, "General");
+			category.mIsBold = true;
+			category.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, cHeaderColor);
+			AddPropertiesItem(category, "Emscripten Path", "mEmscriptenPath", null, .BrowseForFolder);
+			category.Open(true, true);
+		}
+
 		void CommandContextToString(IDECommand.ContextFlags contextFlags, String str)
 		{
 			bool isFirst = true;
@@ -376,6 +390,8 @@ namespace IDE.ui
 					PopulateDebuggerOptions();
 				case .VisualStudio:
 					PopulateVSOptions();
+				case .Wasm:
+					PopulateWasmOptions();
 				default:
 					/*mCurPropertiesTarget = gApp.mSettings.mEditorSettings;
 					PopulateEditorOptions();*/

+ 13 - 1
bin/build_wasm.bat

@@ -1,4 +1,16 @@
 mkdir ..\wasm
 cd ..\wasm
 call emcc ..\BeefRT\rt\Math.cpp ..\BeefRT\rt\Object.cpp ..\BeefRT\rt\Thread.cpp ..\BeefRT\rt\Internal.cpp ..\BeefySysLib\platform\wasm\WasmCommon.cpp ..\BeefySysLib\Common.cpp ..\BeefySysLib\util\String.cpp ..\BeefySysLib\util\UTF8.cpp ..\BeefySysLib\third_party\utf8proc\utf8proc.c -I..\ -I..\BeefySysLib -I..\BeefySysLib\platform\wasm -g -DBF_DISABLE_FFI -c -s WASM=1 -s USE_PTHREADS=1
-emar r BeefRT.a Common.o Internal.o Math.o Object.o String.o Thread.o UTF8.o utf8proc.o WasmCommon.o
+@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
+call emar r ..\IDE\dist\Beef042RT32_wasm.a Common.o Internal.o Math.o Object.o String.o Thread.o UTF8.o utf8proc.o WasmCommon.o
+@IF %ERRORLEVEL% NEQ 0 GOTO HADERROR
+
+:SUCCESS
+@ECHO SUCCESS!
+@POPD
+@EXIT /b 0
+
+:HADERROR
+@ECHO =================FAILED=================
+@POPD
+@EXIT /b %ERRORLEVEL%