Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Versions-mac.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<string>http-client-handlers</string>
<string>mono-symbol-archive</string>
<string>sgen-concurrent-gc</string>
<string>link-platform</string>
<string>hybrid-aot</string>
</array>
</dict>
Expand Down
2 changes: 2 additions & 0 deletions docs/website/mmp-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ The easiest way to get exact version information is to use the **Xamarin Studio*

<h3><a name="MM202x"/>MM202x: Binding Optimizer failed processing `...`.</h3>

<h3><a name="MM2100"/>MM2100: Xamarin.Mac Classic API does not support Platform Linking. </h3>

# MM3xxx: AOT

## MM30xx: AOT (general) errors
Expand Down
1 change: 1 addition & 0 deletions docs/website/mtouch-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ Something unexpected occured when trying to reduce the metadata from the applica

Something unexpected occured when trying to mark `NSObject` subclasses from the application. The assembly causing the issue is named in the error message. In order to fix this issue the assembly will need to be provided in a [bug report](http://bugzilla.xamarin.com) along with a complete build log with verbosity enabled (i.e. `-v -v -v -v` in the **Additional mtouch arguments**).

<!--- 2100 used by mmp -->

# MT3xxx: AOT error messages

Expand Down
3 changes: 3 additions & 0 deletions msbuild/Xamarin.Mac.Tasks.Core/Tasks/MmpTaskBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ protected override string GenerateCommandLineCommands ()
case "sdkonly":
args.Add ("/linksdkonly");
break;
case "platform":
args.Add ("/linkplatform");
break;
default:
args.Add ("/nolink");
break;
Expand Down
2 changes: 1 addition & 1 deletion tests/common/mac/ClassicExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<ConsolePause>false</ConsolePause>
<UseRefCounting>false</UseRefCounting>
<UseSGen>false</UseSGen>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<IncludeMonoRuntime>%INCLUDE_MONO_RUNTIME%</IncludeMonoRuntime>
<EnablePackageSigning>false</EnablePackageSigning>
<CodeSigningKey>Mac Developer</CodeSigningKey>
<EnableCodeSigning>false</EnableCodeSigning>
Expand Down
10 changes: 5 additions & 5 deletions tests/common/mac/ProjectTestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool s
return new OutputText (buildOutput, runOutput);
}

public static OutputText TestClassicExecutable (string tmpDir, string testCode = "", string csprojConfig = "", bool shouldFail = false)
public static OutputText TestClassicExecutable (string tmpDir, string testCode = "", string csprojConfig = "", bool shouldFail = false, bool includeMonoRuntime = false)
{
Guid guid = Guid.NewGuid ();
string csprojTarget = GenerateClassicEXEProject (tmpDir, "ClassicExample.csproj", testCode + GenerateOutputCommand (tmpDir,guid), csprojConfig, "");
string csprojTarget = GenerateClassicEXEProject (tmpDir, "ClassicExample.csproj", testCode + GenerateOutputCommand (tmpDir,guid), csprojConfig, includeMonoRuntime: includeMonoRuntime);
string buildOutput = BuildProject (csprojTarget, isUnified : false, diagnosticMSBuild: false, shouldFail : shouldFail);
if (shouldFail)
return new OutputText (buildOutput, "");
Expand All @@ -278,7 +278,7 @@ public static OutputText TestSystemMonoExecutable (UnifiedTestConfig config, boo
return new OutputText (buildOutput, runOutput);
}

public static string GenerateClassicEXEProject (string tmpDir, string projectName, string testCode, string csprojConfig = "", string references = "", string assemblyName = null)
public static string GenerateClassicEXEProject (string tmpDir, string projectName, string testCode, string csprojConfig = "", string references = "", string assemblyName = null, bool includeMonoRuntime = false)
{
WriteMainFile ("", testCode, false, false, Path.Combine (tmpDir, "Main.cs"));

Expand All @@ -287,7 +287,7 @@ public static string GenerateClassicEXEProject (string tmpDir, string projectNam

return CopyFileWithSubstitutions (Path.Combine (sourceDir, projectName), Path.Combine (tmpDir, projectName), text =>
{
return text.Replace ("%CODE%", csprojConfig).Replace ("%REFERENCES%", references).Replace ("%NAME%", assemblyName ?? Path.GetFileNameWithoutExtension (projectName));
return text.Replace ("%CODE%", csprojConfig).Replace ("%REFERENCES%", references).Replace ("%NAME%", assemblyName ?? Path.GetFileNameWithoutExtension (projectName)).Replace ("%INCLUDE_MONO_RUNTIME%", includeMonoRuntime.ToString ());
});
}

Expand Down Expand Up @@ -487,4 +487,4 @@ public static int RunCommand (string path, string args, string[] env = null, Str
}
}
}
#endif
#endif
1 change: 1 addition & 0 deletions tests/mmptest/mmptest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<Link>unit\aot.cs</Link>
</Compile>
<Compile Include="src\FrameworkLinksTests.cs" />
<Compile Include="src\LinkerTests.cs" />
<Compile Include="src\Extensions.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
76 changes: 76 additions & 0 deletions tests/mmptest/src/LinkerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Reflection;

