diff --git a/tests/common/mac/Component1.fs b/tests/common/mac/Component1.fs
index 36da391d07..5be06e207f 100644
--- a/tests/common/mac/Component1.fs
+++ b/tests/common/mac/Component1.fs
@@ -1,3 +1,5 @@
namespace FSharpXM45Library
type Class1() =
member this.X = "F#"
+
+%CODE%
diff --git a/tests/common/mac/MyClass.cs b/tests/common/mac/MyClass.cs
index ef728deed5..2b4c3c6e29 100644
--- a/tests/common/mac/MyClass.cs
+++ b/tests/common/mac/MyClass.cs
@@ -10,3 +10,4 @@ namespace Library
}
}
+%CODE%
diff --git a/tests/common/mac/ProjectTestHelpers.cs b/tests/common/mac/ProjectTestHelpers.cs
index 51b903e8e0..159ad91273 100644
--- a/tests/common/mac/ProjectTestHelpers.cs
+++ b/tests/common/mac/ProjectTestHelpers.cs
@@ -34,14 +34,15 @@ namespace Xamarin.MMP.Tests
public bool FSharp { get; set; }
public bool XM45 { get; set; }
public bool DiagnosticMSBuild { get; set; }
- public string ProjectName { get; set; }
- public string TestCode { get; set; }
- public string TestDecl { get; set; }
- public string CSProjConfig { get; set; }
- public string References { get; set; }
- public string AssemblyName { get; set; }
- public string ItemGroup { get; set; }
- public string SystemMonoVersion { get; set; }
+ public string ProjectName { get; set; } = "";
+ public string TestCode { get; set; } = "";
+ public string TestDecl { get; set; } = "";
+ public string CSProjConfig { get; set; } = "";
+ public string References { get; set; } = "";
+ public string ReferencesBeforePlatform { get; set; } = "";
+ public string AssemblyName { get; set; } = "";
+ public string ItemGroup { get; set; } = "";
+ public string SystemMonoVersion { get; set; } = "";
// Binding project specific
public string APIDefinitionConfig { get; set; }
@@ -53,16 +54,6 @@ namespace Xamarin.MMP.Tests
public UnifiedTestConfig (string tmpDir)
{
TmpDir = tmpDir;
- ProjectName = "";
- TestCode = "";
- TestDecl = "";
- CSProjConfig = "";
- References = "";
- AssemblyName = "";
- APIDefinitionConfig = "";
- StructsAndEnumsConfig = "";
- ItemGroup = "";
- SystemMonoVersion = "";
}
}
@@ -150,7 +141,11 @@ namespace Xamarin.MMP.Tests
static string ProjectTextReplacement (UnifiedTestConfig config, string text)
{
- return text.Replace ("%CODE%", config.CSProjConfig).Replace ("%REFERENCES%", config.References).Replace ("%NAME%", config.AssemblyName ?? Path.GetFileNameWithoutExtension (config.ProjectName)).Replace ("%ITEMGROUP%", config.ItemGroup);
+ return text.Replace ("%CODE%", config.CSProjConfig)
+ .Replace ("%REFERENCES%", config.References)
+ .Replace ("%REFERENCES_BEFORE_PLATFORM%", config.ReferencesBeforePlatform)
+ .Replace ("%NAME%", config.AssemblyName ?? Path.GetFileNameWithoutExtension (config.ProjectName))
+ .Replace ("%ITEMGROUP%", config.ItemGroup);
}
public static string RunEXEAndVerifyGUID (string tmpDir, Guid guid, string path)
@@ -196,11 +191,14 @@ namespace Xamarin.MMP.Tests
string sourceDir = FindSourceDirectory ();
string sourceFileName = config.FSharp ? "Component1.fs" : "MyClass.cs";
string projectSuffix = config.FSharp ? ".fsproj" : ".csproj";
- File.Copy (Path.Combine (sourceDir, sourceFileName), Path.Combine (config.TmpDir, sourceFileName), true);
+
+ CopyFileWithSubstitutions (Path.Combine (sourceDir, sourceFileName), Path.Combine (config.TmpDir, sourceFileName), text => {
+ return text.Replace ("%CODE%", config.TestCode);
+ });
return CopyFileWithSubstitutions (Path.Combine (sourceDir, config.ProjectName + projectSuffix), Path.Combine (config.TmpDir, config.ProjectName + projectSuffix), text => {
- return ProjectTextReplacement (config, text);
- });
+ return ProjectTextReplacement (config, text);
+ });
}
public static string GetUnifiedExecutableProjectName (UnifiedTestConfig config)
@@ -220,10 +218,10 @@ namespace Xamarin.MMP.Tests
return GenerateEXEProject (config);
}
- public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, string configuration = null)
+ public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null)
{
string csprojTarget = GenerateUnifiedExecutableProject (config);
- return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, configuration: configuration);
+ return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, useMSBuild: useMSBuild, configuration: configuration);
}
public static string RunGeneratedUnifiedExecutable (UnifiedTestConfig config)
@@ -233,7 +231,7 @@ namespace Xamarin.MMP.Tests
return RunEXEAndVerifyGUID (config.TmpDir, config.guid, exePath);
}
- public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, string configuration = null)
+ public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null)
{
// If we've already generated guid bits for this config, don't tack on a second copy
if (config.guid == Guid.Empty)
@@ -242,7 +240,7 @@ namespace Xamarin.MMP.Tests
config.TestCode += GenerateOutputCommand (config.TmpDir, config.guid);
}
- string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, configuration);
+ string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, useMSBuild, configuration);
if (shouldFail)
return new OutputText (buildOutput, "");
diff --git a/tests/common/mac/UnifiedExample.csproj b/tests/common/mac/UnifiedExample.csproj
index 077641e43b..2f0a361a2f 100644
--- a/tests/common/mac/UnifiedExample.csproj
+++ b/tests/common/mac/UnifiedExample.csproj
@@ -27,6 +27,7 @@
+%REFERENCES_BEFORE_PLATFORM%
%REFERENCES%
diff --git a/tests/mmptest/src/MMPTest.cs b/tests/mmptest/src/MMPTest.cs
index cf1f800976..a760047f9b 100644
--- a/tests/mmptest/src/MMPTest.cs
+++ b/tests/mmptest/src/MMPTest.cs
@@ -728,5 +728,29 @@ namespace Xamarin.MMP.Tests
TI.TestUnifiedExecutable (test);
});
}
+
+ [Test]
+ public void Unified32BitWithXMRequiringLibrary_ShouldReferenceCorrectXM_AndNotCrash ()
+ {
+ RunMMPTest (tmpDir => {
+ TI.UnifiedTestConfig libConfig = new TI.UnifiedTestConfig (tmpDir) {
+ ProjectName = "UnifiedLibrary",
+ TestCode = "namespace Library { public static class Foo { public static void Bar () { var v = new Foundation.NSObject (); } } }"
+ };
+
+ string csprojTarget = TI.GenerateUnifiedLibraryProject (libConfig);
+ TI.BuildProject (csprojTarget, isUnified: true);
+
+ string referenceCode = string.Format (@"{0}", Path.Combine (tmpDir, "bin/Debug/UnifiedLibrary.dll"));
+
+ TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) {
+ CSProjConfig = @"x86i386",
+ ReferencesBeforePlatform = referenceCode,
+ TestCode = "Library.Foo.Bar ();"
+ };
+
+ TI.TestUnifiedExecutable (test);
+ });
+ }
}
}
diff --git a/tools/mmp/driver.cs b/tools/mmp/driver.cs
index 8bb2656287..e296c6a264 100644
--- a/tools/mmp/driver.cs
+++ b/tools/mmp/driver.cs
@@ -109,6 +109,7 @@ namespace Xamarin.Bundler {
static string BundleName { get { return custom_bundle_name != null ? custom_bundle_name : "MonoBundle"; } }
static string AppPath { get { return Path.Combine (macos_dir, app_name); } }
+ public static string Arch => arch;
static string icon;
static string certificate_name;
@@ -122,12 +123,6 @@ namespace Xamarin.Bundler {
static Version MinimumMonoVersion = new Version (4, 2, 0);
const string pkg_config = "/Library/Frameworks/Mono.framework/Commands/pkg-config";
- static HashSet xammac_reference_assemblies = new HashSet {
- "Xamarin.Mac.dll",
- "Xamarin.Mac.CFNetwork.dll",
- "OpenTK.dll"
- };
-
static void ShowHelp (OptionSet os) {
Console.WriteLine ("mmp - Xamarin.Mac Packer");
Console.WriteLine ("Copyright 2010 Novell Inc.");
@@ -1867,9 +1862,7 @@ namespace Xamarin.Bundler {
static void GatherAssemblies () {
foreach (string asm in references) {
- var assembly = BuildTarget.Resolver.AddAssembly (SwapOutReferenceAssembly (asm));
- if (assembly == null)
- ErrorHelper.Warning (1501, "Can not resolve reference: {0}", asm);
+ AssemblyDefinition assembly = AddAssemblyPathToResolver (asm);
ProcessAssemblyReferences (assembly);
}
if (BuildTarget.Resolver.Exceptions.Count > 0)
@@ -1894,33 +1887,63 @@ namespace Xamarin.Bundler {
resolved_assemblies.Add (fqname);
foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) {
- var reference_assembly = BuildTarget.Resolver.Resolve (SwapOutReferenceAssembly (reference.FullName));
+ AssemblyDefinition reference_assembly = AddAssemblyReferenceToResolver (reference.Name);
ProcessAssemblyReferences (reference_assembly);
}
}
- static string SwapOutReferenceAssembly (string assembly)
+ static AssemblyDefinition AddAssemblyPathToResolver (string path)
{
- // Inject the correct Xamarin.Mac.dll - the one in the framework
- // directory is a reference assembly only (stripped of IL, containing
- // only API/metadata) and the correct one based on the target
- // architecture needs to replace it
- string fileName = Path.GetFileName (assembly);
+ if (AssemblySwapInfo.AssemblyNeedsSwappedOut (path))
+ path = AssemblySwapInfo.GetSwappedAssemblyPath (path);
- if (assembly.Contains ("OpenTK.dll") && IsUnifiedFullXamMacFramework)
- return assembly;
- if (IsUnified &&
- xammac_reference_assemblies.Contains (fileName)) {
- switch (arch) {
+ var assembly = BuildTarget.Resolver.AddAssembly (path);
+ if (assembly == null)
+ ErrorHelper.Warning (1501, "Can not resolve reference: {0}", path);
+ return assembly;
+ }
+
+ static AssemblyDefinition AddAssemblyReferenceToResolver (string reference)
+ {
+ if (AssemblySwapInfo.ReferencedNeedsSwappedOut (reference))
+ return BuildTarget.Resolver.AddAssembly (AssemblySwapInfo.GetSwappedReference (reference));
+
+ return BuildTarget.Resolver.Resolve (reference);
+ }
+ }
+
+ public static class AssemblySwapInfo {
+ static HashSet xammac_reference_assemblies_names = new HashSet {
+ "Xamarin.Mac",
+ "Xamarin.Mac.CFNetwork",
+ "OpenTK"
+ };
+
+ public static bool AssemblyNeedsSwappedOut (string path) => NeedsSwappedCore (Path.GetFileNameWithoutExtension (path));
+ public static bool ReferencedNeedsSwappedOut (string reference) => NeedsSwappedCore (reference);
+
+ static bool NeedsSwappedCore (string name)
+ {
+ if (name.Contains ("OpenTK") && Driver.IsUnifiedFullXamMacFramework)
+ return false;
+
+ return Driver.IsUnified && xammac_reference_assemblies_names.Contains (name);
+ }
+
+ public static string GetSwappedAssemblyPath (string path) => GetSwappedPathCore (Path.GetFileNameWithoutExtension (path));
+ public static string GetSwappedReference (string reference) => GetSwappedPathCore (reference);
+
+ static string GetSwappedPathCore (string name)
+ {
+ string flavor = (Driver.IsUnifiedFullSystemFramework || Driver.IsUnifiedFullXamMacFramework) ? "full" : "mobile";
+ switch (Driver.Arch) {
case "i386":
case "x86_64":
- return Path.Combine (GetXamMacPrefix (), "lib", arch, (IsUnifiedFullSystemFramework || IsUnifiedFullXamMacFramework) ? "full" : "mobile", fileName);
+ return Path.Combine (Driver.GetXamMacPrefix (), "lib", Driver.Arch, flavor, name + ".dll");
default:
- throw new MonoMacException (5205, true, "Invalid architecture '{0}'. " +
- "Valid architectures are i386 and x86_64 (when --profile=mobile).", arch);
- }
+ throw new MonoMacException (5205, true, "Invalid architecture '{0}'. " +
+ "Valid architectures are i386 and x86_64 (when --profile=mobile).", Driver.Arch);
}
- return assembly;
}
}
}