diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets
index 635443931e..333eaf401f 100644
--- a/dotnet/targets/Xamarin.Shared.Sdk.targets
+++ b/dotnet/targets/Xamarin.Shared.Sdk.targets
@@ -137,6 +137,7 @@
PlatformAssembly=$(_PlatformAssemblyName).dll
SdkVersion=$(_SdkVersion)
TargetArchitectures=$(TargetArchitectures)
+ TargetFramework=$(_ComputedTargetFrameworkMoniker)
Verbosity=$(_BundlerVerbosity)
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data "LinkerOptionsFile=$(_CustomLinkerOptionsFile)"
@@ -181,6 +182,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -315,8 +328,9 @@
))]
@@ -84,7 +84,7 @@ namespace Registrar {
}
abstract partial class Registrar {
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
public Application App { get; protected set; }
#endif
@@ -124,7 +124,7 @@ namespace Registrar {
public bool IsInformalProtocol;
public bool IsWrapper;
public bool IsGeneric;
-#if !MTOUCH && !MMP
+#if !MTOUCH && !MMP && !BUNDLER
public IntPtr Handle;
#else
public TType ProtocolWrapperType;
@@ -140,7 +140,7 @@ namespace Registrar {
public bool IsCategory { get { return CategoryAttribute != null; } }
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
HashSet all_protocols;
// This contains all protocols in the type hierarchy.
// Given a type T that implements a protocol with super protocols:
@@ -585,7 +585,7 @@ namespace Registrar {
}
}
-#if !MMP && !MTOUCH
+#if !MMP && !MTOUCH && !BUNDLER
// The ArgumentSemantic enum is public, and
// I don't want to add another enum value there which
// is just an internal implementation detail, so just
@@ -832,7 +832,7 @@ namespace Registrar {
if (trampoline != Trampoline.None)
return trampoline;
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
throw ErrorHelper.CreateError (8018, Errors.MT8018);
#else
var mi = (System.Reflection.MethodInfo) Method;
@@ -1001,7 +1001,7 @@ namespace Registrar {
}
internal class ObjCField : ObjCMember {
-#if !MTOUCH && !MMP
+#if !MTOUCH && !MMP && !BUNDLER
public int Size;
public byte Alignment;
#else
@@ -1259,7 +1259,7 @@ namespace Registrar {
#if MONOMAC
internal const string AssemblyName = "Xamarin.Mac";
#else
-#if MTOUCH
+#if MTOUCH || BUNDLER
internal string AssemblyName
{
get {
@@ -1305,7 +1305,7 @@ namespace Registrar {
}
}
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
// "#if MTOUCH" code does not need locking when accessing 'types', because mtouch is single-threaded.
public Dictionary Types {
get { return types; }
@@ -1884,7 +1884,7 @@ namespace Registrar {
protected bool SupportsModernObjectiveC {
get {
-#if MTOUCH || MONOTOUCH
+#if MTOUCH || MONOTOUCH || BUNDLER
return true;
#elif MMP
return App.Is64Build;
@@ -1935,7 +1935,7 @@ namespace Registrar {
isInformalProtocol = pAttr.IsInformal;
isProtocol = true;
-#if MMP || MTOUCH
+#if MMP || MTOUCH || BUNDLER
if (pAttr.FormalSinceVersion != null && pAttr.FormalSinceVersion > App.SdkVersion)
isInformalProtocol = !isInformalProtocol;
#endif
@@ -1969,7 +1969,7 @@ namespace Registrar {
objcType.VerifyAdoptedProtocolsNames (ref exceptions);
objcType.BaseType = isProtocol ? null : (baseObjCType ?? objcType);
objcType.Protocols = GetProtocols (objcType, ref exceptions);
-#if MMP || MTOUCH
+#if MMP || MTOUCH || BUNDLER
objcType.ProtocolWrapperType = (isProtocol && !isInformalProtocol) ? GetProtocolAttributeWrapperType (objcType.Type) : null;
#endif
objcType.IsWrapper = (isProtocol && !isInformalProtocol) ? (GetProtocolAttributeWrapperType (objcType.Type) != null) : (objcType.RegisterAttribute != null && objcType.RegisterAttribute.IsWrapper);
@@ -2064,7 +2064,7 @@ namespace Registrar {
}
}
-#if MMP || MTOUCH
+#if MMP || MTOUCH || BUNDLER
// Special fields
if (is_first_nonWrapper) {
// static registrar
@@ -2131,7 +2131,7 @@ namespace Registrar {
}
} else {
TMethod method = null;
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
method = attrib.Method;
#endif
var objcMethod = new ObjCMethod (this, objcType, method) {
@@ -2180,7 +2180,7 @@ namespace Registrar {
objcType.Add (new ObjCField () {
DeclaringType = objcType,
Name = ca.Name ?? GetPropertyName (property),
-#if !MTOUCH && !MMP
+#if !MTOUCH && !MMP && !BUNDLER
Size = Is64Bits ? 8 : 4,
Alignment = (byte) (Is64Bits ? 3 : 2),
#endif
@@ -2460,7 +2460,7 @@ namespace Registrar {
if (exceptions.Count > 0) {
Exception ae = exceptions.Count == 1 ? exceptions [0] : new AggregateException (exceptions);
-#if !MTOUCH && !MMP
+#if !MTOUCH && !MMP && !BUNDLER
Runtime.NSLog (ae.ToString ());
#endif
throw ae;
@@ -2689,7 +2689,7 @@ namespace Registrar {
System.Threading.Monitor.Exit (types);
}
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
internal static void NSLog (string format, params object [] args)
{
Console.WriteLine (format, args);
diff --git a/src/ObjCRuntime/RuntimeOptions.cs b/src/ObjCRuntime/RuntimeOptions.cs
index f99690ed17..24acb310ee 100644
--- a/src/ObjCRuntime/RuntimeOptions.cs
+++ b/src/ObjCRuntime/RuntimeOptions.cs
@@ -2,7 +2,7 @@ using System;
using System.IO;
using System.Text;
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
using Mono.Cecil;
using Xamarin.Linker;
#else
@@ -11,7 +11,7 @@ using Foundation;
using ObjCRuntime;
#endif
-#if MMP || MMP_TEST || MTOUCH
+#if MMP || MMP_TEST || MTOUCH || BUNDLER
namespace Xamarin.Bundler {
#else
namespace ObjCRuntime {
@@ -24,7 +24,7 @@ namespace ObjCRuntime {
string http_message_handler;
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
/*
* This section is only used by the tools
*/
diff --git a/tests/bindings-test/dotnet/shared.targets b/tests/bindings-test/dotnet/shared.targets
index 76425ccb68..ffc5acd1e7 100644
--- a/tests/bindings-test/dotnet/shared.targets
+++ b/tests/bindings-test/dotnet/shared.targets
@@ -45,7 +45,7 @@
Registrar.cs
-
+
TestRuntime.cs
diff --git a/tests/bindings-test2/dotnet/iOS/bindings-test2.csproj b/tests/bindings-test2/dotnet/iOS/bindings-test2.csproj
index 5a7c3cbd34..662296c7d1 100644
--- a/tests/bindings-test2/dotnet/iOS/bindings-test2.csproj
+++ b/tests/bindings-test2/dotnet/iOS/bindings-test2.csproj
@@ -3,6 +3,11 @@
ios-fat
iOS
+ ..\..\..
+
+
+
+
diff --git a/tests/bindings-test2/dotnet/macOS/bindings-test2.csproj b/tests/bindings-test2/dotnet/macOS/bindings-test2.csproj
index e4c2fdcd47..43be3f9d00 100644
--- a/tests/bindings-test2/dotnet/macOS/bindings-test2.csproj
+++ b/tests/bindings-test2/dotnet/macOS/bindings-test2.csproj
@@ -3,6 +3,11 @@
macos
macOS
+ ..\..\..
+
+
+
+
diff --git a/tests/bindings-test2/dotnet/shared.targets b/tests/bindings-test2/dotnet/shared.targets
index db29771015..ef600332be 100644
--- a/tests/bindings-test2/dotnet/shared.targets
+++ b/tests/bindings-test2/dotnet/shared.targets
@@ -8,17 +8,10 @@
latest
true
- $(MSBuildThisFileDirectory)\..\..
$(RootTestsDirectory)\bindings-test2
$(RootTestsDirectory)\test-libraries
-
-
-
-
-
-
diff --git a/tests/bindings-test2/dotnet/tvOS/bindings-test2.csproj b/tests/bindings-test2/dotnet/tvOS/bindings-test2.csproj
index de9b244243..9bf780dbaf 100644
--- a/tests/bindings-test2/dotnet/tvOS/bindings-test2.csproj
+++ b/tests/bindings-test2/dotnet/tvOS/bindings-test2.csproj
@@ -3,6 +3,11 @@
tvos-fat
tvOS
+ ..\..\..
+
+
+
+
diff --git a/tests/bindings-test2/dotnet/watchOS/bindings-test2.csproj b/tests/bindings-test2/dotnet/watchOS/bindings-test2.csproj
index 09be0a846b..332cb51a9c 100644
--- a/tests/bindings-test2/dotnet/watchOS/bindings-test2.csproj
+++ b/tests/bindings-test2/dotnet/watchOS/bindings-test2.csproj
@@ -3,6 +3,11 @@
watchos-fat
watchOS
+ ..\..\..
+
+
+
+
diff --git a/tests/dotnet/UnitTests/ProjectTest.cs b/tests/dotnet/UnitTests/ProjectTest.cs
index 8a42171ac4..33e5b67475 100644
--- a/tests/dotnet/UnitTests/ProjectTest.cs
+++ b/tests/dotnet/UnitTests/ProjectTest.cs
@@ -258,11 +258,77 @@ namespace Xamarin.Tests {
Assert.That (ad.MainModule.Resources [0].Name, Is.EqualTo ("libtest2.a"), "libtest2.a");
}
- void CopyDotNetSupportingFiles (string targetDirectory)
+ [TestCase ("iOS")]
+ [TestCase ("tvOS")]
+ // [TestCase ("watchOS")] // No watchOS Touch.Client project for .NET yet
+ // [TestCase ("macOS")] // No macOS Touch.Client project for .NET yet
+ public void BuildInterdependentBindingProjects (string platform)
+ {
+ var assemblyName = "interdependent-binding-projects";
+ var dotnet_bindings_dir = Path.Combine (Configuration.SourceRoot, "tests", assemblyName, "dotnet");
+ var project_dir = Path.Combine (dotnet_bindings_dir, platform);
+ var project_path = Path.Combine (project_dir, $"{assemblyName}.csproj");
+
+ Clean (project_path);
+ CopyDotNetSupportingFiles (dotnet_bindings_dir);
+ CopyDotNetSupportingFiles (dotnet_bindings_dir.Replace (assemblyName, "bindings-test"));
+ CopyDotNetSupportingFiles (dotnet_bindings_dir.Replace (assemblyName, "bindings-test2"));
+ var cleanupSupportFiles = CopyDotNetSupportingFiles (Path.Combine (Configuration.SourceRoot, "external", "Touch.Unit", "Touch.Client/dotnet"));
+ try {
+ var result = DotNet.AssertBuild (project_path, verbosity);
+ var lines = result.StandardOutput.ToString ().Split ('\n');
+ // 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;
+ });
+ Assert.That (assemblies, Is.Not.Empty, "Assemblies");
+ // Make sure there's no other assembly confusing our logic
+ assemblies = assemblies.Distinct ();
+ Assert.That (assemblies.Count (), Is.EqualTo (1), $"Unique assemblies: {string.Join (", ", assemblies)}");
+ var asm = assemblies.First ();
+ Assert.That (asm, Does.Exist, "Assembly existence");
+
+ // Verify that the resources
+ var asmDir = Path.GetDirectoryName (asm);
+ var ad = AssemblyDefinition.ReadAssembly (asm, new ReaderParameters { ReadingMode = ReadingMode.Deferred });
+ Assert.That (ad.MainModule.Resources.Count, Is.EqualTo (0), "0 resources for interdependent-binding-projects.dll");
+
+ var ad1 = AssemblyDefinition.ReadAssembly (Path.Combine (asmDir, "bindings-test.dll"), new ReaderParameters { ReadingMode = ReadingMode.Deferred });
+ Assert.That (ad1.MainModule.Resources.Count, Is.EqualTo (1), "1 resource for bindings-test.dll");
+ Assert.That (ad1.MainModule.Resources [0].Name, Is.EqualTo ("libtest.a"), "libtest.a - bindings-test.dll");
+
+ var ad2 = AssemblyDefinition.ReadAssembly (Path.Combine (asmDir, "bindings-test2.dll"), new ReaderParameters { ReadingMode = ReadingMode.Deferred });
+ Assert.That (ad2.MainModule.Resources.Count, Is.EqualTo (1), "1 resource for bindings-test2.dll");
+ Assert.That (ad2.MainModule.Resources [0].Name, Is.EqualTo ("libtest2.a"), "libtest2.a - bindings-test2.dll");
+ } finally {
+ foreach (var file in cleanupSupportFiles)
+ File.Delete (file);
+ }
+ }
+
+ string[] CopyDotNetSupportingFiles (string targetDirectory)
{
var srcDirectory = Path.Combine (Configuration.SourceRoot, "tests", "dotnet");
- foreach (var fn in new string [] { "global.json", "NuGet.config" })
- File.Copy (Path.Combine (srcDirectory, fn), Path.Combine (targetDirectory, fn), true);
+ var files = new string [] { "global.json", "NuGet.config" };
+ var targets = new string [files.Length];
+ for (var i = 0; i < files.Length; i++) {
+ var fn = files [i];
+ targets [i] = Path.Combine (targetDirectory, fn);
+ File.Copy (Path.Combine (srcDirectory, fn), targets [i], true);
+ }
+ return targets;
}
void AssertThatLinkerExecuted (ExecutionResult result)
diff --git a/tests/interdependent-binding-projects/dotnet/.gitignore b/tests/interdependent-binding-projects/dotnet/.gitignore
new file mode 100644
index 0000000000..71d64b8653
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/.gitignore
@@ -0,0 +1,3 @@
+global.json
+NuGet.config
+
diff --git a/tests/interdependent-binding-projects/dotnet/iOS/Info.plist b/tests/interdependent-binding-projects/dotnet/iOS/Info.plist
new file mode 100644
index 0000000000..0c59aa4d9d
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/iOS/Info.plist
@@ -0,0 +1,19 @@
+
+
+
+
+ CFBundleDisplayName
+ InterdependentBindingProject
+ CFBundleIdentifier
+ com.xamarin.dotnet.interdependentbindingprojects
+ CFBundleName
+ InterdependentBindingProject
+ MinimumOSVersion
+ 7.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/iOS/interdependent-binding-projects.csproj b/tests/interdependent-binding-projects/dotnet/iOS/interdependent-binding-projects.csproj
new file mode 100644
index 0000000000..2f752a63f4
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/iOS/interdependent-binding-projects.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net5.0
+ Exe
+ true
+ latest
+ ios-x64
+ xamarinios10;$(AssetTargetFallback)
+ ..\..\..\
+
+ $(DefaultItemExcludes);packages/**;
+ $(RootTestsDirectory)\..\product.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/macOS/Info.plist b/tests/interdependent-binding-projects/dotnet/macOS/Info.plist
new file mode 100644
index 0000000000..3a70a4c319
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/macOS/Info.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ CFBundleDisplayName
+ InterdependentBindingProject
+ CFBundleIdentifier
+ com.xamarin.dotnet.interdependentbindingprojects
+ CFBundleName
+ CFBundleIdentifier
+ LSMinimumSystemVersion
+ 10.9
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/macOS/interdependent-binding-projects.csproj b/tests/interdependent-binding-projects/dotnet/macOS/interdependent-binding-projects.csproj
new file mode 100644
index 0000000000..9b8c2d5528
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/macOS/interdependent-binding-projects.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net5.0
+ Exe
+ true
+ latest
+ osx-x64
+ ..\..\..\
+
+ $(DefaultItemExcludes);packages/**;
+ $(RootTestsDirectory)\..\product.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/tvOS/Info.plist b/tests/interdependent-binding-projects/dotnet/tvOS/Info.plist
new file mode 100644
index 0000000000..361708d682
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/tvOS/Info.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleDisplayName
+ InterdependentBindingProject
+ CFBundleIdentifier
+ com.xamarin.dotnet.interdependentbindingprojects
+ CFBundleName
+ InterdependentBindingProject
+ MinimumOSVersion
+ 9.0
+ UIDeviceFamily
+
+ 3
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/tvOS/interdependent-binding-projects.csproj b/tests/interdependent-binding-projects/dotnet/tvOS/interdependent-binding-projects.csproj
new file mode 100644
index 0000000000..7629282f02
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/tvOS/interdependent-binding-projects.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net5.0
+ Exe
+ true
+ latest
+ tvos-x64
+ xamarintvos10;$(AssetTargetFallback)
+ ..\..\..\
+
+ $(DefaultItemExcludes);packages/**;
+ $(RootTestsDirectory)\..\product.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/watchOS/Info.plist b/tests/interdependent-binding-projects/dotnet/watchOS/Info.plist
new file mode 100644
index 0000000000..710fcccd29
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/watchOS/Info.plist
@@ -0,0 +1,35 @@
+
+
+
+
+ CFBundleDisplayName
+ InterdependentBindingProject
+ CFBundleIdentifier
+ com.xamarin.dotnet.interdependentbindingprojects_watch.watchkitapp.watchkitextension
+ CFBundleName
+ InterdependentBindingProject
+ MinimumOSVersion
+ 2.0
+ UIDeviceFamily
+
+ 4
+
+ RemoteInterfacePrincipleClass
+ InterfaceController
+ NSExtension
+
+ NSExtensionAttributes
+
+ WKAppBundleIdentifier
+ com.xamarin.dotnet.interdependentbindingprojects_watch.watchkitapp
+
+ NSExtensionPointIdentifier
+ com.apple.watchkit
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+
+
diff --git a/tests/interdependent-binding-projects/dotnet/watchOS/interdependent-binding-projects.csproj b/tests/interdependent-binding-projects/dotnet/watchOS/interdependent-binding-projects.csproj
new file mode 100644
index 0000000000..76227cb41e
--- /dev/null
+++ b/tests/interdependent-binding-projects/dotnet/watchOS/interdependent-binding-projects.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net5.0
+ Exe
+ true
+ latest
+ watchos-x86
+ ..\..\..\
+
+ $(DefaultItemExcludes);packages/**;
+ $(RootTestsDirectory)\..\product.snk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/xharness/Harness.cs b/tests/xharness/Harness.cs
index c2bb0ba34b..23afae1056 100644
--- a/tests/xharness/Harness.cs
+++ b/tests/xharness/Harness.cs
@@ -371,7 +371,7 @@ namespace Xharness {
void AutoConfigureIOS ()
{
- var test_suites = new string [] { "monotouch-test", "framework-test", "interdependent-binding-projects" };
+ var test_suites = new string [] { "monotouch-test", "framework-test" };
var library_projects = new string [] { "BundledResources", "EmbeddedResources", "bindings-test2", "bindings-framework-test" };
var fsharp_test_suites = new string [] { "fsharp" };
var fsharp_library_projects = new string [] { "fsharplibrary" };
@@ -387,6 +387,8 @@ namespace Xharness {
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "bindings-test", "iOS", "bindings-test.csproj")), false) { Name = "bindings-test" });
+ IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "interdependent-binding-projects", "interdependent-binding-projects.csproj"))) { Name = "interdependent-binding-projects" });
+ IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "interdependent-binding-projects", "dotnet", "iOS", "interdependent-binding-projects.csproj"))) { Name = "interdependent-binding-projects", IsDotNetProject = true, SkipiOSVariation = false, SkiptvOSVariation = true, SkipwatchOSVariation = true, SkipTodayExtensionVariation = true, SkipDeviceVariations = true, SkipiOS32Variation = true, });
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "introspection", "iOS", "introspection-ios.csproj"))) { Name = "introspection" });
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "introspection", "iOS", "introspection-ios-dotnet.csproj"))) { Name = "introspection", IsDotNetProject = true, SkipiOSVariation = false, SkiptvOSVariation = false, SkipwatchOSVariation = true, SkipTodayExtensionVariation = true, SkipDeviceVariations = true, SkipiOS32Variation = true, });
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "linker", "ios", "dont link", "dont link.csproj"))) { Configurations = new string [] { "Debug", "Release" } });
diff --git a/tests/xharness/Jenkins/Jenkins.cs b/tests/xharness/Jenkins/Jenkins.cs
index 281764cf85..2007e2d15b 100644
--- a/tests/xharness/Jenkins/Jenkins.cs
+++ b/tests/xharness/Jenkins/Jenkins.cs
@@ -223,7 +223,7 @@ namespace Xharness.Jenkins {
TestProject = buildDotNetTestsProject,
Platform = TestPlatform.All,
TestName = "DotNet tests",
- Timeout = TimeSpan.FromMinutes (5),
+ Timeout = TimeSpan.FromMinutes (15),
Ignored = !IncludeDotNet,
};
Tasks.Add (runDotNetTests);
diff --git a/tests/xharness/Jenkins/MacTestTasksEnumerable.cs b/tests/xharness/Jenkins/MacTestTasksEnumerable.cs
index 0bdadab2d6..c56b7d5e7a 100644
--- a/tests/xharness/Jenkins/MacTestTasksEnumerable.cs
+++ b/tests/xharness/Jenkins/MacTestTasksEnumerable.cs
@@ -81,7 +81,7 @@ namespace Xharness.Jenkins {
foreach (var config in configurations) {
MSBuildTask build = new MSBuildTask (jenkins: jenkins, testProject: project, processManager: processManager);
build.Platform = platform;
- build.CloneTestProject (jenkins.MainLog, processManager, project);
+ build.CloneTestProject (jenkins.MainLog, processManager, project, HarnessConfiguration.RootDirectory);
build.ProjectConfiguration = config;
build.ProjectPlatform = project.Platform;
build.SpecifyPlatform = false;
diff --git a/tests/xharness/Jenkins/RunDeviceTasksFactory.cs b/tests/xharness/Jenkins/RunDeviceTasksFactory.cs
index 222bbef5a3..b94a5291be 100644
--- a/tests/xharness/Jenkins/RunDeviceTasksFactory.cs
+++ b/tests/xharness/Jenkins/RunDeviceTasksFactory.cs
@@ -52,7 +52,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.iOS_Unified64,
TestName = project.Name,
};
- build64.CloneTestProject (jenkins.MainLog, processManager, project);
+ build64.CloneTestProject (jenkins.MainLog, processManager, project, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
@@ -69,7 +69,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.iOS_Unified32,
TestName = project.Name,
};
- build32.CloneTestProject (jenkins.MainLog, processManager, project);
+ build32.CloneTestProject (jenkins.MainLog, processManager, project, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
@@ -88,7 +88,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.iOS_TodayExtension64,
TestName = project.Name,
};
- buildToday.CloneTestProject (jenkins.MainLog, processManager, todayProject);
+ buildToday.CloneTestProject (jenkins.MainLog, processManager, todayProject, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
@@ -109,7 +109,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.tvOS,
TestName = project.Name,
};
- buildTV.CloneTestProject (jenkins.MainLog, processManager, tvOSProject);
+ buildTV.CloneTestProject (jenkins.MainLog, processManager, tvOSProject, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
@@ -130,7 +130,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.watchOS_32,
TestName = project.Name,
};
- buildWatch32.CloneTestProject (jenkins.MainLog, processManager, watchOSProject);
+ buildWatch32.CloneTestProject (jenkins.MainLog, processManager, watchOSProject, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
@@ -149,7 +149,7 @@ namespace Xharness.Jenkins {
Platform = TestPlatform.watchOS_64_32,
TestName = project.Name,
};
- buildWatch64_32.CloneTestProject (jenkins.MainLog, processManager, watchOSProject);
+ buildWatch64_32.CloneTestProject (jenkins.MainLog, processManager, watchOSProject, HarnessConfiguration.RootDirectory);
projectTasks.Add (new RunDeviceTask (
jenkins: jenkins,
devices: jenkins.Devices,
diff --git a/tests/xharness/Jenkins/RunSimulatorTasksFactory.cs b/tests/xharness/Jenkins/RunSimulatorTasksFactory.cs
index 5209ed75a3..716553721b 100644
--- a/tests/xharness/Jenkins/RunSimulatorTasksFactory.cs
+++ b/tests/xharness/Jenkins/RunSimulatorTasksFactory.cs
@@ -74,7 +74,7 @@ namespace Xharness.Jenkins {
derived.Ignored = configIgnored;
derived.TestName = project.Name;
derived.Dependency = project.Dependency;
- derived.CloneTestProject (jenkins.MainLog, processManager, pair.Item1);
+ derived.CloneTestProject (jenkins.MainLog, processManager, pair.Item1, HarnessConfiguration.RootDirectory);
var simTasks = CreateAsync (jenkins, processManager, derived);
runSimulatorTasks.AddRange (simTasks);
foreach (var task in simTasks) {
diff --git a/tests/xharness/Jenkins/TestVariationsFactory.cs b/tests/xharness/Jenkins/TestVariationsFactory.cs
index 21c3349f72..3853f8096a 100644
--- a/tests/xharness/Jenkins/TestVariationsFactory.cs
+++ b/tests/xharness/Jenkins/TestVariationsFactory.cs
@@ -160,7 +160,7 @@ namespace Xharness.Jenkins {
var clone = task.TestProject.Clone ();
var clone_task = Task.Run (async () => {
await task.BuildTask.InitialTask; // this is the project cloning above
- await clone.CreateCopyAsync (jenkins.MainLog, processManager, task);
+ await clone.CreateCopyAsync (jenkins.MainLog, processManager, task, HarnessConfiguration.RootDirectory);
var isMac = task.Platform.IsMac ();
var canSymlink = task.Platform.CanSymlink();
diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Tasks/TestTask.cs b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Tasks/TestTask.cs
index bd37eb489b..672cf23d50 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Tasks/TestTask.cs
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Tasks/TestTask.cs
@@ -242,7 +242,7 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Tasks {
return Task.CompletedTask;
}
- public void CloneTestProject (ILog log, IProcessManager processManager, TestProject project)
+ public void CloneTestProject (ILog log, IProcessManager processManager, TestProject project, string rootDirectory)
{
// Don't build in the original project directory
// We can build multiple projects in parallel, and if some of those
@@ -252,7 +252,7 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Tasks {
// So we clone the project file to a separate directory and build there instead.
// This is done asynchronously to speed to the initial test load.
TestProject = project.Clone ();
- InitialTask = TestProject.CreateCopyAsync (log, processManager, this);
+ InitialTask = TestProject.CreateCopyAsync (log, processManager, this, rootDirectory);
}
protected Stopwatch waitingDuration = new Stopwatch ();
diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestProject.cs b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestProject.cs
index 04300aaa41..fe10b822ee 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestProject.cs
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/TestProject.cs
@@ -69,14 +69,20 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared {
return rv;
}
- internal async Task CreateCloneAsync (ILog log, IProcessManager processManager, ITestTask test)
+ internal async Task CreateCloneAsync (ILog log, IProcessManager processManager, ITestTask test, string rootDirectory)
{
var rv = Clone ();
- await rv.CreateCopyAsync (log, processManager, test);
+ await rv.CreateCopyAsync (log, processManager, test, rootDirectory);
return rv;
}
- public async Task CreateCopyAsync (ILog log, IProcessManager processManager, ITestTask test)
+ public Task CreateCopyAsync (ILog log, IProcessManager processManager, ITestTask test, string rootDirectory)
+ {
+ var pr = new Dictionary ();
+ return CreateCopyAsync (log, processManager, test, rootDirectory, pr);
+ }
+
+ async Task CreateCopyAsync (ILog log, IProcessManager processManager, ITestTask test, string rootDirectory, Dictionary allProjectReferences)
{
var directory = DirectoryUtilities.CreateTemporaryDirectory (test?.TestName ?? System.IO.Path.GetFileNameWithoutExtension (Path));
Directory.CreateDirectory (directory);
@@ -89,7 +95,7 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared {
doc = new XmlDocument ();
doc.LoadWithoutNetworkAccess (original_path);
var original_name = System.IO.Path.GetFileName (original_path);
- doc.ResolveAllPaths (original_path);
+ doc.ResolveAllPaths (original_path, rootDirectory);
if (doc.IsDotNetProject ()) {
if (doc.GetEnableDefaultItems () != false) {
@@ -154,8 +160,12 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared {
var projectReferences = new List ();
foreach (var pr in doc.GetProjectReferences ()) {
- var tp = new TestProject (pr.Replace ('\\', '/'));
- await tp.CreateCopyAsync (log, processManager, test);
+ var prPath = pr.Replace ('\\', '/');
+ if (!allProjectReferences.TryGetValue (prPath, out var tp)) {
+ tp = new TestProject (pr.Replace ('\\', '/'));
+ await tp.CreateCopyAsync (log, processManager, test, rootDirectory, allProjectReferences);
+ allProjectReferences.Add (prPath, tp);
+ }
doc.SetProjectReferenceInclude (pr, tp.Path.Replace ('/', '\\'));
projectReferences.Add (tp);
}
diff --git a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs
index f935757b1f..6d35e5a682 100644
--- a/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs
+++ b/tests/xharness/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs
@@ -912,7 +912,7 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Utilities {
}
}
- public static void ResolveAllPaths (this XmlDocument csproj, string project_path)
+ public static void ResolveAllPaths (this XmlDocument csproj, string project_path, string rootDirectory = null)
{
var dir = System.IO.Path.GetDirectoryName (project_path);
var nodes_with_paths = new string []
@@ -942,7 +942,7 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Utilities {
new string [] { "ObjcBindingCoreSource", "Include" },
new string [] { "ObjcBindingNativeLibrary", "Include" },
new string [] { "ObjcBindingNativeFramework", "Include" },
- new string [] { "Import", "Project", "CustomBuildActions.targets" },
+ new string [] { "Import", "Project", "CustomBuildActions.targets", "..\\shared.targets" },
new string [] { "FilesToCopy", "Include" },
new string [] { "FilesToCopyFoo", "Include" },
new string [] { "FilesToCopyFooBar", "Include" },
@@ -967,6 +967,10 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Utilities {
if (input.StartsWith ("$(MSBuildBinPath)", StringComparison.Ordinal))
return input; // This is already a full path.
input = input.Replace ('\\', '/'); // make unix-style
+
+ if (rootDirectory != null)
+ input = input.Replace ("$(RootTestsDirectory)", rootDirectory);
+
input = System.IO.Path.GetFullPath (System.IO.Path.Combine (dir, input));
input = input.Replace ('/', '\\'); // make windows-style again
return input;
@@ -1064,9 +1068,12 @@ namespace Microsoft.DotNet.XHarness.iOS.Shared.Utilities {
foreach (var prop in properties)
args.Add ($"/p:{prop.Key}={prop.Value}");
args.Add (inspector);
+ var env = new Dictionary {
+ { "MSBUILD_EXE_PATH", null },
+ };
proc.StartInfo.Arguments = StringUtils.FormatArguments (args);
proc.StartInfo.WorkingDirectory = dir;
- var rv = await processManager.RunAsync (proc, log, timeout: TimeSpan.FromSeconds (15));
+ var rv = await processManager.RunAsync (proc, log, environment_variables: env, timeout: TimeSpan.FromSeconds (15));
if (!rv.Succeeded)
throw new Exception ($"Unable to evaluate the property {evaluateProperty}.");
return File.ReadAllText (output).Trim ();
diff --git a/tests/xharness/Targets/Target.cs b/tests/xharness/Targets/Target.cs
index 581fe6a1fb..9136db1d9e 100644
--- a/tests/xharness/Targets/Target.cs
+++ b/tests/xharness/Targets/Target.cs
@@ -199,6 +199,7 @@ namespace Xharness.Targets
protected void CreateLibraryProject ()
{
ProcessProject ();
+ inputProject.ResolveAllPaths (TemplateProjectPath);
inputProject.Save (ProjectPath, (l, m) => Harness.Log (l,m));
ProjectGuid = inputProject.GetProjectGuid ();
diff --git a/tests/xharness/Targets/TodayExtensionTarget.cs b/tests/xharness/Targets/TodayExtensionTarget.cs
index 552b850d8a..aa3c68d178 100644
--- a/tests/xharness/Targets/TodayExtensionTarget.cs
+++ b/tests/xharness/Targets/TodayExtensionTarget.cs
@@ -51,6 +51,7 @@ namespace Xharness.Targets {
TodayContainerGuid = "{" + Helpers.GenerateStableGuid ().ToString ().ToUpper () + "}";
ProjectGuid = TodayContainerGuid;
csproj.SetProjectGuid (TodayContainerGuid);
+ csproj.ResolveAllPaths (Harness.TodayContainerTemplate);
csproj.Save(TodayContainerProjectPath, (l, m) => Harness.Log (l,m));
XmlDocument info_plist = new XmlDocument ();
@@ -79,7 +80,7 @@ namespace Xharness.Targets {
csproj.AddInterfaceDefinition (Path.Combine (Harness.TodayExtensionTemplate, "TodayView.storyboard").Replace ('/', '\\'));
csproj.SetExtraLinkerDefs ("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml");
csproj.FixProjectReferences (Path.Combine (ProjectsDir, GetTargetSpecificDir ()), "-today", FixProjectReference);
-
+ csproj.ResolveAllPaths (TemplateProjectPath);
csproj.Save (TodayExtensionProjectPath, (l,m) => Harness.Log (l,m));
TodayExtensionGuid = csproj.GetProjectGuid ();
diff --git a/tools/common/Application.cs b/tools/common/Application.cs
index c2abfc10af..7bccce1923 100644
--- a/tools/common/Application.cs
+++ b/tools/common/Application.cs
@@ -16,8 +16,12 @@ using ObjCRuntime;
#if MONOTOUCH
using PlatformResolver = MonoTouch.Tuner.MonoTouchResolver;
-#else
+#elif MMP
using PlatformResolver = Xamarin.Bundler.MonoMacResolver;
+#elif NET
+using PlatformResolver = Xamarin.Linker.DotNetResolver;
+#else
+#error Invalid defines
#endif
namespace Xamarin.Bundler {
diff --git a/tools/common/Assembly.cs b/tools/common/Assembly.cs
index 0f3054e8c2..6aceca94f3 100644
--- a/tools/common/Assembly.cs
+++ b/tools/common/Assembly.cs
@@ -55,25 +55,31 @@ namespace Xamarin.Bundler {
public AssemblyDefinition AssemblyDefinition;
public Target Target;
- public bool IsFrameworkAssembly { get { return is_framework_assembly.Value; } }
+ public bool? IsFrameworkAssembly { get { return is_framework_assembly; } }
public string FullPath {
get {
return full_path;
}
set {
full_path = value;
- if (!is_framework_assembly.HasValue) {
+ if (!is_framework_assembly.HasValue && !string.IsNullOrEmpty (full_path)) {
var real_full_path = Target.GetRealPath (full_path);
+#if NET
+ // TODO: Figure out how to determine whether an assembly is a framework assembly or not (but it's not urgent to implement, it's just a performance improvement)
+#else
is_framework_assembly = real_full_path.StartsWith (Path.GetDirectoryName (Path.GetDirectoryName (Target.Resolver.FrameworkDirectory)), StringComparison.Ordinal);
+#endif
}
}
}
public string FileName { get { return Path.GetFileName (FullPath); } }
- public string Identity { get { return GetIdentity (FullPath); } }
+ public string Identity { get { return GetIdentity (AssemblyDefinition); } }
public static string GetIdentity (AssemblyDefinition ad)
{
- return Path.GetFileNameWithoutExtension (ad.MainModule.FileName);
+ if (!string.IsNullOrEmpty (ad.MainModule.FileName))
+ return Path.GetFileNameWithoutExtension (ad.MainModule.FileName);
+ return ad.Name.Name;
}
public static string GetIdentity (string path)
@@ -143,7 +149,7 @@ namespace Xamarin.Bundler {
public void ExtractNativeLinkInfo ()
{
// ignore framework assemblies, they won't have any LinkWith attributes
- if (IsFrameworkAssembly)
+ if (IsFrameworkAssembly == true)
return;
var assembly = AssemblyDefinition;
diff --git a/tools/common/DerivedLinkContext.cs b/tools/common/DerivedLinkContext.cs
index 4b44bc0afe..6e7f3c2e6a 100644
--- a/tools/common/DerivedLinkContext.cs
+++ b/tools/common/DerivedLinkContext.cs
@@ -9,6 +9,10 @@ using Registrar;
using Mono.Tuner;
using Xamarin.Bundler;
+#if NET
+using LinkContext = Xamarin.Bundler.DotNetLinkContext;
+#endif
+
namespace Xamarin.Tuner
{
public class DerivedLinkContext : LinkContext
diff --git a/tools/common/Driver.cs b/tools/common/Driver.cs
index bd42d52b1b..bb9bdebb20 100644
--- a/tools/common/Driver.cs
+++ b/tools/common/Driver.cs
@@ -28,6 +28,7 @@ namespace Xamarin.Bundler {
public static bool Force { get; set; }
static Version min_xcode_version = new Version (6, 0);
+#if !NET
public static int Main (string [] args)
{
try {
@@ -327,6 +328,7 @@ namespace Xamarin.Bundler {
return false;
}
+#endif // !NET
static int Jobs;
public static int Concurrency {
diff --git a/tools/common/Driver.execution.cs b/tools/common/Driver.execution.cs
index 1dde08fa9b..2a6d7e3d1f 100644
--- a/tools/common/Driver.execution.cs
+++ b/tools/common/Driver.execution.cs
@@ -139,7 +139,7 @@ namespace Xamarin.Bundler {
return Task.Run (() => RunCommand (path, args, env, output, output, suppressPrintOnErrors, verbosity ?? Verbosity));
}
-#if !MTOUCH && !MMP
+#if !MTOUCH && !MMP && !BUNDLER
internal static int Verbosity;
#endif
}
diff --git a/tools/common/SdkVersions.cs.in b/tools/common/SdkVersions.cs.in
index c80db22a9a..d7d1fa7a47 100644
--- a/tools/common/SdkVersions.cs.in
+++ b/tools/common/SdkVersions.cs.in
@@ -1,6 +1,6 @@
using System;
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
using Xamarin.Bundler;
using Xamarin.Utils;
#endif
@@ -62,7 +62,7 @@ namespace Xamarin {
public static Version XcodeVersion { get { return new Version (Xcode); }}
-#if MTOUCH || MMP
+#if MTOUCH || MMP || BUNDLER
public static Version GetVersion (Application app)
{
switch (app.Platform) {
diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs
index 24cbd18108..7296f56e01 100644
--- a/tools/common/StaticRegistrar.cs
+++ b/tools/common/StaticRegistrar.cs
@@ -20,6 +20,7 @@ using Registrar;
using Foundation;
using ObjCRuntime;
using Mono.Cecil;
+using Mono.Linker;
using Mono.Tuner;
namespace Registrar {
diff --git a/tools/common/Target.cs b/tools/common/Target.cs
index a54480f470..87368ff872 100644
--- a/tools/common/Target.cs
+++ b/tools/common/Target.cs
@@ -26,10 +26,16 @@ using MonoTouch;
using MonoTouch.Tuner;
using PlatformResolver = MonoTouch.Tuner.MonoTouchResolver;
using PlatformLinkContext = MonoTouch.Tuner.MonoTouchLinkContext;
-#else
+#elif MMP
using MonoMac.Tuner;
using PlatformResolver = Xamarin.Bundler.MonoMacResolver;
using PlatformLinkContext = MonoMac.Tuner.MonoMacLinkContext;
+#elif NET
+using LinkerOptions = Xamarin.Linker.LinkerConfiguration;
+using PlatformLinkContext = Xamarin.Tuner.DerivedLinkContext;
+using PlatformResolver = Xamarin.Linker.DotNetResolver;
+#else
+#error Invalid defines
#endif
namespace Xamarin.Bundler {
@@ -80,6 +86,13 @@ namespace Xamarin.Bundler {
this.StaticRegistrar = new StaticRegistrar (this);
}
+ public Assembly AddAssembly (AssemblyDefinition assembly)
+ {
+ var asm = new Assembly (this, assembly);
+ Assemblies.Add (asm);
+ return asm;
+ }
+
// This will find the link context, possibly looking in container targets.
public PlatformLinkContext GetLinkContext ()
{
diff --git a/tools/common/cache.cs b/tools/common/cache.cs
index 934c8955cc..acc3187744 100644
--- a/tools/common/cache.cs
+++ b/tools/common/cache.cs
@@ -13,6 +13,8 @@ public class Cache {
const string NAME = "mmp";
#elif MTOUCH
const string NAME = "mtouch";
+#elif BUNDLER
+ const string NAME = "dotnet-linker";
#else
#error Wrong defines
#endif
diff --git a/tools/dotnet-linker/Compat.cs b/tools/dotnet-linker/Compat.cs
index 53253a97ce..8ca426c02e 100644
--- a/tools/dotnet-linker/Compat.cs
+++ b/tools/dotnet-linker/Compat.cs
@@ -1,51 +1,109 @@
// Compat.cs: might not be ideal but it eases code sharing with existing code during the initial implementation.
using System;
+using System.Collections.Generic;
+
+using Mono.Cecil;
+using Mono.Linker;
+using Mono.Linker.Steps;
using Xamarin.Linker;
using Xamarin.Utils;
namespace Xamarin.Bundler {
- public class Application {
+ public partial class Application {
public LinkerConfiguration Configuration { get; private set; }
- public Application (LinkerConfiguration configuration)
+ public Application (LinkerConfiguration configuration, string[] arguments)
+ : this (arguments)
{
this.Configuration = configuration;
}
- // This method is needed for ErrorHelper.tools.cs to compile.
- public void LoadSymbols ()
- {
- }
-
- public string GetProductName ()
- {
- switch (Platform) {
- case ApplePlatform.iOS:
- case ApplePlatform.TVOS:
- case ApplePlatform.WatchOS:
- return "Xamarin.iOS";
- case ApplePlatform.MacOSX:
- return "Xamarin.Mac";
- default:
- throw ErrorHelper.CreateError (177, Errors.MX0177 /* "Unknown platform: {0}. This usually indicates a bug; please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new with a test case." */, Platform);
+ public string ProductName {
+ get {
+ switch (Platform) {
+ case ApplePlatform.iOS:
+ return "Microsoft.iOS";
+ case ApplePlatform.TVOS:
+ return "Microsoft.tvOS";
+ case ApplePlatform.WatchOS:
+ return "Microsoft.watchOS";
+ case ApplePlatform.MacOSX:
+ return "Microsoft.macOS";
+ default:
+ throw ErrorHelper.CreateError (177, Errors.MX0177 /* "Unknown platform: {0}. This usually indicates a bug; please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new with a test case." */, Platform);
+ }
}
}
- public Version SdkVersion {
- get { return Configuration.SdkVersion; }
+ public void SelectRegistrar ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public partial class Driver {
+ public static string NAME {
+ get { return "xamarin-bundler"; }
}
- public Version DeploymentTarget {
- get { return Configuration.DeploymentTarget; }
+ public static string GetArch32Directory (Application app)
+ {
+ throw new NotImplementedException ();
}
- public bool IsSimulatorBuild {
- get { return Configuration.IsSimulatorBuild; }
+ public static string GetArch64Directory (Application app)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public class DotNetLinkContext {
+ public DotNetLinkContext ()
+ {
+ throw new NotImplementedException ();
}
- public ApplePlatform Platform {
- get { return Configuration.Platform; }
+ public DotNetLinkContext (Pipeline pipeline, AssemblyResolver resolver)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AssemblyAction UserAction {
+ get { throw new NotImplementedException (); }
+ set { throw new NotImplementedException (); }
+ }
+
+ public AnnotationStore Annotations {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public AssemblyDefinition GetAssembly (string name)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public class Pipeline {
+
+ }
+}
+
+namespace Mono.Linker {
+ public static class LinkContextExtensions {
+ public static void LogMessage (this LinkContext context, string messsage)
+ {
+ throw new NotImplementedException ();
+ }
+ public static IEnumerable GetAssemblies (this LinkContext context)
+ {
+ throw new NotImplementedException ();
+ }
+ public static Dictionary GetCustomAnnotations (this AnnotationStore self, string name)
+ {
+ throw new NotImplementedException ();
}
}
}
diff --git a/tools/dotnet-linker/Constants.cs b/tools/dotnet-linker/Constants.cs
new file mode 100644
index 0000000000..9c51e76ee3
--- /dev/null
+++ b/tools/dotnet-linker/Constants.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Xamarin.Bundler {
+ public static partial class Constants {
+ public static string Version {
+ get { throw new NotImplementedException (); }
+ }
+ internal static string Revision {
+ get { throw new NotImplementedException (); }
+ }
+ public static string SdkVersion {
+ get { throw new NotImplementedException (); }
+ }
+ }
+}
diff --git a/tools/dotnet-linker/DotNetResolver.cs b/tools/dotnet-linker/DotNetResolver.cs
new file mode 100644
index 0000000000..9f51e55ff7
--- /dev/null
+++ b/tools/dotnet-linker/DotNetResolver.cs
@@ -0,0 +1,14 @@
+using System;
+
+using Mono.Cecil;
+
+using Xamarin.Bundler;
+
+namespace Xamarin.Linker {
+ public class DotNetResolver : CoreResolver {
+ public override AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
diff --git a/tools/dotnet-linker/LinkerConfiguration.cs b/tools/dotnet-linker/LinkerConfiguration.cs
index 3dc90438dd..b77bd61c83 100644
--- a/tools/dotnet-linker/LinkerConfiguration.cs
+++ b/tools/dotnet-linker/LinkerConfiguration.cs
@@ -5,11 +5,14 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
+using Mono.Cecil;
using Mono.Linker;
using Xamarin.Bundler;
using Xamarin.Utils;
+using ObjCRuntime;
+
namespace Xamarin.Linker {
public class LinkerConfiguration {
public List Abis;
@@ -27,13 +30,19 @@ namespace Xamarin.Linker {
static ConditionalWeakTable configurations = new ConditionalWeakTable ();
public Application Application { get; private set; }
+ public Target Target { get; private set; }
+
+ public LinkContext Context { get; private set; }
public static LinkerConfiguration GetInstance (LinkContext context)
{
if (!configurations.TryGetValue (context, out var instance)) {
if (!context.TryGetCustomData ("LinkerOptionsFile", out var linker_options_file))
throw new Exception ($"No custom linker options file was passed to the linker (using --custom-data LinkerOptionsFile=...");
- instance = new LinkerConfiguration (linker_options_file);
+ instance = new LinkerConfiguration (linker_options_file) {
+ Context = context,
+ };
+
configurations.Add (context, instance);
}
@@ -46,6 +55,7 @@ namespace Xamarin.Linker {
throw new FileNotFoundException ($"The custom linker file {linker_file} does not exist.");
var lines = File.ReadAllLines (linker_file);
+ var significantLines = new List (); // This is the input the cache uses to verify if the cache is still valid
for (var i = 0; i < lines.Length; i++) {
var line = lines [i].TrimStart ();
if (line.Length == 0 || line [0] == '#')
@@ -55,6 +65,8 @@ namespace Xamarin.Linker {
if (eq == -1)
throw new InvalidOperationException ($"Invalid syntax for line {i + 1} in {linker_file}: No equals sign.");
+ significantLines.Add (line);
+
var key = line [..eq];
var value = line [(eq + 1)..];
@@ -116,6 +128,11 @@ namespace Xamarin.Linker {
Abis.Add (a);
}
break;
+ case "TargetFramework":
+ if (!TargetFramework.TryParse (value, out var tf))
+ throw new InvalidOperationException ($"Invalid TargetFramework '{value}' in {linker_file}");
+ Driver.TargetFramework = TargetFramework.Parse (value);
+ break;
case "Verbosity":
if (!int.TryParse (value, out var verbosity))
throw new InvalidOperationException ($"Invalid Verbosity '{value}' in {linker_file}");
@@ -128,7 +145,29 @@ namespace Xamarin.Linker {
ErrorHelper.Platform = Platform;
- Application = new Application (this);
+ Application = new Application (this, significantLines.ToArray ());
+ Target = new Target (Application);
+
+ Application.Cache.Location = CacheDirectory;
+ Application.DeploymentTarget = DeploymentTarget;
+ Application.SdkVersion = SdkVersion;
+
+ switch (Platform) {
+ case ApplePlatform.iOS:
+ case ApplePlatform.TVOS:
+ case ApplePlatform.WatchOS:
+ Application.BuildTarget = IsSimulatorBuild ? BuildTarget.Simulator : BuildTarget.Device;
+ break;
+ case ApplePlatform.MacOSX:
+ default:
+ break;
+ }
+
+ if (Driver.TargetFramework.Platform != Platform)
+ throw ErrorHelper.CreateError (99, "Inconsistent platforms. TargetFramework={0}, Platform={1}", Driver.TargetFramework.Platform, Platform);
+
+ Driver.Verbosity = Verbosity;
+ ErrorHelper.Verbosity = Verbosity;
}
public void Write ()
@@ -148,6 +187,15 @@ namespace Xamarin.Linker {
}
}
+ public string GetAssemblyFileName (AssemblyDefinition assembly)
+ {
+ // See: https://github.com/mono/linker/issues/1313
+ // Call LinkContext.Resolver.GetAssemblyFileName (https://github.com/mono/linker/blob/da2cc0fcd6c3a8e8e5d1b5d4a655f3653baa8980/src/linker/Linker/AssemblyResolver.cs#L88) using reflection.
+ var resolver = typeof (LinkContext).GetProperty ("Resolver").GetValue (Context);
+ var filename = (string) resolver.GetType ().GetMethod ("GetAssemblyFileName", new Type [] { typeof (AssemblyDefinition) }).Invoke (resolver, new object [] { assembly });
+ return filename;
+ }
+
public void WriteOutputForMSBuild (string itemName, List items)
{
var xmlNs = XNamespace.Get ("http://schemas.microsoft.com/developer/msbuild/2003");
diff --git a/tools/dotnet-linker/SetupStep.cs b/tools/dotnet-linker/SetupStep.cs
index 96884a3ac4..ace37ceb6a 100644
--- a/tools/dotnet-linker/SetupStep.cs
+++ b/tools/dotnet-linker/SetupStep.cs
@@ -29,6 +29,8 @@ namespace Xamarin {
// Don't use --custom-step to load each step, because this assembly
// is loaded into the current process once per --custom-step,
// which makes it very difficult to share state between steps.
+ Steps.Add (new LoadNonSkippedAssembliesStep ());
+ Steps.Add (new ExtractBindingLibrariesStep ());
Steps.Add (new GenerateMainStep ());
Steps.Add (new GatherFrameworksStep ());
diff --git a/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs b/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs
index f784a67330..04c96bcd23 100644
--- a/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs
+++ b/tools/dotnet-linker/Steps/ConfigurationAwareStep.cs
@@ -1,9 +1,20 @@
+using System;
+using System.Collections.Generic;
using Mono.Linker.Steps;
+using Xamarin.Bundler;
+
namespace Xamarin.Linker {
public abstract class ConfigurationAwareStep : BaseStep {
public LinkerConfiguration Configuration {
get { return LinkerConfiguration.GetInstance (Context); }
}
+
+ protected void Report (List exceptions)
+ {
+ // Maybe there's a better way to show errors that integrates with the linker?
+ // We can't just throw an exception or exit here, since there might be only warnings in the list of exceptions.
+ ErrorHelper.Show (exceptions);
+ }
}
}
diff --git a/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs b/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs
new file mode 100644
index 0000000000..0327986f07
--- /dev/null
+++ b/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+
+namespace Xamarin.Linker {
+
+ public class ExtractBindingLibrariesStep : ConfigurationAwareStep {
+ protected override void EndProcess ()
+ {
+ base.EndProcess ();
+
+ // No attributes are currently linked away, which means we don't need to worry about linked away LinkWith attributes.
+ // Ref: https://github.com/mono/linker/issues/952 (still open as of this writing).
+ var exceptions = new List ();
+ Configuration.Target.ExtractNativeLinkInfo (exceptions);
+ Report (exceptions);
+
+ // Tell MSBuild about the native libraries we found
+ var linkWith = new List ();
+ foreach (var asm in Configuration.Target.Assemblies) {
+ foreach (var arg in asm.LinkWith) {
+ var item = new MSBuildItem {
+ Include = arg,
+ Metadata = new Dictionary {
+ { "ForceLoad", "true" },
+ { "Assembly", asm.Identity },
+ },
+ };
+ linkWith.Add (item);
+ }
+ }
+ Configuration.WriteOutputForMSBuild ("_BindingLibraryLinkWith", linkWith);
+
+ // Tell MSBuild about the frameworks libraries we found
+ var frameworks = new List ();
+ foreach (var asm in Configuration.Target.Assemblies) {
+ foreach (var fw in asm.Frameworks) {
+ var item = new MSBuildItem {
+ Include = fw,
+ Metadata = new Dictionary {
+ { "Assembly", asm.Identity },
+ },
+ };
+ frameworks.Add (item);
+ }
+ foreach (var fw in asm.WeakFrameworks) {
+ var item = new MSBuildItem {
+ Include = fw,
+ Metadata = new Dictionary {
+ { "IsWeak", "true " },
+ { "Assembly", asm.Identity },
+ },
+ };
+ frameworks.Add (item);
+ }
+ }
+ Configuration.WriteOutputForMSBuild ("_BindingLibraryFrameworks", frameworks);
+
+ // Tell MSBuild about any additional linker flags we found
+ var linkerFlags = new List ();
+ foreach (var asm in Configuration.Target.Assemblies) {
+ if (asm.LinkerFlags == null)
+ continue;
+ foreach (var arg in asm.LinkerFlags) {
+ var item = new MSBuildItem {
+ Include = arg,
+ Metadata = new Dictionary {
+ { "Assembly", asm.Identity },
+ },
+ };
+ linkerFlags.Add (item);
+ }
+ }
+ Configuration.WriteOutputForMSBuild ("_BindingLibraryLinkerFlags", linkerFlags);
+ }
+ }
+}
diff --git a/tools/dotnet-linker/Steps/LoadNonSkippedAssembliesStep.cs b/tools/dotnet-linker/Steps/LoadNonSkippedAssembliesStep.cs
new file mode 100644
index 0000000000..a6a7d99054
--- /dev/null
+++ b/tools/dotnet-linker/Steps/LoadNonSkippedAssembliesStep.cs
@@ -0,0 +1,42 @@
+using System;
+
+using Mono.Cecil;
+using Mono.Linker;
+
+namespace Xamarin.Linker {
+ // List all the assemblies we care about (i.e. the ones that have not been linked away)
+ public class LoadNonSkippedAssembliesStep : ConfigurationAwareStep {
+
+ protected override void ProcessAssembly (AssemblyDefinition assembly)
+ {
+ base.ProcessAssembly (assembly);
+
+ // Figure out if an assembly is linked away or not
+ if (Context.Annotations.HasAction (assembly)) {
+ var action = Context.Annotations.GetAction (assembly);
+ switch (action) {
+ case AssemblyAction.Delete:
+ case AssemblyAction.Skip:
+ break;
+ case AssemblyAction.Copy:
+ case AssemblyAction.CopyUsed:
+ case AssemblyAction.Link:
+ case AssemblyAction.Save:
+ var ad = Configuration.Target.AddAssembly (assembly);
+ var assemblyFileName = Configuration.GetAssemblyFileName (assembly);
+ ad.FullPath = assemblyFileName;
+ break;
+ case AssemblyAction.AddBypassNGen: // This should be turned into Save or Delete
+ case AssemblyAction.AddBypassNGenUsed: // This should be turned into Save or Delete
+ // Log this?
+ break;
+ default:
+ // Log this?
+ break;
+ }
+ } else {
+ // Log this?
+ }
+ }
+ }
+}
diff --git a/tools/dotnet-linker/dotnet-linker.csproj b/tools/dotnet-linker/dotnet-linker.csproj
index 13634632af..0e734c9372 100644
--- a/tools/dotnet-linker/dotnet-linker.csproj
+++ b/tools/dotnet-linker/dotnet-linker.csproj
@@ -3,6 +3,7 @@
net5.0
dotnet_linker
$(DefineConstants);BUNDLER
+ true
@@ -18,6 +19,9 @@
src\ObjCRuntime\ErrorHelper.cs
+
+ external\tools\common\CoreResolver.cs
+
tools\common\error.cs
@@ -31,6 +35,123 @@
tools\common\Frameworks.cs
+
+ external\tools\mtouch\Stripper.cs
+
+
+ external\tools\common\Application.cs
+
+
+ external\tools\common\cache.cs
+
+
+ external\tools\common\Assembly.cs
+
+
+ external\tools\common\Driver.cs
+
+
+ external\tools\common\Driver.execution.cs
+
+
+ external\tools\common\Execution.cs
+
+
+ external\tools\common\FileCopier.cs
+
+
+ external\tools\common\LinkMode.cs
+
+
+ external\tools\common\SdkVersions.cs
+
+
+ external\tools\common\Symbols.cs
+
+
+ external\tools\common\Assembly.cs
+
+
+ external\tools\common\DerivedLinkContext.cs
+
+
+ external\tools\common\Optimizations.cs
+
+
+ external\tools\common\PInvokeWrapperGenerator.cs
+
+
+ external\tools\common\PListExtensions.cs
+
+
+ external\tools\common\StaticRegistrar.cs
+
+
+ external\tools\common\StringUtils.cs
+
+
+ external\tools\common\TargetFramework.cs
+
+
+ external\tools\linker\CustomSymbolWriter.cs
+
+
+ external\src\ObjCRuntime\Registrar.cs
+
+
+ external\src\ObjCRuntime\Registrar.core.cs
+
+
+ external\src\ObjCRuntime\ArgumentSemantic.cs
+
+
+ external\src\ObjCRuntime\BindingImplAttribute.cs
+
+
+ external\src\ObjCRuntime\Constants.cs
+
+
+ external\src\Foundation\ExportAttribute.cs
+
+
+ external\src\Foundation\ConnectAttribute.cs
+
+
+ external\src\ObjCRuntime\ExceptionMode.cs
+
+
+ external\src\ObjCRuntime\LinkWithAttribute.cs
+
+
+ external\src\ObjCRuntime\PlatformAvailability2.cs
+
+
+ external\src\ObjCRuntime\RuntimeOptions.cs
+
+
+ external\tools\linker\MonoTouch.Tuner\Extensions.cs
+
+
+ external\tools\linker\MobileExtensions.cs
+
+
+ external\tools\linker\ObjCExtensions.cs
+
+
+ external\mono-archive\Mono.Tuner\Extensions.cs
+
+
+ external\mono-archive\Linker\AssemblyResolver.cs
+
+
+ external\mono-archive\Linker\I18nAssemblies.cs
+
+
+ external\mono-archive\Mono.Tuner\CecilRocks.cs
+
+
+ external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs
+
diff --git a/tools/mmp/driver.cs b/tools/mmp/driver.cs
index f885579f84..23f4ebbfad 100644
--- a/tools/mmp/driver.cs
+++ b/tools/mmp/driver.cs
@@ -1609,9 +1609,8 @@ namespace Xamarin.Bundler {
Target.PrintAssemblyReferences (assembly);
- var asm = new Assembly (BuildTarget, assembly);
+ var asm = BuildTarget.AddAssembly (assembly);
asm.ComputeSatellites ();
- BuildTarget.Assemblies.Add (asm);
resolved_assemblies.Add (fqname);
diff --git a/tools/mtouch/Target.mtouch.cs b/tools/mtouch/Target.mtouch.cs
index 09f8af52d6..361bbc1e50 100644
--- a/tools/mtouch/Target.mtouch.cs
+++ b/tools/mtouch/Target.mtouch.cs
@@ -336,9 +336,8 @@ namespace Xamarin.Bundler
// Load all the assemblies in the cached list of assemblies
foreach (var assembly in assemblies) {
var ad = ManifestResolver.Load (assembly);
- var asm = new Assembly (this, ad);
+ var asm = AddAssembly (ad);
asm.ComputeSatellites ();
- this.Assemblies.Add (asm);
}
return;
}
@@ -381,9 +380,8 @@ namespace Xamarin.Bundler
PrintAssemblyReferences (assembly);
assemblies.Add (fqname);
- var asm = new Assembly (this, assembly);
+ var asm = AddAssembly (assembly);
asm.ComputeSatellites ();
- this.Assemblies.Add (asm);
var main = assembly.MainModule;
foreach (AssemblyNameReference reference in main.AssemblyReferences) {
diff --git a/tools/mtouch/mtouch.cs b/tools/mtouch/mtouch.cs
index 4f285fdd74..9c5f4f4325 100644
--- a/tools/mtouch/mtouch.cs
+++ b/tools/mtouch/mtouch.cs
@@ -1154,7 +1154,7 @@ namespace Xamarin.Bundler
static bool IsBoundAssembly (Assembly s)
{
- if (s.IsFrameworkAssembly)
+ if (s.IsFrameworkAssembly == true)
return false;
AssemblyDefinition ad = s.AssemblyDefinition;