diff --git a/dotnet/targets/Xamarin.Shared.Sdk.props b/dotnet/targets/Xamarin.Shared.Sdk.props index badf92982b65..71c022b14afa 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.props +++ b/dotnet/targets/Xamarin.Shared.Sdk.props @@ -203,4 +203,10 @@ --> true + + + + <_SdkIsSimulator Condition="'$(RuntimeIdentifier)' != '' And '$(_SdkIsSimulator)' == ''">$(RuntimeIdentifier.Contains('simulator')) + <_SdkIsSimulator Condition="'$(RuntimeIdentifiers)' != '' And '$(_SdkIsSimulator)' == ''">$(RuntimeIdentifiers.Contains('simulator')) + diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx index 32cd700a7c59..41d34a42d204 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx @@ -1662,4 +1662,8 @@ Unknown resource type: {1}. + + + Can't process the native reference '{0}' on this platform because it is or contains a symlink. + diff --git a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs index 4f2f8d5c0636..d11bfb0af74c 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; +using System.Linq; using System.Reflection; using System.Threading; @@ -12,6 +13,7 @@ using Xamarin.Bundler; using Xamarin.Localization.MSBuild; using Xamarin.MacDev.Tasks; +using Xamarin.Utils; #nullable enable @@ -222,6 +224,134 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string return rv; } + /// + /// Compresses the specified resources (may be either files or directories) into a zip file. + /// + /// Fails if: + /// * The resources is or contains a symlink and we're executing on Windows. + /// * The resources isn't found inside the zip file. + /// + /// + /// The zip to create + /// The files or directories to compress. + /// + public static bool TryCompress (TaskLoggingHelper log, string zip, IEnumerable resources, bool overwrite, string workingDirectory, bool maxCompression = false) + { + // We use 'zip' to compress on !Windows, and System.IO.Compression to extract on Windows. + // This is because System.IO.Compression doesn't handle symlinks correctly, so we can only use + // it on Windows. It's also possible to set the XAMARIN_USE_SYSTEM_IO_COMPRESSION=1 environment + // variable to force using System.IO.Compression on !Windows, which is particularly useful when + // testing the System.IO.Compression implementation locally (with the caveat that if the resources + // to compress has symlinks, it may not work). + + if (overwrite) { + if (File.Exists (zip)) { + log.LogMessage (MessageImportance.Low, "Replacing zip file {0} with {1}", zip, string.Join (", ", resources)); + File.Delete (zip); + } else { + log.LogMessage (MessageImportance.Low, "Creating zip file {0} with {1}", zip, string.Join (", ", resources)); + } + } else { + if (File.Exists (zip)) { + log.LogMessage (MessageImportance.Low, "Updating zip file {0} with {1}", zip, string.Join (", ", resources)); + } else { + log.LogMessage (MessageImportance.Low, "Creating new zip file {0} with {1}", zip, string.Join (", ", resources)); + } + } + + var zipdir = Path.GetDirectoryName (zip); + if (!string.IsNullOrEmpty (zipdir)) + Directory.CreateDirectory (zipdir); + + bool rv; + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { + rv = TryCompressUsingSystemIOCompression (log, zip, resources, workingDirectory, maxCompression); + } else if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_USE_SYSTEM_IO_COMPRESSION"))) { + rv = TryCompressUsingSystemIOCompression (log, zip, resources, workingDirectory, maxCompression); + } else { + rv = TryCompressUsingZip (log, zip, resources, workingDirectory, maxCompression); + } + + return rv; + } + + // Will add to an existing zip file (not replace) + static bool TryCompressUsingZip (TaskLoggingHelper log, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) + { + var zipArguments = new List (); + if (maxCompression) + zipArguments.Add ("-9"); + zipArguments.Add ("-r"); + zipArguments.Add ("-y"); + zipArguments.Add (zip); + + foreach (var resource in resources) { + var fullPath = Path.GetFullPath (resource); + var relativePath = PathUtils.AbsoluteToRelative (workingDirectory, fullPath); + zipArguments.Add (relativePath); + } + var rv = XamarinTask.ExecuteAsync (log, "zip", zipArguments, workingDirectory: workingDirectory).Result; + log.LogMessage (MessageImportance.Low, "Updated {0} with {1}: {2}", zip, string.Join (", ", resources), rv.ExitCode == 0); + return rv.ExitCode == 0; + } + +#if NET + const CompressionLevel SmallestCompressionLevel = CompressionLevel.SmallestSize; +#else + const CompressionLevel SmallestCompressionLevel = CompressionLevel.Optimal; +#endif + + // Will add to an existing zip file (not replace) + static bool TryCompressUsingSystemIOCompression (TaskLoggingHelper log, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) + { + var rv = true; + + workingDirectory = Path.GetFullPath (workingDirectory); + + var resourcePaths = resources.Select ((v) => Path.Combine (workingDirectory, v)).ToList (); + foreach (var resource in resourcePaths) { + if (!resource.StartsWith (workingDirectory, StringComparison.Ordinal)) + throw new InvalidOperationException ($"The resource to compress '{resource}' must be inside the working directory '{workingDirectory}'"); + } + + using var archive = ZipFile.Open (zip, File.Exists (zip) ? ZipArchiveMode.Update : ZipArchiveMode.Create); + + var rootDirLength = workingDirectory.Length; + foreach (var resource in resourcePaths) { + if (Directory.Exists (resource)) { + var entries = Directory.GetFileSystemEntries (resource, "*", SearchOption.AllDirectories); + var entriesWithZipName = entries.Select (v => new { Path = v, ZipName = v.Substring (rootDirLength) }); + foreach (var entry in entriesWithZipName) { + if (Directory.Exists (entry.Path)) { + if (entries.Where (v => v.StartsWith (entry.Path, StringComparison.Ordinal)).Count () == 1) { + // this is a directory with no files inside, we need to create an entry with a trailing directory separator. + archive.CreateEntry (entry.ZipName + zipDirectorySeparator); + } + } else { + WriteFileToZip (log, archive, entry.Path, entry.ZipName, maxCompression); + } + } + } else if (File.Exists (resource)) { + var zipName = resource.Substring (rootDirLength); + WriteFileToZip (log, archive, resource, zipName, maxCompression); + } else { + throw new FileNotFoundException (resource); + } + log.LogMessage (MessageImportance.Low, "Updated {0} with {1}", zip, resource); + } + + return rv; + } + + static void WriteFileToZip (TaskLoggingHelper log, ZipArchive archive, string path, string zipName, bool maxCompression) + { + var zipEntry = archive.CreateEntry (zipName, maxCompression ? SmallestCompressionLevel : CompressionLevel.Optimal); + using var fs = File.OpenRead (path); + using var zipStream = zipEntry.Open (); + fs.CopyTo (zipStream); + log.LogMessage (MessageImportance.Low, $"Compressed {path} into the zip file as {zipName}"); + } + static int GetExternalAttributes (ZipArchiveEntry self) { // The ZipArchiveEntry.ExternalAttributes property is available in .NET 4.7.2 (which we need to target for builds on Windows) and .NET 5+, but not netstandard2.0 (which is the latest netstandard .NET 4.7.2 supports). diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs index 41b74c9d6553..4de4df49ff23 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs @@ -90,19 +90,10 @@ public override bool Execute () filesToZip.Add (manifestPath); foreach (var nativeRef in filesToZip) { - var zipArguments = new List (); - zipArguments.Add ("-9"); - zipArguments.Add ("-r"); - zipArguments.Add ("-y"); - zipArguments.Add (zipFile); - - var fullPath = Path.GetFullPath (nativeRef); - var workingDirectory = Path.GetDirectoryName (fullPath); - zipArguments.Add (Path.GetFileName (fullPath)); - ExecuteAsync ("zip", zipArguments, workingDirectory: workingDirectory).Wait (); - - packagedFiles.Add (zipFile); + var workingDirectory = Path.GetDirectoryName (nativeRef); + CompressionHelper.TryCompress (Log, zipFile, new string [] { nativeRef }, false, workingDirectory, true); } + packagedFiles.Add (zipFile); } else { var bindingResourcePath = BindingResourcePath; Log.LogMessage (MSBStrings.M0121, bindingResourcePath); @@ -127,11 +118,14 @@ public override bool Execute () return !Log.HasLoggedErrors; } - static bool ContainsSymlinks (ITaskItem [] items) + bool ContainsSymlinks (ITaskItem [] items) { foreach (var item in items) { - if (PathUtils.IsSymlinkOrContainsSymlinks (item.ItemSpec)) + if (PathUtils.IsSymlinkOrContainsSymlinks (item.ItemSpec)) { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + Log.LogError (MSBStrings.E7120_TEMP /* Can't process the native reference '{0}' on this platform because it is or contains a symlink. */, item?.ItemSpec); return true; + } } return false; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs index e8396be02c84..82a8be125b47 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs @@ -15,21 +15,15 @@ namespace Xamarin.MacDev.Tasks { public class Zip : XamarinTask, ICancelableTask { - CancellationTokenSource? cancellationTokenSource; - #region Inputs [Output] [Required] public ITaskItem? OutputFile { get; set; } - public bool Recursive { get; set; } - [Required] public ITaskItem [] Sources { get; set; } = Array.Empty (); - public bool Symlinks { get; set; } - [Required] public ITaskItem? WorkingDirectory { get; set; } @@ -37,41 +31,11 @@ public class Zip : XamarinTask, ICancelableTask { #endregion - static string GetExecutable (List arguments, string toolName, string toolPathOverride) - { - if (string.IsNullOrEmpty (toolPathOverride)) { - arguments.Insert (0, toolName); - return "xcrun"; - } - return toolPathOverride; - } - string GetWorkingDirectory () { return WorkingDirectory!.GetMetadata ("FullPath"); } - List GenerateCommandLineCommands () - { - var args = new List (); - - if (Recursive) - args.Add ("-r"); - - if (Symlinks) - args.Add ("-y"); - - args.Add (OutputFile!.GetMetadata ("FullPath")); - - var root = GetWorkingDirectory (); - for (int i = 0; i < Sources.Length; i++) { - var relative = PathUtils.AbsoluteToRelative (root, Sources [i].GetMetadata ("FullPath")); - args.Add (relative); - } - - return args; - } - public override bool Execute () { if (ShouldExecuteRemotely ()) { @@ -85,10 +49,17 @@ public override bool Execute () return rv; } - var args = GenerateCommandLineCommands (); - var executable = GetExecutable (args, "zip", ZipPath); - cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, workingDirectory: GetWorkingDirectory (), cancellationToken: cancellationTokenSource.Token).Wait (); + var zip = OutputFile!.GetMetadata ("FullPath"); + var workingDirectory = GetWorkingDirectory (); + var sources = new List (); + for (int i = 0; i < Sources.Length; i++) { + var relative = PathUtils.AbsoluteToRelative (workingDirectory, Sources [i].GetMetadata ("FullPath")); + sources.Add (relative); + } + + if (!CompressionHelper.TryCompress (this.Log, zip, sources, false, workingDirectory, false)) + return false; + return !Log.HasLoggedErrors; } @@ -96,8 +67,6 @@ public void Cancel () { if (ShouldExecuteRemotely ()) { BuildConnection.CancelAsync (BuildEngine4).Wait (); - } else { - cancellationTokenSource?.Cancel (); } } diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.ObjCBinding.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.ObjCBinding.targets index 6d467ab74dbc..3d0caa776265 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.ObjCBinding.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.ObjCBinding.targets @@ -93,14 +93,9 @@ Copyright (C) 2020 Microsoft. All rights reserved. - + @@ -116,8 +111,6 @@ Copyright (C) 2020 Microsoft. All rights reserved. diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index ff3f9d6d7194..d309eb83f3c0 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -151,8 +151,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_FileNativeReference Include="@(NativeReference)" Condition="'%(Extension)' != '.framework' And '%(Extension)' != '.xcframework' And '%(Extension)' != '.zip'" /> auto - @@ -245,7 +239,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. $(TargetsForTfmSpecificContentInPackage);_IncludeBindingResourcesInNuGetPackage <_HasOldStyleBindingItems Condition="@(ObjcBindingNativeLibrary->Count()) > 0">true @@ -1784,6 +1778,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_GenerateBindingsDependsOn> + _ComputeGenerationLocation; _CompileApiDefinitions; $(_GenerateBindingsDependsOn); @@ -1863,7 +1858,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. @(_CompiledApiDefinitionsCompile);" Outputs="$(_CompiledApiDefinitionAssembly);$(_CompiledApiDefinitionDocumentationFile)" DependsOnTargets="_ComputeCompileApiDefinitionsInputs" - Condition="'$(IsBindingProject)' == 'true' And '$(DesignTimeBuild)' != 'true'" + Condition="'$(IsBindingProject)' == 'true'" > @@ -1890,13 +1885,22 @@ Copyright (C) 2018 Microsoft. All rights reserved. + + + true + false + $(BuildSessionId) + + + + Condition="'$(IsBindingProject)' == 'true'"> - + + $(BTouchEmitDebugInformation) @@ -1910,12 +1914,12 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -1927,8 +1931,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -109,7 +114,12 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved. - + @@ -166,7 +176,12 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved. - + diff --git a/tests/Makefile b/tests/Makefile index 1dec5b2ffcc0..c6efacc6fde5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -200,6 +200,7 @@ package-test-libraries.zip: $(Q_GEN) rm -f "$@" "$@.tmp" $(Q_GEN) cd $(TOP) && zip -9r --symlinks $(abspath $@).tmp ./tests/test-libraries $(Q_GEN) cd $(TOP) && find tests -regex 'tests/test-libraries/custom-type-assembly/.libs/.*dll' -exec zip -9r --symlinks $(abspath $@).tmp {} + + $(Q_GEN) cd $(TOP) && git ls-files -o -- 'tests/bindings-test/*.generated.cs' | zip -9r --symlinks $(abspath $@).tmp -@ $(Q) mv "$@".tmp "$@" build-all: diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/ApiDefinition.cs deleted file mode 100644 index 57b6c66be50f..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/ApiDefinition.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Foundation; - -namespace MyApiDefinition { - [BaseType (typeof (NSObject))] - interface MyNativeClass { - } -} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs deleted file mode 120000 index f0f219820ed4..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs +++ /dev/null @@ -1 +0,0 @@ -../ApiDefinition.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs new file mode 100644 index 000000000000..f3a6430670fa --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/ApiDefinition.cs @@ -0,0 +1,8 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using Foundation; + +namespace MyApiDefinition { + [BaseType (typeof (NSObject))] + interface MyNativeClass { + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs deleted file mode 120000 index a8c5f5dd7287..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs +++ /dev/null @@ -1 +0,0 @@ -../MyClass.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs new file mode 100644 index 000000000000..69de7b469b7c --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/MyClass.cs @@ -0,0 +1,9 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using System; +namespace MyClassLibrary { + public class MyClass { + public MyClass () + { + } + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs deleted file mode 120000 index 082d90ff1d72..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs +++ /dev/null @@ -1 +0,0 @@ -../StructsAndEnums.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs new file mode 100644 index 000000000000..891d49cd9ecb --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/MacCatalyst/StructsAndEnums.cs @@ -0,0 +1,7 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +namespace MyClassLibrary { + public struct MyStruct { + public int A; + public int B; + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/MyClass.cs deleted file mode 100644 index 89ef0fec5fc9..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/MyClass.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; -namespace MyClassLibrary { - public class MyClass { - public MyClass () - { - } - } -} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/StructsAndEnums.cs deleted file mode 100644 index 6e8191ddb814..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/StructsAndEnums.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MyClassLibrary { - public struct MyStruct { - public int A; - public int B; - } -} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs deleted file mode 120000 index f0f219820ed4..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs +++ /dev/null @@ -1 +0,0 @@ -../ApiDefinition.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs new file mode 100644 index 000000000000..f3a6430670fa --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/ApiDefinition.cs @@ -0,0 +1,8 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using Foundation; + +namespace MyApiDefinition { + [BaseType (typeof (NSObject))] + interface MyNativeClass { + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs deleted file mode 120000 index a8c5f5dd7287..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs +++ /dev/null @@ -1 +0,0 @@ -../MyClass.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs new file mode 100644 index 000000000000..69de7b469b7c --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/MyClass.cs @@ -0,0 +1,9 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using System; +namespace MyClassLibrary { + public class MyClass { + public MyClass () + { + } + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs deleted file mode 120000 index 082d90ff1d72..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs +++ /dev/null @@ -1 +0,0 @@ -../StructsAndEnums.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs new file mode 100644 index 000000000000..891d49cd9ecb --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/iOS/StructsAndEnums.cs @@ -0,0 +1,7 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +namespace MyClassLibrary { + public struct MyStruct { + public int A; + public int B; + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs deleted file mode 120000 index f0f219820ed4..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs +++ /dev/null @@ -1 +0,0 @@ -../ApiDefinition.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs new file mode 100644 index 000000000000..f3a6430670fa --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/ApiDefinition.cs @@ -0,0 +1,8 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using Foundation; + +namespace MyApiDefinition { + [BaseType (typeof (NSObject))] + interface MyNativeClass { + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs deleted file mode 120000 index a8c5f5dd7287..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs +++ /dev/null @@ -1 +0,0 @@ -../MyClass.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs new file mode 100644 index 000000000000..69de7b469b7c --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/MyClass.cs @@ -0,0 +1,9 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using System; +namespace MyClassLibrary { + public class MyClass { + public MyClass () + { + } + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs deleted file mode 120000 index 082d90ff1d72..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs +++ /dev/null @@ -1 +0,0 @@ -../StructsAndEnums.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs new file mode 100644 index 000000000000..891d49cd9ecb --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/macOS/StructsAndEnums.cs @@ -0,0 +1,7 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +namespace MyClassLibrary { + public struct MyStruct { + public int A; + public int B; + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs deleted file mode 120000 index f0f219820ed4..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs +++ /dev/null @@ -1 +0,0 @@ -../ApiDefinition.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs new file mode 100644 index 000000000000..f3a6430670fa --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/ApiDefinition.cs @@ -0,0 +1,8 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using Foundation; + +namespace MyApiDefinition { + [BaseType (typeof (NSObject))] + interface MyNativeClass { + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs deleted file mode 120000 index a8c5f5dd7287..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs +++ /dev/null @@ -1 +0,0 @@ -../MyClass.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs new file mode 100644 index 000000000000..69de7b469b7c --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/MyClass.cs @@ -0,0 +1,9 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +using System; +namespace MyClassLibrary { + public class MyClass { + public MyClass () + { + } + } +} diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs deleted file mode 120000 index 082d90ff1d72..000000000000 --- a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs +++ /dev/null @@ -1 +0,0 @@ -../StructsAndEnums.cs \ No newline at end of file diff --git a/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs new file mode 100644 index 000000000000..891d49cd9ecb --- /dev/null +++ b/tests/dotnet/BindingWithDefaultCompileInclude/tvOS/StructsAndEnums.cs @@ -0,0 +1,7 @@ +/* If this file is modified, remember to copy the changes the corresponding file for all the other platforms */ +namespace MyClassLibrary { + public struct MyStruct { + public int A; + public int B; + } +} diff --git a/tests/dotnet/UnitTests/PackTest.cs b/tests/dotnet/UnitTests/PackTest.cs index aa52a321d141..eaeec492f683 100644 --- a/tests/dotnet/UnitTests/PackTest.cs +++ b/tests/dotnet/UnitTests/PackTest.cs @@ -11,6 +11,7 @@ public class PackTest : TestBaseClass { [TestCase (ApplePlatform.MacCatalyst)] [TestCase (ApplePlatform.TVOS)] [TestCase (ApplePlatform.MacOSX)] + [Category ("AllPlatforms")] public void BindingOldStyle (ApplePlatform platform) { var project = "BindingOldStyle"; @@ -64,6 +65,9 @@ public void BindingFrameworksProject (ApplePlatform platform, bool noBindingEmbe var files = archive.Entries.Select (v => v.FullName).ToHashSet (); var tfm = platform.ToFrameworkWithPlatformVersion (isExecutable: false); var hasSymlinks = noBindingEmbedding && (platform == ApplePlatform.MacCatalyst || platform == ApplePlatform.MacOSX); + Console.WriteLine ($"Got {files.Count ()} files in nupkg:"); + foreach (var file in files) + Console.WriteLine ($" {file}"); if (noBindingEmbedding) { Assert.That (archive.Entries.Count, Is.EqualTo (hasSymlinks ? 6 : 10), $"nupkg file count - {nupkg}"); } else { @@ -97,6 +101,7 @@ public void BindingFrameworksProject (ApplePlatform platform, bool noBindingEmbe [TestCase (ApplePlatform.TVOS, false)] [TestCase (ApplePlatform.MacOSX, true)] [TestCase (ApplePlatform.MacOSX, false)] + [Category ("AllPlatforms")] public void BindingXcFrameworksProject (ApplePlatform platform, bool noBindingEmbedding) { var project = "bindings-xcframework-test"; @@ -129,6 +134,11 @@ public void BindingXcFrameworksProject (ApplePlatform platform, bool noBindingEm var archive = ZipFile.OpenRead (nupkg); var files = archive.Entries.Select (v => v.FullName).ToHashSet (); var tfm = platform.ToFrameworkWithPlatformVersion (isExecutable: false); + + Console.WriteLine ($"Got {files.Count ()} files in nupkg:"); + foreach (var file in files) + Console.WriteLine ($" {file}"); + Assert.That (archive.Entries.Count, Is.EqualTo (noBindingEmbedding ? 6 : 5), $"nupkg file count - {nupkg}"); Assert.That (files, Does.Contain (assemblyName + ".nuspec"), "nuspec"); Assert.That (files, Does.Contain ("_rels/.rels"), ".rels"); @@ -248,6 +258,7 @@ public void BindingCompressedXcFrameworksProject (ApplePlatform platform, bool c [TestCase (ApplePlatform.MacCatalyst)] [TestCase (ApplePlatform.TVOS)] [TestCase (ApplePlatform.MacOSX)] + [Category ("AllPlatforms")] public void LibraryProject (ApplePlatform platform) { var project = "MyClassLibrary"; @@ -265,6 +276,9 @@ public void LibraryProject (ApplePlatform platform) var archive = ZipFile.OpenRead (nupkg); var files = archive.Entries.Select (v => v.FullName).ToHashSet (); + Console.WriteLine ($"Got {files.Count ()} files in nupkg:"); + foreach (var file in files) + Console.WriteLine ($" {file}"); Assert.That (archive.Entries.Count, Is.EqualTo (5), "nupkg file count"); Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec"); Assert.That (files, Does.Contain ("_rels/.rels"), ".rels"); diff --git a/tests/dotnet/UnitTests/ProjectTest.cs b/tests/dotnet/UnitTests/ProjectTest.cs index 30a9a50e4745..5ae33ca447ad 100644 --- a/tests/dotnet/UnitTests/ProjectTest.cs +++ b/tests/dotnet/UnitTests/ProjectTest.cs @@ -96,6 +96,7 @@ public void BuildMyCatalystApp (string runtimeIdentifier) [TestCase ("tvOS")] [TestCase ("macOS")] [TestCase ("MacCatalyst")] + [Category ("AllPlatforms")] public void BuildMyClassLibrary (string platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -109,6 +110,7 @@ public void BuildMyClassLibrary (string platform) [TestCase ("tvOS")] [TestCase ("macOS")] [TestCase ("MacCatalyst")] + [Category ("AllPlatforms")] public void BuildEmbeddedResourcesTest (string platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -141,6 +143,7 @@ public void BuildEmbeddedResourcesTest (string platform) [TestCase ("tvOS")] [TestCase ("macOS")] [TestCase ("MacCatalyst")] + [Category ("AllPlatforms")] public void BuildFSharpLibraryTest (string platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -152,10 +155,10 @@ public void BuildFSharpLibraryTest (string platform) var result = DotNet.AssertBuild (project_path, verbosity); var lines = BinLog.PrintToLines (result.BinLogPath); // Find the resulting binding assembly from the build log - var assemblies = FilterToAssembly (lines, assemblyName); + var assemblies = FilterToAssembly (lines, assemblyName).Distinct (); Assert.That (assemblies, Is.Not.Empty, "Assemblies"); // Make sure there's no other assembly confusing our logic - Assert.That (assemblies.Distinct ().Count (), Is.EqualTo (1), "Unique assemblies"); + Assert.That (assemblies.Count (), Is.EqualTo (1), $"Unique assemblies:\n\t{string.Join ("\n\t", assemblies)}"); var asm = assemblies.First (); Assert.That (asm, Does.Exist, "Assembly existence"); // Verify that there's no resources in the assembly @@ -173,6 +176,7 @@ public void BuildFSharpLibraryTest (string platform) [TestCase (ApplePlatform.TVOS)] [TestCase (ApplePlatform.MacOSX)] [TestCase (ApplePlatform.MacCatalyst)] + [Category ("AllPlatforms")] public void BuildBindingsTest (ApplePlatform platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -206,6 +210,7 @@ public void BuildBindingsTest (ApplePlatform platform) [TestCase (ApplePlatform.TVOS)] [TestCase (ApplePlatform.MacOSX)] [TestCase (ApplePlatform.MacCatalyst)] + [Category ("AllPlatforms")] public void BuildBindingsTest2 (ApplePlatform platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -236,6 +241,7 @@ public void BuildBindingsTest2 (ApplePlatform platform) [TestCase ("tvOS", "monotouch")] [TestCase ("macOS", "xammac")] [TestCase ("MacCatalyst", "monotouch")] + // [Category ("AllPlatforms")] public void BuildBundledResources (string platform, string prefix) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -257,18 +263,21 @@ public void BuildBundledResources (string platform, string prefix) // Verify that there's one resource in the binding assembly, and its name var ad = AssemblyDefinition.ReadAssembly (asm, new ReaderParameters { ReadingMode = ReadingMode.Deferred }); - Assert.That (ad.MainModule.Resources.Count, Is.EqualTo (3), "3 resources"); // Sort the resources before we assert, since we don't care about the order, and sorted order makes the asserts simpler. - var resources = ad.MainModule.Resources.OrderBy (v => v.Name).ToArray (); - Assert.That (resources [0].Name, Is.EqualTo ($"__{prefix}_content_basn3p08__with__loc.png"), $"__{prefix}_content_basn3p08__with__loc.png"); - Assert.That (resources [1].Name, Is.EqualTo ($"__{prefix}_content_basn3p08.png"), $"__{prefix}_content_basn3p08.png"); - Assert.That (resources [2].Name, Is.EqualTo ($"__{prefix}_content_xamvideotest.mp4"), $"__{prefix}_content_xamvideotest.mp4"); + var resources = ad.MainModule.Resources.OrderBy (v => v.Name).Select (v => v.Name).ToArray (); + var expectedResources = new string [] { + $"__{prefix}_content_basn3p08__with__loc.png", + $"__{prefix}_content_basn3p08.png", + $"__{prefix}_content_xamvideotest.mp4", + }; + Assert.That (resources, Is.EqualTo (expectedResources), "Resources"); } [TestCase ("iOS")] [TestCase ("tvOS")] [TestCase ("macOS")] [TestCase ("MacCatalyst")] + // [Category ("AllPlatforms")] // builds a complete app, not just the binding projects, so can only be built on macOS public void BuildInterdependentBindingProjects (string platform) { Configuration.IgnoreIfIgnoredPlatform (platform); @@ -281,21 +290,7 @@ public void BuildInterdependentBindingProjects (string platform) var result = DotNet.AssertBuild (project_path, verbosity); var lines = BinLog.PrintToLines (result.BinLogPath); // Find the resulting binding assembly from the build log - var assemblies = lines. - Select (v => v.Trim ()). - Where (v => { - if (v.Length < 10) - return false; - if (v [0] != '/') - return false; - if (!v.EndsWith ($"{assemblyName}.dll", StringComparison.Ordinal)) - return false; - if (!v.Contains ("/bin/", StringComparison.Ordinal)) - return false; - if (!v.Contains ($"{assemblyName}.app", StringComparison.Ordinal)) - return false; - return true; - }); + var assemblies = FilterToAssembly (lines, assemblyName, true); Assert.That (assemblies, Is.Not.Empty, "Assemblies"); // Make sure there's no other assembly confusing our logic assemblies = assemblies.Distinct (); @@ -400,6 +395,7 @@ public void InvalidRuntimeIdentifiers (ApplePlatform platform, string runtimeIde [TestCase (ApplePlatform.iOS, "ios-arm64", true, null, "Release")] [TestCase (ApplePlatform.iOS, "ios-arm64", true, "PublishTrimmed=true;UseInterpreter=true")] [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64", false)] + [Category ("AllPlatforms")] public void IsNotMacBuild (ApplePlatform platform, string runtimeIdentifiers, bool isDeviceBuild, string? extraProperties = null, string configuration = "Debug") { var project = "MySimpleApp"; @@ -1110,6 +1106,7 @@ public void DoubleBuild (ApplePlatform platform, string runtimeIdentifiers) [TestCase (ApplePlatform.TVOS)] [TestCase (ApplePlatform.MacCatalyst)] [TestCase (ApplePlatform.MacOSX)] + [Category ("AllPlatforms")] public void LibraryReferencingBindingLibrary (ApplePlatform platform) { var project = "LibraryReferencingBindingLibrary"; @@ -1126,6 +1123,23 @@ public void LibraryReferencingBindingLibrary (ApplePlatform platform) Path.Combine ("BindingWithUncompressedResourceBundle.resources", "manifest"), }; + switch (platform) { + case ApplePlatform.iOS: + case ApplePlatform.TVOS: + bindingResourcePackages.Add (Path.Combine ("bindings-framework-test.resources", "XStaticArTest.framework", "XStaticArTest")); + bindingResourcePackages.Add (Path.Combine ("bindings-framework-test.resources", "XStaticObjectTest.framework", "XStaticObjectTest")); + bindingResourcePackages.Add (Path.Combine ("bindings-framework-test.resources", "XTest.framework", "Info.plist")); + bindingResourcePackages.Add (Path.Combine ("bindings-framework-test.resources", "XTest.framework", "XTest")); + bindingResourcePackages.Add (Path.Combine ("bindings-framework-test.resources", "manifest")); + break; + case ApplePlatform.MacCatalyst: + case ApplePlatform.MacOSX: + bindingResourcePackages.Add ("bindings-framework-test.resources.zip"); + break; + } + + DumpFiles (bindir); + foreach (var brp in bindingResourcePackages) { var file = Path.Combine (bindir, brp); Assert.That (file, Does.Exist, "Existence"); @@ -1263,6 +1277,14 @@ public void LibraryReferencingBindingLibrary (ApplePlatform platform) } } + void DumpFiles (string dir) + { + var files = Directory.GetFileSystemEntries (dir, "*", SearchOption.AllDirectories).ToArray (); + Console.WriteLine ($"DumpFiles ({dir}): {files.Length} files:"); + foreach (var file in files) + Console.WriteLine ($" {file}"); + } + void AssertAppContents (ApplePlatform platform, string app_directory) { var info_plist_path = GetInfoPListPath (platform, app_directory); @@ -1289,21 +1311,66 @@ void AssertAppContents (ApplePlatform platform, string app_directory) Assert.That (libxamarin, Has.Length.LessThanOrEqualTo (1), $"No more than one libxamarin should be present, but found {libxamarin.Length}:\n\t{string.Join ("\n\t", libxamarin)}"); } - IEnumerable FilterToAssembly (IEnumerable lines, string assemblyName) + IEnumerable FilterToAssembly (IEnumerable lines, string assemblyName, bool doAppCheckInsteadOfRefCheck = false) + { + var rv = FilterToAssembly2 (lines, assemblyName, false, doAppCheckInsteadOfRefCheck); + if (!rv.Any ()) { + Console.WriteLine ($"Could not find any matching lines of {lines.Count ()} lines matching {assemblyName}"); + rv = FilterToAssembly2 (lines, assemblyName, true, doAppCheckInsteadOfRefCheck); + } + return rv; + } + + IEnumerable FilterToAssembly2 (IEnumerable lines, string assemblyName, bool log, bool doAppCheckInsteadOfRefCheck = false) { return lines. Select (v => v.Trim ()). Where (v => { - if (v.Length < 10) - return false; - if (v [0] != '/' && !(char.IsAsciiLetter (v [0]) && v [1] == ':')) + if (v.Length < 10) { + if (log) + Console.WriteLine ($" 1: {v}"); return false; - if (!v.EndsWith ($"{assemblyName}.dll", StringComparison.Ordinal)) + } + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { + if (v [1] != ':') { + if (log) + Console.WriteLine ($" 2a: {v}"); + return false; + } + } else { + if (v [0] != '/') { + if (log) + Console.WriteLine ($" 2b: {v}"); + return false; + } + } + if (!v.EndsWith ($"{assemblyName}.dll", StringComparison.Ordinal)) { + if (log) + Console.WriteLine ($" 3: {v}"); return false; - if (!(v.Contains ("/bin/", StringComparison.Ordinal) || v.Contains ("\\bin\\", StringComparison.Ordinal))) + } + if (!(v.Contains ("/bin/", StringComparison.Ordinal) || v.Contains ("\\bin\\", StringComparison.Ordinal))) { + if (log) + Console.WriteLine ($" 4: {v}"); return false; - if (v.Contains ("/ref/", StringComparison.Ordinal) || v.Contains ("\\ref\\", StringComparison.Ordinal)) + } + if (!doAppCheckInsteadOfRefCheck && v.Contains (Path.DirectorySeparatorChar + "ref" + Path.DirectorySeparatorChar, StringComparison.Ordinal)) { + if (log) + Console.WriteLine ($" 5a: {v}"); return false; // Skip reference assemblies + } + if (doAppCheckInsteadOfRefCheck && !v.Contains ($"{assemblyName}.app", StringComparison.Ordinal)) { + if (log) + Console.WriteLine ($" 5b: {v}"); + return false; + } + if (!File.Exists (v)) { + if (log) + Console.WriteLine ($" 6: {v}"); + return false; + } + + Console.WriteLine ($" YAY 7: {v}"); return true; }); } diff --git a/tools/common/FileCopier.cs b/tools/common/FileCopier.cs index 9c5de9884744..f4299e05187a 100644 --- a/tools/common/FileCopier.cs +++ b/tools/common/FileCopier.cs @@ -134,7 +134,66 @@ static void UpdateDirectory (string source, string target) ReportError (1022, Errors.MT1022, source, target, err, strerror (err)); } + static bool? use_managed_copying; + static bool UseManagedCopying { + get { + if (!use_managed_copying.HasValue) { + if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_USE_MANAGED_UPDATE_DIRECTORY"))) { + use_managed_copying = true; + } else if (Environment.OSVersion.Platform == PlatformID.Win32NT) { + use_managed_copying = true; + } else { + use_managed_copying = false; + } + } + return use_managed_copying.Value; + } + } + static bool TryUpdateDirectory (string source, string target, out int errno) + { + if (UseManagedCopying) + return TryUpdateDirectoryWindows (source, target, out errno); + return TryUpdateDirectoryMacOS (source, target, out errno); + } + + static bool TryUpdateDirectoryWindows (string source, string target, out int errno) + { + Log (1, $"TryUpdateDirectoryWindows ({source}, {target})"); + errno = 0; + Directory.CreateDirectory (target); + + var rv = true; + var attr = File.GetAttributes (source); + if (attr.HasFlag (FileAttributes.Directory)) { + var dir = new DirectoryInfo (source); + foreach (var sourceFile in dir.GetFiles ()) { + var sourcePath = sourceFile.FullName; + var targetPath = Path.Combine (target, Path.GetFileName (source), sourceFile.Name); + CopyIfNeeded (sourcePath, targetPath); + } + foreach (var subdir in dir.GetDirectories ()) { + rv &= TryUpdateDirectoryWindows (Path.Combine (source, subdir.Name), Path.Combine (target, Path.GetFileName (source)), out errno); + } + } else { + var targetPath = Path.Combine (target, Path.GetFileName (source)); + CopyIfNeeded (source, targetPath); + } + return rv; + } + + static void CopyIfNeeded (string source, string target) + { + if (IsUptodate (source, target)) { + Log (3, "Target '{0}' is up-to-date", target); + } else { + Directory.CreateDirectory (Path.GetDirectoryName (target)!); + File.Copy (source, target, true); + Log (1, "Copied {0} to {1}", source, target); + } + } + + static bool TryUpdateDirectoryMacOS (string source, string target, out int errno) { Directory.CreateDirectory (target); diff --git a/tools/common/PathUtils.cs b/tools/common/PathUtils.cs index f3bb302c3a02..19dcc31df8fe 100644 --- a/tools/common/PathUtils.cs +++ b/tools/common/PathUtils.cs @@ -348,6 +348,10 @@ static int lstat (string path, out Stat buf) public static bool IsSymlink (string file) { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { + var attr = File.GetAttributes (file); + return attr.HasFlag (FileAttributes.ReparsePoint); + } Stat buf; var rv = lstat (file, out buf); if (rv != 0) diff --git a/tools/devops/automation/scripts/run-local-windows-tests.ps1 b/tools/devops/automation/scripts/run-local-windows-tests.ps1 index 9cdc714ffd1f..349192bae91c 100644 --- a/tools/devops/automation/scripts/run-local-windows-tests.ps1 +++ b/tools/devops/automation/scripts/run-local-windows-tests.ps1 @@ -15,7 +15,7 @@ $Env:XMA_PASSWORD = "" & $Env:DOTNET ` test ` "$Env:BUILD_SOURCESDIRECTORY/$Env:BUILD_REPOSITORY_TITLE/tests/dotnet/UnitTests/DotNetUnitTests.csproj" ` - --filter Category=Windows ` + --filter "Category=Windows|Category=AllPlatforms" ` --verbosity quiet ` --settings $Env:BUILD_SOURCESDIRECTORY/$Env:BUILD_REPOSITORY_TITLE/tests/dotnet/Windows/config.runsettings ` "--results-directory:$Env:BUILD_SOURCESDIRECTORY/$Env:BUILD_REPOSITORY_TITLE/jenkins-results/windows-remote-tests/" `