diff --git a/eng/Versions.props b/eng/Versions.props index 63046ad9113c7..e0a4ab7d12662 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -162,7 +162,7 @@ 2.0.4 4.12.0 2.14.3 - 6.0.100-preview.7.21362.5 + 6.0.100-preview.7.21372.19 5.0.0-preview-20201009.2 diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 306cc52e98707..85d301885db2f 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -18,6 +18,7 @@ + _InitializeCommonProperties; _PrepareForWasmBuildNativeOnly; _WasmBuildNativeCore; @@ -38,13 +39,14 @@ + + <_WasmAssembliesInternal Remove="@(_WasmAssembliesInternal)" /> <_WasmAssembliesInternal Include="@(WasmAssembliesToBundle->Distinct())" /> - <_EMSDKMissingPaths Condition="'$(_EMSDKMissingPaths)' == '' and ('$(EmscriptenSdkToolsPath)' == '' or !Exists('$(EmscriptenSdkToolsPath)'))">%24(EmscriptenSdkToolsPath)=$(EmscriptenSdkToolsPath) @@ -115,8 +117,9 @@ true - false - true + true + false + true false @@ -152,7 +155,11 @@ <_EmccOptimizationFlagDefault Condition="'$(_EmccOptimizationFlagDefault)' == ''">-Oz $(_EmccOptimizationFlagDefault) - -O0 -s ASSERTIONS=$(_EmccAssertionLevelDefault) + $(EmccCompileOptimizationFlag) + + <_EmccCompileRsp>$(_WasmIntermediateOutputPath)emcc-compile.rsp + <_EmccCompileOutputMessageImportance Condition="'$(EmccVerbose)' == 'true'">Normal + <_EmccCompileOutputMessageImportance Condition="'$(EmccVerbose)' != 'true'">Low @@ -161,15 +168,42 @@ <_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" /> <_EmccCommonFlags Include="-g" Condition="'$(WasmNativeStrip)' == 'false'" /> <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> + + <_EmccIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" /> + <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" /> + <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)wasm" /> + + + <_EmccCFlags Include="$(EmccCompileOptimizationFlag)" /> + <_EmccCFlags Include="@(_EmccCommonFlags)" /> + + <_EmccCFlags Include="-DENABLE_AOT=1" Condition="'$(RunAOTCompilation)' == 'true'" /> + <_EmccCFlags Include="-DDRIVER_GEN=1" Condition="'$(RunAOTCompilation)' == 'true'" /> + <_EmccCFlags Include="-DINVARIANT_GLOBALIZATION=1" Condition="'$(InvariantGlobalization)' == 'true'" /> + <_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" /> + <_EmccCFlags Include="-DCORE_BINDINGS" /> + <_EmccCFlags Include="-DGEN_PINVOKE=1" /> + <_EmccCFlags Include="-emit-llvm" /> + + <_EmccCFlags Include=""-I%(_EmccIncludePaths.Identity)"" /> + <_EmccCFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> + + <_EmccCFlags Include="$(EmccExtraCFlags)" /> + + <_WasmRuntimePackSrcFile Include="$(_WasmRuntimePackSrcDir)*.c" /> + <_WasmRuntimePackSrcFile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" /> + + <_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" /> + <_WasmNativeFileForLinking Include="@(NativeFileReference)" /> - - <_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" /> - + + <_WasmPInvokeModules Include="%(_WasmNativeFileForLinking.FileName)" Condition="'%(_WasmNativeFileForLinking.ScanForPInvokes)' != 'false'" /> + <_WasmPInvokeModules Include="libSystem.Native" /> <_WasmPInvokeModules Include="libSystem.IO.Compression.Native" /> <_WasmPInvokeModules Include="libSystem.Globalization.Native" /> @@ -194,38 +228,13 @@ - <_EmccIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" /> - <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" /> - <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)wasm" /> - - - <_EmccCFlags Include="$(EmccCompileOptimizationFlag)" /> - <_EmccCFlags Include="@(_EmccCommonFlags)" /> - - <_EmccCFlags Include="-DENABLE_AOT=1" Condition="'$(RunAOTCompilation)' == 'true'" /> - <_EmccCFlags Include="-DDRIVER_GEN=1" Condition="'$(RunAOTCompilation)' == 'true'" /> - <_EmccCFlags Include="-DINVARIANT_GLOBALIZATION=1" Condition="'$(InvariantGlobalization)' == 'true'" /> - <_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" /> - <_EmccCFlags Include="-DCORE_BINDINGS" /> - <_EmccCFlags Include="-DGEN_PINVOKE=1" /> - <_EmccCFlags Include="-emit-llvm" /> - - <_EmccCFlags Include=""-I%(_EmccIncludePaths.Identity)"" /> - <_EmccCFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" /> - <_EmccCFlags Include="-s EXPORTED_FUNCTIONS='[@(_ExportedFunctions->'"%(Identity)"', ',')]'" Condition="@(_ExportedFunctions->Count()) > 0" /> - - <_EmccCFlags Include="$(EmccExtraCFlags)" /> - - <_WasmRuntimePackSrcFile Remove="@(_WasmRuntimePackSrcFile)" /> - <_WasmRuntimePackSrcFile Include="$(_WasmRuntimePackSrcDir)\*.c" /> - <_WasmRuntimePackSrcFile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" /> + <_WasmSourceFileToCompile Remove="@(_WasmSourceFileToCompile)" /> <_WasmSourceFileToCompile Include="@(_WasmRuntimePackSrcFile)" /> <_EmBuilder Condition="$([MSBuild]::IsOSPlatform('WINDOWS'))">embuilder.bat <_EmBuilder Condition="!$([MSBuild]::IsOSPlatform('WINDOWS'))">embuilder.py - <_EmccCompileRsp>$(_WasmIntermediateOutputPath)emcc-compile.rsp @@ -234,7 +243,15 @@ - + + + + + @@ -259,8 +276,9 @@ + Arguments=""@$(_EmccDefaultFlagsRsp)" @(_EmccLDFlags, ' ')" + EnvironmentVariables="@(EmscriptenEnvVars)" + OutputMessageImportance="$(_EmccCompileOutputMessageImportance)" /> @@ -271,6 +289,8 @@ Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)\*.a" Exclude="@(_MonoRuntimeComponentDontLink->'$(MicrosoftNetCoreAppRuntimePackRidNativeDir)\%(Identity)')" /> + <_WasmExtraJSFile Include="@(Content)" Condition="'%(Content.Extension)' == '.js'" /> + <_EmccLinkStepArgs Include="@(_EmccLDFlags)" /> <_EmccLinkStepArgs Include="--js-library "%(_DotnetJSSrcFile.Identity)"" /> <_EmccLinkStepArgs Include="--js-library "%(_WasmExtraJSFile.Identity)"" Condition="'%(_WasmExtraJSFile.Kind)' == 'js-library'" /> @@ -483,6 +503,5 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ - - + diff --git a/src/mono/wasm/build/WasmApp.props b/src/mono/wasm/build/WasmApp.props index 10b939d6da73c..bc45a6d54d73d 100644 --- a/src/mono/wasm/build/WasmApp.props +++ b/src/mono/wasm/build/WasmApp.props @@ -7,6 +7,7 @@ Publish + _InitializeCommonProperties; _BeforeWasmBuildApp; _WasmResolveReferences; _WasmAotCompileApp; diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 10bd9ac7973c5..534caf9025bf1 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -80,6 +80,9 @@ false + + + <_WasmIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm')) <_BeforeWasmBuildAppDependsOn /> @@ -90,7 +93,7 @@ - + @@ -100,11 +103,12 @@ $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir))) $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir), 'native')) - <_WasmRuntimePackIncludeDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'include')) <_WasmRuntimePackSrcDir>$([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'src')) + + @@ -115,8 +119,6 @@ $(TargetFileName) $([MSBuild]::NormalizeDirectory($(WasmAppDir))) - - <_WasmIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm')) diff --git a/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs b/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs index a0af313aa1e6a..8a8149ef15484 100644 --- a/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs +++ b/src/tasks/AndroidAppBuilder/AndroidApkFileReplacerTask.cs @@ -26,8 +26,7 @@ public class AndroidApkFileReplacerTask : Task public override bool Execute() { - Utils.Logger = Log; - var apkBuilder = new ApkBuilder(); + var apkBuilder = new ApkBuilder(Log); apkBuilder.OutputDir = OutputDir; apkBuilder.AndroidSdk = AndroidSdk; apkBuilder.MinApiLevel = MinApiLevel; diff --git a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs index 345ad7219998d..fcf71c0e6f68e 100644 --- a/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -87,11 +87,9 @@ public class AndroidAppBuilderTask : Task public override bool Execute() { - Utils.Logger = Log; - string abi = DetermineAbi(); - var apkBuilder = new ApkBuilder(); + var apkBuilder = new ApkBuilder(Log); apkBuilder.ProjectName = ProjectName; apkBuilder.AppDir = AppDir; apkBuilder.OutputDir = OutputDir; diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs index 23475c9e1e6c2..c69288218d69f 100644 --- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; public class ApkBuilder { @@ -32,6 +33,13 @@ public class ApkBuilder public string? DiagnosticPorts { get; set; } public ITaskItem[] Assemblies { get; set; } = Array.Empty(); + private TaskLoggingHelper logger; + + public ApkBuilder(TaskLoggingHelper logger) + { + this.logger = logger; + } + public (string apk, string packageId) BuildApk( string abi, string mainLibraryFileName, @@ -209,7 +217,7 @@ public class ApkBuilder string cmake = "cmake"; string zip = "zip"; - Utils.RunProcess(zip, workingDir: assetsToZipDirectory, args: "-q -r ../assets/assets.zip ."); + Utils.RunProcess(logger, zip, workingDir: assetsToZipDirectory, args: "-q -r ../assets/assets.zip ."); Directory.Delete(assetsToZipDirectory, true); if (!File.Exists(androidJar)) @@ -274,7 +282,7 @@ public class ApkBuilder // if lib doesn't exist (primarly due to runtime build without static lib support), fallback linking stub lib. if (!File.Exists(componentLibToLink)) { - Utils.LogInfo($"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); + logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); componentLibToLink = staticComponentStubLib; } @@ -339,8 +347,8 @@ public class ApkBuilder cmakeBuildArgs += " --config Debug"; } - Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeGenArgs); - Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeBuildArgs); + Utils.RunProcess(logger, cmake, workingDir: OutputDir, args: cmakeGenArgs); + Utils.RunProcess(logger, cmake, workingDir: OutputDir, args: cmakeBuildArgs); // 2. Compile Java files @@ -369,15 +377,15 @@ public class ApkBuilder .Replace("%MinSdkLevel%", MinApiLevel)); string javaCompilerArgs = $"-d obj -classpath src -bootclasspath {androidJar} -source 1.8 -target 1.8 "; - Utils.RunProcess(javac, javaCompilerArgs + javaActivityPath, workingDir: OutputDir); - Utils.RunProcess(javac, javaCompilerArgs + monoRunnerPath, workingDir: OutputDir); - Utils.RunProcess(dx, "--dex --output=classes.dex obj", workingDir: OutputDir); + Utils.RunProcess(logger, javac, javaCompilerArgs + javaActivityPath, workingDir: OutputDir); + Utils.RunProcess(logger, javac, javaCompilerArgs + monoRunnerPath, workingDir: OutputDir); + Utils.RunProcess(logger, dx, "--dex --output=classes.dex obj", workingDir: OutputDir); // 3. Generate APK string debugModeArg = StripDebugSymbols ? string.Empty : "--debug-mode"; string apkFile = Path.Combine(OutputDir, "bin", $"{ProjectName}.unaligned.apk"); - Utils.RunProcess(aapt, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"package -f -m -F {apkFile} -A assets -M AndroidManifest.xml -I {androidJar} {debugModeArg}", workingDir: OutputDir); var dynamicLibs = new List(); dynamicLibs.Add(Path.Combine(OutputDir, "monodroid", "libmonodroid.so")); @@ -433,21 +441,21 @@ public class ApkBuilder // NOTE: we can run android-strip tool from NDK to shrink native binaries here even more. File.Copy(dynamicLib, Path.Combine(OutputDir, destRelative), true); - Utils.RunProcess(aapt, $"add {apkFile} {destRelative}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add {apkFile} {destRelative}", workingDir: OutputDir); } - Utils.RunProcess(aapt, $"add {apkFile} classes.dex", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add {apkFile} classes.dex", workingDir: OutputDir); // 4. Align APK string alignedApk = Path.Combine(OutputDir, "bin", $"{ProjectName}.apk"); - Utils.RunProcess(zipalign, $"-v 4 {apkFile} {alignedApk}", workingDir: OutputDir); + Utils.RunProcess(logger, zipalign, $"-v 4 {apkFile} {alignedApk}", workingDir: OutputDir); // we don't need the unaligned one any more File.Delete(apkFile); // 5. Generate key (if needed) & sign the apk SignApk(alignedApk, apksigner); - Utils.LogInfo($"\nAPK size: {(new FileInfo(alignedApk).Length / 1000_000.0):0.#} Mb.\n"); + logger.LogMessage(MessageImportance.High, $"\nAPK size: {(new FileInfo(alignedApk).Length / 1000_000.0):0.#} Mb.\n"); return (alignedApk, packageId); } @@ -460,7 +468,7 @@ private void SignApk(string apkPath, string apksigner) if (!File.Exists(signingKey)) { - Utils.RunProcess("keytool", "-genkey -v -keystore debug.keystore -storepass android -alias " + + Utils.RunProcess(logger, "keytool", "-genkey -v -keystore debug.keystore -storepass android -alias " + "androiddebugkey -keypass android -keyalg RSA -keysize 2048 -noprompt " + "-dname \"CN=Android Debug,O=Android,C=US\"", workingDir: OutputDir, silent: true); } @@ -468,7 +476,7 @@ private void SignApk(string apkPath, string apksigner) { File.Copy(signingKey, Path.Combine(OutputDir, "debug.keystore")); } - Utils.RunProcess(apksigner, $"sign --min-sdk-version {MinApiLevel} --ks debug.keystore " + + Utils.RunProcess(logger, apksigner, $"sign --min-sdk-version {MinApiLevel} --ks debug.keystore " + $"--ks-pass pass:android --key-pass pass:android {apkPath}", workingDir: OutputDir); } @@ -499,8 +507,8 @@ public void ReplaceFileInApk(string file) if (!File.Exists(apkPath)) throw new Exception($"{apkPath} was not found"); - Utils.RunProcess(aapt, $"remove -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); - Utils.RunProcess(aapt, $"add -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"remove -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); + Utils.RunProcess(logger, aapt, $"add -v bin/{Path.GetFileName(apkPath)} {file}", workingDir: OutputDir); // we need to re-sign the apk SignApk(apkPath, apksigner); diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 259622da70785..465c8845209d9 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -194,8 +194,6 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task public override bool Execute() { - Utils.Logger = Log; - if (string.IsNullOrEmpty(CompilerBinaryPath)) { throw new ArgumentException($"'{nameof(CompilerBinaryPath)}' is required.", nameof(CompilerBinaryPath)); @@ -545,15 +543,25 @@ private bool PrecompileLibrary(ITaskItem assemblyItem, string? monoPaths) Log.LogMessage(MessageImportance.Low, $"AOT compiler arguments: {responseFileContent}"); + string args = $"--response=\"{responseFilePath}\""; + + // Log the command in a compact format which can be copy pasted + StringBuilder envStr = new StringBuilder(string.Empty); + foreach (KeyValuePair kvp in envVariables) + envStr.Append($"{kvp.Key}={kvp.Value} "); + Log.LogMessage(MessageImportance.Low, $"Exec: {envStr}{CompilerBinaryPath} {args}"); + try { // run the AOT compiler - (int exitCode, string output) = Utils.TryRunProcess(CompilerBinaryPath, - $"--response=\"{responseFilePath}\"", + (int exitCode, string output) = Utils.TryRunProcess(Log, + CompilerBinaryPath, + args, envVariables, assemblyDir, silent: false, - debugMessageImportance: MessageImportance.Low); + debugMessageImportance: MessageImportance.Low, + label: assembly); if (exitCode != 0) { Log.LogError($"Precompiling failed for {assembly}: {output}"); diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 0b20d27f38835..a0637d8d8453d 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -153,7 +153,6 @@ public string TargetOS public override bool Execute() { - Utils.Logger = Log; bool isDevice = (TargetOS == TargetNames.iOS || TargetOS == TargetNames.tvOS); if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) @@ -227,7 +226,7 @@ public override bool Execute() if (GenerateXcodeProject) { - Xcode generator = new Xcode(TargetOS, Arch); + Xcode generator = new Xcode(Log, TargetOS, Arch); generator.EnableRuntimeLogging = EnableRuntimeLogging; generator.DiagnosticPorts = DiagnosticPorts; @@ -239,7 +238,7 @@ public override bool Execute() if (isDevice && string.IsNullOrEmpty(DevTeamProvisioning)) { // DevTeamProvisioning shouldn't be empty for arm64 builds - Utils.LogInfo("DevTeamProvisioning is not set, BuildAppBundle step is skipped."); + Log.LogMessage(MessageImportance.High, "DevTeamProvisioning is not set, BuildAppBundle step is skipped."); } else { diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index b79387da224f8..2e938d8ea0e36 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -6,6 +6,8 @@ using System.IO; using System.Linq; using System.Text; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; internal class Xcode { @@ -13,27 +15,29 @@ internal class Xcode private string SysRoot { get; set; } private string Target { get; set; } private string XcodeArch { get; set; } + private TaskLoggingHelper Logger { get; set; } - public Xcode(string target, string arch) + public Xcode(TaskLoggingHelper logger, string target, string arch) { + Logger = logger; Target = target; XcodeArch = (arch == "x64") ? "x86_64" : arch; switch (Target) { case TargetNames.iOS: - SysRoot = Utils.RunProcess("xcrun", "--sdk iphoneos --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphoneos --show-sdk-path"); break; case TargetNames.iOSsim: - SysRoot = Utils.RunProcess("xcrun", "--sdk iphonesimulator --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk iphonesimulator --show-sdk-path"); break; case TargetNames.tvOS: - SysRoot = Utils.RunProcess("xcrun", "--sdk appletvos --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvos --show-sdk-path"); break; case TargetNames.tvOSsim: - SysRoot = Utils.RunProcess("xcrun", "--sdk appletvsimulator --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk appletvsimulator --show-sdk-path"); break; default: - SysRoot = Utils.RunProcess("xcrun", "--sdk macosx --show-sdk-path"); + SysRoot = Utils.RunProcess(Logger, "xcrun", "--sdk macosx --show-sdk-path"); break; } @@ -145,7 +149,7 @@ public string GenerateXCode( // if lib doesn't exist (primarly due to runtime build without static lib support), fallback linking stub lib. if (!File.Exists(componentLibToLink)) { - Utils.LogInfo($"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); + Logger.LogMessage(MessageImportance.High, $"\nCouldn't find static component library: {componentLibToLink}, linking static component stub library: {staticComponentStubLib}.\n"); componentLibToLink = staticComponentStubLib; } @@ -298,7 +302,7 @@ public string GenerateXCode( .Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier) .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib))); - Utils.RunProcess("cmake", cmakeArgs.ToString(), workingDir: binDir); + Utils.RunProcess(Logger, "cmake", cmakeArgs.ToString(), workingDir: binDir); return Path.Combine(binDir, projectName, projectName + ".xcodeproj"); } @@ -391,7 +395,7 @@ public string BuildAppBundle( string config = optimized ? "Release" : "Debug"; args.Append(" -configuration ").Append(config); - Utils.RunProcess("xcodebuild", args.ToString(), workingDir: Path.GetDirectoryName(xcodePrjPath)); + Utils.RunProcess(Logger, "xcodebuild", args.ToString(), workingDir: Path.GetDirectoryName(xcodePrjPath)); string appPath = Path.Combine(Path.GetDirectoryName(xcodePrjPath)!, config + "-" + sdk, Path.GetFileNameWithoutExtension(xcodePrjPath) + ".app"); @@ -400,7 +404,7 @@ public string BuildAppBundle( .EnumerateFiles("*", SearchOption.AllDirectories) .Sum(file => file.Length); - Utils.LogInfo($"\nAPP size: {(appSize / 1000_000.0):0.#} Mb.\n"); + Logger.LogMessage(MessageImportance.High, $"\nAPP size: {(appSize / 1000_000.0):0.#} Mb.\n"); return appPath; } diff --git a/src/tasks/Common/Utils.cs b/src/tasks/Common/Utils.cs index 8756a3156c220..3376b4d5e7bdc 100644 --- a/src/tasks/Common/Utils.cs +++ b/src/tasks/Common/Utils.cs @@ -22,10 +22,11 @@ public static string GetEmbeddedResource(string file) return reader.ReadToEnd(); } - public static (int exitCode, string output) RunShellCommand(string command, + public static (int exitCode, string output) RunShellCommand( + TaskLoggingHelper logger, + string command, IDictionary envVars, string workingDir, - TaskLoggingHelper logger, bool silent=false, bool logStdErrAsMessage=false, MessageImportance debugMessageImportance=MessageImportance.Low, @@ -37,16 +38,16 @@ public static (int exitCode, string output) RunShellCommand(string command, : ("/bin/sh", $"\"{scriptFileName}\""); string msgPrefix = label == null ? string.Empty : $"[{label}] "; - LogMessage(debugMessageImportance, $"Running {command} via script {scriptFileName}:", msgPrefix); - LogMessage(debugMessageImportance, File.ReadAllText(scriptFileName), msgPrefix); + logger.LogMessage(debugMessageImportance, $"Running {command} via script {scriptFileName}:", msgPrefix); + logger.LogMessage(debugMessageImportance, File.ReadAllText(scriptFileName), msgPrefix); - return TryRunProcess(shell, + return TryRunProcess(logger, + shell, args, envVars, workingDir, silent: silent, logStdErrAsMessage: logStdErrAsMessage, - logger: logger, label: label, debugMessageImportance: debugMessageImportance); @@ -74,6 +75,7 @@ static string CreateTemporaryBatchFile(string command) } public static string RunProcess( + TaskLoggingHelper logger, string path, string args = "", IDictionary? envVars = null, @@ -83,12 +85,12 @@ public static string RunProcess( MessageImportance debugMessageImportance=MessageImportance.High) { (int exitCode, string output) = TryRunProcess( + logger, path, args, envVars, workingDir, silent: silent, - logger: Logger, debugMessageImportance: debugMessageImportance); if (exitCode != 0 && !ignoreErrors) @@ -98,20 +100,18 @@ public static string RunProcess( } public static (int, string) TryRunProcess( + TaskLoggingHelper logger, string path, string args = "", IDictionary? envVars = null, string? workingDir = null, bool silent = true, bool logStdErrAsMessage = false, - TaskLoggingHelper? logger = null, MessageImportance debugMessageImportance=MessageImportance.High, string? label=null) { - Logger = logger; - string msgPrefix = label == null ? string.Empty : $"[{label}] "; - LogMessage(debugMessageImportance, $"Running: {path} {args}", msgPrefix); + logger.LogMessage(debugMessageImportance, $"Running: {path} {args}", msgPrefix); var outputBuilder = new StringBuilder(); var processStartInfo = new ProcessStartInfo { @@ -126,17 +126,17 @@ public static (int, string) TryRunProcess( if (workingDir != null) processStartInfo.WorkingDirectory = workingDir; - LogMessage(debugMessageImportance, $"Using working directory: {workingDir ?? Environment.CurrentDirectory}", msgPrefix); + logger.LogMessage(debugMessageImportance, $"Using working directory: {workingDir ?? Environment.CurrentDirectory}", msgPrefix); if (envVars != null) { if (envVars.Count > 0) - LogMessage(MessageImportance.Low, $"Setting environment variables for execution:", msgPrefix); + logger.LogMessage(MessageImportance.Low, $"Setting environment variables for execution:", msgPrefix); foreach (KeyValuePair envVar in envVars) { processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value; - Logger?.LogMessage(MessageImportance.Low, $"{msgPrefix}\t{envVar.Key} = {envVar.Value}"); + logger.LogMessage(MessageImportance.Low, $"{msgPrefix}\t{envVar.Key} = {envVar.Value}"); } } @@ -155,9 +155,9 @@ public static (int, string) TryRunProcess( if (!silent) { if (logStdErrAsMessage) - LogMessage(debugMessageImportance, e.Data, msgPrefix); + logger.LogMessage(debugMessageImportance, e.Data, msgPrefix); else - Logger?.LogWarning(msg); + logger.LogWarning(msg); } outputBuilder.AppendLine(e.Data); } @@ -170,7 +170,7 @@ public static (int, string) TryRunProcess( return; if (!silent) - LogMessage(debugMessageImportance, e.Data, msgPrefix); + logger.LogMessage(debugMessageImportance, e.Data, msgPrefix); outputBuilder.AppendLine(e.Data); } }; @@ -178,7 +178,7 @@ public static (int, string) TryRunProcess( process.BeginErrorReadLine(); process.WaitForExit(); - Logger?.LogMessage(debugMessageImportance, $"{msgPrefix}Exit code: {process.ExitCode}"); + logger.LogMessage(debugMessageImportance, $"{msgPrefix}Exit code: {process.ExitCode}"); return (process.ExitCode, outputBuilder.ToString().Trim('\r', '\n')); } @@ -223,24 +223,4 @@ public static void DirectoryCopy(string sourceDir, string destDir, Func envVarsDict = GetEnvironmentVariablesDict(); ConcurrentBag outputItems = new(); try @@ -112,7 +119,7 @@ bool ProcessSourceFile(ITaskItem srcItem) try { - string command = $"emcc {Arguments} -c -o {objFile} {srcFile}"; + string command = $"emcc {Arguments} -c -o \"{objFile}\" \"{srcFile}\""; // Log the command in a compact format which can be copy pasted StringBuilder envStr = new StringBuilder(string.Empty); @@ -120,12 +127,12 @@ bool ProcessSourceFile(ITaskItem srcItem) envStr.Append($"{key}={envVarsDict[key]} "); Log.LogMessage(MessageImportance.Low, $"Exec: {envStr}{command}"); (int exitCode, string output) = Utils.RunShellCommand( + Log, command, envVarsDict, workingDir: Environment.CurrentDirectory, - logger: Log, logStdErrAsMessage: true, - debugMessageImportance: MessageImportance.High, + debugMessageImportance: messageImportance, label: Path.GetFileName(srcFile)); if (exitCode != 0) diff --git a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs index bdd84c295ee7d..7ae4ca9920a2c 100644 --- a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs +++ b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs @@ -22,6 +22,8 @@ public class PInvokeTableGenerator : Task [Required] public string? OutputPath { get; set; } + private static char[] s_charsToReplace = new[] { '.', '-', }; + public override bool Execute() { Log.LogMessage(MessageImportance.Normal, $"Generating pinvoke table to '{OutputPath}'."); @@ -101,7 +103,7 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary modules foreach (var module in modules.Keys) { - string symbol = module.Replace(".", "_") + "_imports"; + string symbol = ModuleNameToId(module) + "_imports"; w.WriteLine("static PinvokeImport " + symbol + " [] = {"); var assemblies_pinvokes = pinvokes. @@ -120,7 +122,7 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary modules w.Write("static void *pinvoke_tables[] = { "); foreach (var module in modules.Keys) { - string symbol = module.Replace(".", "_") + "_imports"; + string symbol = ModuleNameToId(module) + "_imports"; w.Write(symbol + ","); } w.WriteLine("};"); @@ -130,6 +132,18 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary modules w.Write("\"" + module + "\"" + ","); } w.WriteLine("};"); + + static string ModuleNameToId(string name) + { + if (name.IndexOfAny(s_charsToReplace) < 0) + return name; + + string fixedName = name; + foreach (char c in s_charsToReplace) + fixedName = fixedName.Replace(c, '_'); + + return fixedName; + } } private string MapType (Type t) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index c76659d5db3a0..4b4a283dc652f 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -34,8 +34,6 @@ public class InstallWorkloadFromArtifacts : Task public override bool Execute() { - Utils.Logger = Log; - if (!HasMetadata(WorkloadId, nameof(WorkloadId), "Version") || !HasMetadata(WorkloadId, nameof(WorkloadId), "ManifestName")) { @@ -59,6 +57,7 @@ public override bool Execute() Log.LogMessage(MessageImportance.High, $"{Environment.NewLine}** workload install **{Environment.NewLine}"); (int exitCode, string output) = Utils.TryRunProcess( + Log, Path.Combine(SdkDir, "dotnet"), $"workload install --skip-manifest-update --no-cache --configfile \"{nugetConfigPath}\" {WorkloadId.ItemSpec}", workingDir: Path.GetTempPath(), diff --git a/src/tasks/WorkloadBuildTasks/PackageInstaller.cs b/src/tasks/WorkloadBuildTasks/PackageInstaller.cs index f6d4e85cf76c8..227dcb4fbf9b7 100644 --- a/src/tasks/WorkloadBuildTasks/PackageInstaller.cs +++ b/src/tasks/WorkloadBuildTasks/PackageInstaller.cs @@ -60,7 +60,7 @@ private bool InstallActual(PackageReference[] references, bool stopOnMissing) _logger.LogMessage(MessageImportance.Low, $"Restoring packages: {string.Join(", ", references.Select(r => $"{r.Name}/{r.Version}"))}"); string args = $"restore \"{projectPath}\" /p:RestorePackagesPath=\"{_packagesDir}\""; - (int exitCode, string output) = Utils.TryRunProcess("dotnet", args, silent: false, debugMessageImportance: MessageImportance.Low); + (int exitCode, string output) = Utils.TryRunProcess(_logger, "dotnet", args, silent: false, debugMessageImportance: MessageImportance.Low); if (exitCode != 0) { LogErrorOrWarning($"Restoring packages failed with exit code: {exitCode}. Output:{Environment.NewLine}{output}", stopOnMissing); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs index dacf67ff4f395..002ca2480311a 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BlazorWasmTests.cs @@ -16,10 +16,16 @@ public BlazorWasmTests(ITestOutputHelper output, SharedBuildPerTestClassFixture { } - [ConditionalFact(typeof(BuildTestBase), nameof(IsUsingWorkloads))] - public void PublishTemplateProject() + // TODO: invariant case? + + [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [InlineData("Debug", false)] + [InlineData("Debug", true)] // just aot + [InlineData("Release", false)] // should re-link + [InlineData("Release", true)] + public void PublishTemplateProject(string config, bool aot) { - string id = "blazorwasm"; + string id = $"blazorwasm_{config}_aot_{aot}"; InitPaths(id); if (Directory.Exists(_projectDir)) Directory.Delete(_projectDir, recursive: true); @@ -37,14 +43,16 @@ public void PublishTemplateProject() .ExecuteWithCapturedOutput("new blazorwasm") .EnsureSuccessful(); - string publishLogPath = Path.Combine(logPath, $"{id}.publish.binlog"); + string publishLogPath = Path.Combine(logPath, $"{id}.binlog"); new DotNetCommand(s_buildEnv) .WithWorkingDirectory(_projectDir) - .ExecuteWithCapturedOutput("publish", $"-bl:{publishLogPath}", "-p:RunAOTCompilation=true") + .ExecuteWithCapturedOutput("publish", $"-bl:{publishLogPath}", aot ? "-p:RunAOTCompilation=true" : "", $"-p:Configuration={config}") .EnsureSuccessful(); //TODO: validate the build somehow? // compare dotnet.wasm? + // relinking - dotnet.wasm should be smaller + // // playwright? } } diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs index 7d211ae618912..4dd5144729cd1 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs @@ -69,6 +69,7 @@ static BuildTestBase() public BuildTestBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) { + Console.WriteLine($"{Environment.NewLine}-------- New test --------{Environment.NewLine}"); _buildContext = buildContext; _testOutput = output; _logPath = s_buildEnv.LogRootPath; // FIXME: @@ -216,7 +217,8 @@ protected static string RunWithXHarness(string testCommand, string testLogPath, [MemberNotNull(nameof(_projectDir), nameof(_logPath))] protected void InitPaths(string id) { - _projectDir = Path.Combine(AppContext.BaseDirectory, id); + if (_projectDir == null) + _projectDir = Path.Combine(AppContext.BaseDirectory, id); _logPath = Path.Combine(s_buildEnv.LogRootPath, id); Directory.CreateDirectory(_logPath); @@ -330,10 +332,7 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp } if (useCache) - { _buildContext.CacheBuild(buildArgs, new BuildProduct(_projectDir, logFilePath, true)); - Console.WriteLine($"caching build for {buildArgs}"); - } return (_projectDir, result.buildOutput); } @@ -539,7 +538,6 @@ public static (int exitCode, string buildOutput) RunProcess(string path, var lastLines = outputBuilder.ToString().Split('\r', '\n').TakeLast(20); throw new XunitException($"Process timed out, output: {string.Join(Environment.NewLine, lastLines)}"); } - } lock (syncObj) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs index 30e487f8171c0..80c7ba5fe85b8 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeBuildTests.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.IO; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; #nullable enable @@ -31,9 +31,8 @@ private void NativeBuild(string projectNamePrefix, string projectContents, Build { string projectName = $"{projectNamePrefix}_{buildArgs.Config}_{buildArgs.AOT}"; - buildArgs = buildArgs with { ProjectName = projectName, ProjectFileContents = projectContents }; + buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs, extraProperties: "true"); - Console.WriteLine ($"-- args: {buildArgs}, name: {projectName}"); BuildProject(buildArgs, initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), projectContents), @@ -44,5 +43,37 @@ private void NativeBuild(string projectNamePrefix, string projectContents, Build test: output => {}, host: host, id: id); } + + [Theory] + [BuildAndRun(host: RunHost.None, aot: true)] + public void IntermediateBitcodeToObjectFilesAreNotLLVMIR(BuildArgs buildArgs, string id) + { + string printFileTypeTarget = @" + + + + + + + + + "; + string projectName = $"bc_to_o_{buildArgs.Config}"; + + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, insertAtEnd: printFileTypeTarget); + + (_, string output) = BuildProject(buildArgs, + initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42), + dotnetWasmFromRuntimePack: false, + id: id); + + if (!output.Contains("wasm-dis exit code: 0")) + throw new XunitException($"Expected to successfully run wasm-dis on System.Private.CoreLib.dll.o ." + + " It might fail if it was incorrectly compiled to a bitcode file, instead of wasm."); + } } } diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeLibraryTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeLibraryTests.cs new file mode 100644 index 0000000000000..e06c099b19c4b --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeLibraryTests.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; + +#nullable enable + +namespace Wasm.Build.Tests +{ + public class NativeLibraryTests : BuildTestBase + { + public NativeLibraryTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + [Theory] + [BuildAndRun(aot: false)] + [BuildAndRun(aot: true)] + public void ProjectWithNativeReference(BuildArgs buildArgs, RunHost host, string id) + { + string projectName = $"AppUsingNativeLib-a"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, extraItems: ""); + + if (!_buildContext.TryGetBuildFor(buildArgs, out BuildProduct? _)) + { + InitPaths(id); + if (Directory.Exists(_projectDir)) + Directory.Delete(_projectDir, recursive: true); + + Utils.DirectoryCopy(Path.Combine(BuildEnvironment.TestAssetsPath, "AppUsingNativeLib"), _projectDir); + File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "native-libs", "native-lib.o"), Path.Combine(_projectDir, "native-lib.o")); + } + + BuildProject(buildArgs, + dotnetWasmFromRuntimePack: false, + id: id); + + string output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 0, + test: output => {}, + host: host, id: id); + + Assert.Contains("print_line: 100", output); + Assert.Contains("from pinvoke: 142", output); + } + + [Theory] + [BuildAndRun(aot: false)] + [BuildAndRun(aot: true)] + public void ProjectUsingSkiaSharp(BuildArgs buildArgs, RunHost host, string id) + { + string projectName = $"AppUsingSkiaSharp"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, + extraItems: @$" + + + + + + "); + + string programText = @" +using System; +using SkiaSharp; + +public class Test +{ + public static int Main() + { + using SKFileStream skfs = new SKFileStream(""mono.png""); + using SKImage img = SKImage.FromEncodedData(skfs); + + Console.WriteLine ($""Size: {skfs.Length} Height: {img.Height}, Width: {img.Width}""); + return 0; + } +}"; + + BuildProject(buildArgs, + initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), + dotnetWasmFromRuntimePack: false, + id: id); + + string output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 0, + test: output => {}, + host: host, id: id, + args: "mono.png"); + + Assert.Contains("Size: 26462 Height: 599, Width: 499", output); + } + } +} diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs index 2c43614ea4169..e84a151bd5b02 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/SharedBuildPerTestClassFixture.cs @@ -44,7 +44,7 @@ private void RemoveDirectory(string path) { try { - Directory.Delete(path, recursive: true); + Directory.Delete(path, recursive: true); } catch (Exception ex) { diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs index b45fefac9acda..9d39dcce04a57 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ToolCommand.cs @@ -88,6 +88,7 @@ private async Task ExecuteAsyncInternal(string executable, string return; output.Add($"[{_label}] {e.Data}"); + Console.WriteLine($"[{_label}] {e.Data}"); ErrorDataReceived?.Invoke(s, e); }; @@ -97,6 +98,7 @@ private async Task ExecuteAsyncInternal(string executable, string return; output.Add($"[{_label}] {e.Data}"); + Console.WriteLine($"[{_label}] {e.Data}"); OutputDataReceived?.Invoke(s, e); }; diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets index 19f795a01f235..62e463bb19958 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/data/Workloads.Directory.Build.targets @@ -2,7 +2,6 @@ PrepareForWasmBuild;$(WasmBuildAppDependsOn) <_MicrosoftNetCoreAppRefDir>$(AppRefDir)\ - Microsoft.NETCore.App diff --git a/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/Program.cs b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/Program.cs new file mode 100644 index 0000000000000..5134392c9d8ca --- /dev/null +++ b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/Program.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using System; +using System.Threading.Tasks; + +namespace SimpleConsole +{ + public class Test + { + public static int Main(string[] args) + { + Console.WriteLine ($"from pinvoke: {SimpleConsole.Test.print_line(100)}"); + return 0; + } + + [DllImport("native-lib")] + public static extern int print_line(int x); + } +} diff --git a/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.cpp b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.cpp new file mode 100644 index 0000000000000..329a593279fe2 --- /dev/null +++ b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.cpp @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "native-lib.h" +#include + +int print_line(int x) +{ + printf("print_line: %d\n", x); + return 42 + x; +} diff --git a/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.h b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.h new file mode 100644 index 0000000000000..826637b3a2d81 --- /dev/null +++ b/src/tests/BuildWasmApps/testassets/AppUsingNativeLib/native-lib.h @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef _NATIVELIB_H_ +#define _NATIVELIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int print_line(int x); + +#ifdef __cplusplus +} +#endif + +#endif // _NATIVELIB_H_ diff --git a/src/tests/BuildWasmApps/testassets/AppUsingSkiaSharp/Program.cs b/src/tests/BuildWasmApps/testassets/AppUsingSkiaSharp/Program.cs new file mode 100644 index 0000000000000..0aeedffaf6d98 --- /dev/null +++ b/src/tests/BuildWasmApps/testassets/AppUsingSkiaSharp/Program.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using SkiaSharp; + +public class Test +{ + public static int Main() + { + using SKFileStream skfs = new SKFileStream("mono.png"); + using SKImage img = SKImage.FromEncodedData(skfs); + + Console.WriteLine ($"Size: {skfs.Length} Height: {img.Height}, Width: {img.Width}"); + return 0; + } +} diff --git a/src/tests/BuildWasmApps/testassets/mono.png b/src/tests/BuildWasmApps/testassets/mono.png new file mode 100644 index 0000000000000..7469aec9d1fcf Binary files /dev/null and b/src/tests/BuildWasmApps/testassets/mono.png differ diff --git a/src/tests/BuildWasmApps/testassets/native-libs/native-lib.o b/src/tests/BuildWasmApps/testassets/native-libs/native-lib.o new file mode 100644 index 0000000000000..10ccf42c5ff23 Binary files /dev/null and b/src/tests/BuildWasmApps/testassets/native-libs/native-lib.o differ