namespace Xamarin.MMP.Tests
{
public partial class MMPTests
{
int GetNumberOfTypesInLibrary (string path)
{
string output = TI.RunAndAssert ("/Library/Frameworks/Mono.framework/Versions/Current/Commands/monop", new StringBuilder ("-r:" + path), "GetNumberOfTypesInLibrary");
string[] splitBuildOutput = output.Split (new string[] { Environment.NewLine }, StringSplitOptions.None);
string outputLine = splitBuildOutput.First (x => x.StartsWith ("Total:"));
string numberSize = outputLine.Split (':')[1];
string number = numberSize.Split (' ')[1];
return int.Parse (number);
}

string GetAppName (bool modern) => modern ? "UnifiedExample.app" : "XM45Example.app";
string GetOutputBundlePath (string tmpDir, string name, bool modern) => Path.Combine (tmpDir, "bin/Debug/" + GetAppName (modern) + "/Contents/MonoBundle", name + ".dll");

string GetFrameworkName (bool modern) => modern ? "Xamarin.Mac" : "4.5";
string GetBaseAssemblyPath (string name, bool modern) => Path.Combine (TI.FindRootDirectory (), "Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/" + GetFrameworkName (modern) + "/", name + ".dll");

const string PlatformProjectConfig = "<LinkMode>Platform</LinkMode>";

[Test]
public void ModernLinkingSDK_WithAllNonProductSkipped_BuildsWithSameNumberOfTypes ()
{
RunMMPTest (tmpDir => {
string[] dependencies = { "mscorlib", "System.Core", "System" };
string config = "<LinkMode>SdkOnly</LinkMode><MonoBundlingExtraArgs>--linkskip=" + dependencies.Aggregate ((arg1, arg2) => arg1 + " --linkskip=" + arg2) + "</MonoBundlingExtraArgs>";
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = config };
TI.TestUnifiedExecutable (test);
foreach (string dep in dependencies) {
int typesInBaseLib = GetNumberOfTypesInLibrary (GetBaseAssemblyPath (dep, true));
int typesInOutput = GetNumberOfTypesInLibrary (GetOutputBundlePath (tmpDir, dep, true));
Assert.AreEqual (typesInBaseLib, typesInOutput, $"We linked a linkskip - {dep} with config ({typesInBaseLib} vs {typesInOutput}:\n {config}");
}
});
}

[Test]
public void FullLinkingSdk_BuildsWithFewerPlatformTypesOnly ()
{
RunMMPTest (tmpDir => {
string[] nonPlatformDependencies = { "mscorlib", "System.Core", "System" };
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { CSProjConfig = PlatformProjectConfig, XM45 = true };
TI.TestUnifiedExecutable (test);
foreach (string dep in nonPlatformDependencies) {
int typesInBaseLib = GetNumberOfTypesInLibrary (GetBaseAssemblyPath (dep, false));
int typesInOutput = GetNumberOfTypesInLibrary (GetOutputBundlePath (tmpDir, dep, false));
Assert.AreEqual (typesInBaseLib, typesInOutput, $"We linked a linkskip - {dep} with config ({typesInBaseLib} vs {typesInOutput}):\n {PlatformProjectConfig}");
}

int typesInBasePlatform = GetNumberOfTypesInLibrary (GetBaseAssemblyPath ("Xamarin.Mac", false));
int typesInOutputPlatform = GetNumberOfTypesInLibrary (GetOutputBundlePath (tmpDir, "Xamarin.Mac", false));
Assert.AreNotEqual (typesInBasePlatform, typesInOutputPlatform, $"We linked a linkskip - Xamarin.Mac with config ({typesInBasePlatform} vs {typesInOutputPlatform}):\n {PlatformProjectConfig}");

});
}

[Test]
public void PlatformSDKOnClassic_ShouldNotBeSupported ()
{
RunMMPTest (tmpDir => {
TI.TestClassicExecutable (tmpDir, csprojConfig: "<MonoBundlingExtraArgs>--linkplatform</MonoBundlingExtraArgs>\n", includeMonoRuntime:true, shouldFail: true);
});
}
}
}
3 changes: 3 additions & 0 deletions tools/common/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public enum LinkMode {
None,
SDKOnly,
All,
#if !MONOTOUCH
Platform,
#endif
}

public partial class Application
Expand Down
7 changes: 5 additions & 2 deletions tools/linker/MobileMarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,11 @@ void ProcessSystemXml (TypeDefinition type)
switch (type.Name) {
case "XslCompiledTransform":
TypeDefinition nop = GetType ("System.Xml", "System.Xml.Xsl.NoOperationDebugger");
MarkNamedMethod (nop, "OnCompile");
MarkNamedMethod (nop, "OnExecute");
// only available on the mobile profile
if (nop != null) {
MarkNamedMethod (nop, "OnCompile");
MarkNamedMethod (nop, "OnExecute");
}
break;
}
break;
Expand Down
29 changes: 17 additions & 12 deletions tools/mmp/Tuning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,6 @@ class Linker {

public static void Process (LinkerOptions options, out LinkContext context, out List<string> assemblies)
{
switch (options.TargetFramework.Identifier) {
case "Xamarin.Mac":
Profile.Current = new MacMobileProfile (options.Architecture == "x86_64" ? 64 : 32);
break;
default:
Profile.Current = new MonoMacProfile ();
break;
}
Namespaces.Initialize ();

var pipeline = CreatePipeline (options);
Expand All @@ -89,6 +81,7 @@ public static void Process (LinkerOptions options, out LinkContext context, out

context = CreateLinkContext (options, pipeline);
context.Resolver.AddSearchDirectory (options.OutputDirectory);
context.KeepTypeForwarderOnlyAssemblies = (Profile.Current is XamarinMacProfile);

try {
pipeline.Process (context);
Expand Down Expand Up @@ -163,15 +156,19 @@ static Pipeline CreatePipeline (LinkerOptions options)
if (options.LinkMode != LinkMode.None) {
pipeline.AppendStep (new TypeMapStep ());

pipeline.AppendStep (new SubStepDispatcher {
var subdispatcher = new SubStepDispatcher {
new ApplyPreserveAttribute (),
new CoreRemoveSecurity (),
new OptimizeGeneratedCodeSubStep (options.EnsureUIThread),
new RemoveUserResourcesSubStep (),
new CoreRemoveAttributes (),
new CoreHttpMessageHandler (options),
new MarkNSObjects (),
});
};
// CoreRemoveSecurity can modify non-linked assemblies
// but the conditions for this cannot happen if only the platform assembly is linked
if (options.LinkMode != LinkMode.Platform)
subdispatcher.Add (new CoreRemoveSecurity ());
pipeline.AppendStep (subdispatcher);

pipeline.AppendStep (new MonoMacPreserveCode (options));
pipeline.AppendStep (new PreserveCrypto ());
Expand Down Expand Up @@ -251,12 +248,20 @@ protected override bool IsLinked (AssemblyDefinition assembly)
if (link_mode == LinkMode.None)
return false;

if (link_mode == LinkMode.Platform)
return Profile.IsProductAssembly (assembly);

return base.IsLinked (assembly);
}

protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (link_mode == LinkMode.None) {
switch (link_mode) {
case LinkMode.Platform:
if (!Profile.IsProductAssembly (assembly))
Annotations.SetAction (assembly, AssemblyAction.Copy);
break;
case LinkMode.None:
Annotations.SetAction (assembly, AssemblyAction.Copy);
return;
}
Expand Down
24 changes: 21 additions & 3 deletions tools/mmp/driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ static void Main2 (string [] args)
}
}
},
{ "linkplatform", "Link only the Xamarin.Mac.dll platform assembly", v => App.LinkMode = LinkMode.Platform },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about XamMac.dll? Do we want to support Classic? We might want to disallow it, just to minimize the test matrix.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bad point. Let me add an error...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{ "linksdkonly", "Link only the SDK assemblies", v => App.LinkMode = LinkMode.SDKOnly },
{ "linkskip=", "Skip linking of the specified assembly", v => App.LinkSkipped.Add (v) },
{ "i18n=", "List of i18n assemblies to copy to the output directory, separated by commas (none,all,cjk,mideast,other,rare,west)", v => App.I18n = LinkerOptions.ParseI18nAssemblies (v) },
Expand Down Expand Up @@ -453,6 +454,9 @@ static void Main2 (string [] args)
if (targetFramework == TargetFramework.Empty)
throw new MonoMacException (1404, true, "Target framework '{0}' is invalid.", userTargetFramework);

if (IsClassic && App.LinkMode == LinkMode.Platform)
throw new MonoMacException (2100, true, "Xamarin.Mac Classic API does not support Platofmr Linking.");

// sanity check as this should never happen: we start out by not setting any
// Unified/Classic properties, and only IsUnifiedMobile if we are are on the
// XM framework. If we are not, we set IsUnifiedFull to true iff we detect
Expand All @@ -468,9 +472,16 @@ static void Main2 (string [] args)
if (IsUnified == IsClassic || (IsUnified && IsUnifiedCount != 1))
throw new Exception ("IsClassic/IsUnified/IsUnifiedMobile/IsUnifiedFullSystemFramework/IsUnifiedFullXamMacFramework logic regression");

if ((IsUnifiedFullSystemFramework || IsUnifiedFullXamMacFramework) && (App.LinkMode != LinkMode.None))
throw new MonoMacException (2007, true,
"Xamarin.Mac Unified API against a full .NET framework does not support linking. Pass the -nolink flag.");
if (IsUnifiedFullSystemFramework || IsUnifiedFullXamMacFramework) {
switch (App.LinkMode) {
case LinkMode.None:
case LinkMode.Platform:
break;
default:
throw new MonoMacException (2007, true,
"Xamarin.Mac Unified API against a full .NET framework does not support linking SDK or All assemblies. Pass either the `-nolink` or `-linkplatform` flag.");
}
}

ValidateXcode ();

Expand Down Expand Up @@ -699,6 +710,13 @@ static void Pack (IList<string> unprocessed)
if (!File.Exists (root_assembly))
throw new MonoMacException (7, true, "The root assembly '{0}' does not exist", root_assembly);

if (IsClassic)
Profile.Current = new MonoMacProfile ();
else if (IsUnifiedFullXamMacFramework || IsUnifiedFullSystemFramework)
Profile.Current = new XamarinMacProfile (arch == "x86_64" ? 64 : 32);
else
Profile.Current = new MacMobileProfile (arch == "x86_64" ? 64 : 32);

string root_wo_ext = Path.GetFileNameWithoutExtension (root_assembly);
if (Profile.IsSdkAssembly (root_wo_ext) || Profile.IsProductAssembly (root_wo_ext))
throw new MonoMacException (3, true, "Application name '{0}.exe' conflicts with an SDK or product assembly (.dll) name.", root_wo_ext);
Expand Down