feat: Add support for custom EXPORTED_RUNTIME_METHODS
This commit is contained in:
Родитель
bbb4d0b955
Коммит
0e422a7111
|
@ -153,3 +153,14 @@ Or use emscripten functions:
|
|||
```
|
||||
[DllImport("__Internal_emscripten")]
|
||||
public static extern void emscripten_console_log(string str);
|
||||
|
||||
### Exposing additional methods from emscripten
|
||||
|
||||
When interoperating with native features, such as OpenGL, it may be needed to expose additional features from emscripten.
|
||||
|
||||
The `EXPORTED_RUNTIME_METHODS` flag can be filled through the following msbuild items:
|
||||
```xml
|
||||
<ItemGroup>
|
||||
<WasmShellEmccExportedRuntimeMethod Include="GL" />
|
||||
</ItemGroup>
|
||||
```
|
|
@ -163,6 +163,8 @@ namespace Uno.Wasm.Bootstrap
|
|||
|
||||
public Microsoft.Build.Framework.ITaskItem[]? NativeCompile { get; set; }
|
||||
|
||||
public Microsoft.Build.Framework.ITaskItem[]? EmccExportedRuntimeMethods { get; set; }
|
||||
|
||||
public bool GenerateCompressedFiles { get; set; }
|
||||
|
||||
public string? DistCompressionLayoutMode { get; set; }
|
||||
|
@ -798,6 +800,9 @@ namespace Uno.Wasm.Bootstrap
|
|||
? string.Join(" ", NativeCompile.Select(f => $"\"--native-compile={AlignPath(GetFilePaths(f).fullPath)}\""))
|
||||
: "";
|
||||
|
||||
var emccExportedRuntimeMethodsParams =
|
||||
string.Join(" ", EmccExportedRuntimeMethods.Select(f => $"\"--emcc-exported-runtime-method={f.ItemSpec}\""));
|
||||
|
||||
if (_runtimeExecutionMode != RuntimeExecutionMode.Interpreter && GenerateAOTProfile)
|
||||
{
|
||||
Log.LogMessage($"Forcing Interpreter mode because GenerateAOTProfile is set");
|
||||
|
@ -814,7 +819,7 @@ namespace Uno.Wasm.Bootstrap
|
|||
|
||||
var dedupOption = !EnableAOTDeduplication ? "--no-dedup" : "";
|
||||
|
||||
var aotOptions = $"{aotMode} {dedupOption} {dynamicLibraryParams} {bitcodeFilesParams} {additionalNativeCompile} --emscripten-sdkdir=\"{emsdkPath}\" --builddir=\"{AlignPath(workAotPath)}\"";
|
||||
var aotOptions = $"{aotMode} {dedupOption} {dynamicLibraryParams} {bitcodeFilesParams} {additionalNativeCompile} {emccExportedRuntimeMethodsParams} --emscripten-sdkdir=\"{emsdkPath}\" --builddir=\"{AlignPath(workAotPath)}\"";
|
||||
|
||||
if (EnableEmccProfiling)
|
||||
{
|
||||
|
@ -1743,6 +1748,10 @@ namespace Uno.Wasm.Bootstrap
|
|||
var enablePWA = !string.IsNullOrEmpty(PWAManifestFile);
|
||||
var offlineFiles = enablePWA ? string.Join(", ", GetPWACacheableFiles().Select(f => $"\".{f}\"")) : "";
|
||||
|
||||
var emccExportedRuntimeMethodsParams = string.Join(
|
||||
",",
|
||||
EmccExportedRuntimeMethods.Select(f => $"\'{f.ItemSpec}\'"));
|
||||
|
||||
config.AppendLine($"let config = {{}};");
|
||||
config.AppendLine($"config.uno_remote_managedpath = \"{ Path.GetFileName(_managedPath) }\";");
|
||||
config.AppendLine($"config.uno_app_base = \"{WebAppBasePath}{_remoteBasePackagePath}\";");
|
||||
|
@ -1757,6 +1766,7 @@ namespace Uno.Wasm.Bootstrap
|
|||
config.AppendLine($"config.enable_pwa = {enablePWA.ToString().ToLowerInvariant()};");
|
||||
config.AppendLine($"config.offline_files = ['{WebAppBasePath}', {offlineFiles}];");
|
||||
config.AppendLine($"config.uno_shell_mode = \"{_shellMode}\";");
|
||||
config.AppendLine($"config.emcc_exported_runtime_methods = [{emccExportedRuntimeMethodsParams}];");
|
||||
|
||||
if (GenerateAOTProfile)
|
||||
{
|
||||
|
|
|
@ -206,6 +206,7 @@
|
|||
CustomLinkerPath="$(MonoRuntimeCustomLinkerPath)"
|
||||
DistCompressionLayoutMode="$(WasmShellCompressionLayoutMode)"
|
||||
DistPath="$(WasmShellDistPath)"
|
||||
EmccExportedRuntimeMethods="@(WasmShellEmccExportedRuntimeMethod)"
|
||||
EmccLinkOptimization="$(WasmShellEmccLinkOptimization)"
|
||||
EmccLinkOptimizationLevel="$(WasmShellEmccLinkOptimizationLevel)"
|
||||
EnableAOTDeduplication="$(WasmShellEnableAOTDeduplication)"
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace Uno.WebAssembly.Bootstrap {
|
|||
onConfigLoaded: this.onConfigLoaded,
|
||||
onDotnetReady: this.onDotnetReady,
|
||||
onAbort: this.onAbort,
|
||||
exports: ["IDBFS", "FS"],
|
||||
exports: ["IDBFS", "FS"].concat(this._unoConfig.emcc_exported_runtime_methods),
|
||||
downloadResource: this.onDownloadResource
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
offline_files: string[];
|
||||
|
||||
emcc_exported_runtime_methods?: string[];
|
||||
|
||||
uno_shell_mode: string;
|
||||
|
||||
environmentVariables?: {
|
||||
|
|
|
@ -446,6 +446,7 @@ class Driver {
|
|||
var native_libs = new List<string> ();
|
||||
var preload_files = new List<string> ();
|
||||
var embed_files = new List<string> ();
|
||||
var emcc_exported_runtime_methods = new List<string> ();
|
||||
var native_compile = new List<string> ();
|
||||
var pinvoke_libs = "";
|
||||
var copyTypeParm = "default";
|
||||
|
@ -515,6 +516,7 @@ class Driver {
|
|||
{ "native-lib=", s => native_libs.Add (s) },
|
||||
{ "preload-file=", s => preload_files.Add (s) },
|
||||
{ "embed-file=", s => embed_files.Add (s) },
|
||||
{ "emcc-exported-runtime-method=", s => emcc_exported_runtime_methods.Add (s) },
|
||||
{ "framework=", s => framework = s },
|
||||
{ "extra-emccflags=", s => extra_emccflags = s },
|
||||
{ "extra-linkerflags=", s => extra_linkerflags = s },
|
||||
|
@ -1095,7 +1097,29 @@ class Driver {
|
|||
emcc_link_flags.Add("-s ALLOW_MEMORY_GROWTH=1");
|
||||
emcc_link_flags.Add("-s NO_EXIT_RUNTIME=1");
|
||||
emcc_link_flags.Add("-s FORCE_FILESYSTEM=1");
|
||||
emcc_link_flags.Add("-s EXPORTED_RUNTIME_METHODS=\"[\'FS\',\'print\',\'ccall\',\'cwrap\',\'setValue\',\'getValue\',\'UTF8ToString\',\'UTF8ArrayToString\',\'FS_createPath\',\'FS_createDataFile\',\'removeRunDependency\',\'addRunDependency\',\'FS_readFile\',\'lengthBytesUTF8\',\'stringToUTF8\',\'addFunction\',\'removeFunction\',\'IDBFS\']\"");
|
||||
|
||||
emcc_exported_runtime_methods.Add("FS");
|
||||
emcc_exported_runtime_methods.Add("print");
|
||||
emcc_exported_runtime_methods.Add("ccall");
|
||||
emcc_exported_runtime_methods.Add("cwrap");
|
||||
emcc_exported_runtime_methods.Add("setValue");
|
||||
emcc_exported_runtime_methods.Add("getValue");
|
||||
emcc_exported_runtime_methods.Add("UTF8ToString");
|
||||
emcc_exported_runtime_methods.Add("UTF8ArrayToString");
|
||||
emcc_exported_runtime_methods.Add("FS_createPath");
|
||||
emcc_exported_runtime_methods.Add("FS_createDataFile");
|
||||
emcc_exported_runtime_methods.Add("removeRunDependency");
|
||||
emcc_exported_runtime_methods.Add("addRunDependency");
|
||||
emcc_exported_runtime_methods.Add("FS_readFile");
|
||||
emcc_exported_runtime_methods.Add("lengthBytesUTF8");
|
||||
emcc_exported_runtime_methods.Add("stringToUTF8");
|
||||
emcc_exported_runtime_methods.Add("addFunction");
|
||||
emcc_exported_runtime_methods.Add("removeFunction");
|
||||
emcc_exported_runtime_methods.Add("IDBFS");
|
||||
|
||||
var exports = string.Join(",", emcc_exported_runtime_methods.Distinct().Select(m => $"\'{m}\'"));
|
||||
|
||||
emcc_link_flags.Add("-s EXPORTED_RUNTIME_METHODS=\"[" + exports + "]\"");
|
||||
|
||||
// https://github.com/dotnet/runtime/blob/8a043bf7adb0fbf5e60a8dd557c98686bc0a8377/src/mono/wasm/wasm.proj#L133
|
||||
emcc_link_flags.Add("-s EXPORTED_FUNCTIONS=_malloc,stackSave,stackRestore,stackAlloc,_memalign,_memset,_htons,_ntohs,_free");
|
||||
|
|
|
@ -43,7 +43,7 @@ const path = require("path");
|
|||
else {
|
||||
console.log(`Results: ${value}`);
|
||||
}
|
||||
const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.3;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;";
|
||||
const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.3;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;";
|
||||
if (value !== expected) {
|
||||
console.log(`Invalid results got ${value}, expected ${expected}`);
|
||||
process.exit(1);
|
||||
|
|
|
@ -42,7 +42,7 @@ const path = require("path");
|
|||
console.log(`Results: ${value}`);
|
||||
}
|
||||
|
||||
const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.3;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;";
|
||||
const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.3;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;";
|
||||
|
||||
if (value !== expected) {
|
||||
console.log(`Invalid results got ${value}, expected ${expected}`);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ItemGroup Condition="'$(UseAOT)'=='true' or '$(WasmShellGenerateAOTProfile)'=='true'">
|
||||
<Content Include="$(MSBuildThisFileDirectory)native/**/*.bc" />
|
||||
<WasmShellNativeCompile Include="$(MSBuildThisFileDirectory)test.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WasmShellEmccExportedRuntimeMethod Include="GL" />
|
||||
|
||||
<!-- Based on https://github.com/dotnet/runtime/issues/76077#issuecomment-1260231545 -->
|
||||
<WasmShellExtraEmccFlags Include="-s LEGACY_GL_EMULATION=1" />
|
||||
<WasmShellExtraEmccFlags Include="-s USE_CLOSURE_COMPILER=1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -50,6 +50,9 @@ namespace Uno.Wasm.Sample
|
|||
var requireAvailable = Runtime.InvokeJS($"typeof require.config !== 'undefined'");
|
||||
Console.WriteLine($"requireAvailable: {idbFSValidation}");
|
||||
|
||||
var glAvailable = Runtime.InvokeJS($"typeof GL !== 'undefined'");
|
||||
Console.WriteLine($"glAvailable: {glAvailable}");
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
var jsInteropResult = Imports.TestCallback();
|
||||
#else
|
||||
|
@ -93,7 +96,8 @@ namespace Uno.Wasm.Sample
|
|||
$"{chmodRes};" +
|
||||
$"{additionalNativeAdd};" +
|
||||
$"requireJs:{requireAvailable};" +
|
||||
$"jsInterop:{jsInteropResult};"
|
||||
$"jsInterop:{jsInteropResult};" +
|
||||
$"gl:{glAvailable};"
|
||||
;
|
||||
|
||||
var r = Runtime.InvokeJS($"Interop.appendResult(\"{res}\")");
|
||||
|
|
|
@ -34,7 +34,15 @@
|
|||
<Content Include="$(MSBuildThisFileDirectory)native/**/*.bc" />
|
||||
<WasmShellNativeCompile Include="$(MSBuildThisFileDirectory)test.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WasmShellEmccExportedRuntimeMethod Include="GL" />
|
||||
<WasmShellExtraEmccFlags Include="-s LEGACY_GL_EMULATION=1" />
|
||||
<WasmShellExtraEmccFlags Include="-s USE_CLOSURE_COMPILER=1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)native\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Common.props" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,6 +1,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#define WASM_EXPORT __attribute__((visibility("default")))
|
||||
|
||||
|
@ -12,3 +15,9 @@ WASM_EXPORT int additional_native_add(int a, int b) {
|
|||
printf("additional_native_add(%d, %d)\r\n", a, b);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
WASM_EXPORT int test_gl() {
|
||||
GLuint programObject;
|
||||
glGetString(GL_VENDOR);
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче