152 строки
4.3 KiB
C#
152 строки
4.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
|
|
namespace Xamarin.MacDev.Tasks
|
|
{
|
|
public abstract class PrepareNativeReferencesTaskBase : Task
|
|
{
|
|
public string SessionId { get; set; }
|
|
|
|
[Required]
|
|
public string IntermediateOutputPath { get; set; }
|
|
|
|
public ITaskItem[] NativeReferences { get; set; }
|
|
|
|
#region Output
|
|
|
|
[Output]
|
|
public ITaskItem LinkWithAttributes { get; set; }
|
|
|
|
[Output]
|
|
public ITaskItem[] EmbeddedResources { get; set; }
|
|
|
|
[Output]
|
|
public ITaskItem[] NativeFrameworks { get; set; }
|
|
|
|
#endregion
|
|
|
|
void AppendLinkTargetProperty (StringBuilder builder, ITaskItem item)
|
|
{
|
|
LinkTarget target;
|
|
string value;
|
|
|
|
value = item.GetMetadata ("LinkTarget");
|
|
if (string.IsNullOrEmpty (value))
|
|
return;
|
|
|
|
if (!Enum.TryParse (value, out target)) {
|
|
Log.LogError (null, null, null, item.ItemSpec, 0, 0, 0, 0, "Unknown link target: {0}", value);
|
|
return;
|
|
}
|
|
|
|
var targets = target.ToString ().Split (',');
|
|
|
|
builder.Append (", LinkTarget = ");
|
|
for (int i = 0; i < targets.Length; i++) {
|
|
if (i > 0)
|
|
builder.Append (" | ");
|
|
builder.AppendFormat ("LinkTarget.{0}", targets[i].Trim ());
|
|
}
|
|
}
|
|
|
|
bool GetBoolean (ITaskItem item, string property, bool defaultValue)
|
|
{
|
|
var text = item.GetMetadata (property);
|
|
bool value;
|
|
|
|
if (string.IsNullOrEmpty (text))
|
|
return defaultValue;
|
|
|
|
bool.TryParse (text, out value);
|
|
|
|
return value;
|
|
}
|
|
|
|
void AppendBooleanProperty (StringBuilder builder, ITaskItem item, string property, bool defaultValue = false)
|
|
{
|
|
if (GetBoolean (item, property, defaultValue))
|
|
builder.AppendFormat (", {0} = true", property);
|
|
}
|
|
|
|
void AppendStringProperty (StringBuilder builder, ITaskItem item, string property)
|
|
{
|
|
var value = item.GetMetadata (property);
|
|
|
|
if (string.IsNullOrEmpty (value))
|
|
return;
|
|
|
|
builder.AppendFormat (", {0} = \"", property);
|
|
for (int i = 0; i < value.Length; i++) {
|
|
if (value[i] == '\\' || value[i] == '"')
|
|
builder.Append ('\\');
|
|
builder.Append (value[i]);
|
|
}
|
|
builder.Append ('"');
|
|
}
|
|
|
|
public override bool Execute ()
|
|
{
|
|
Log.LogTaskName ("PrepareNativeReferences");
|
|
Log.LogTaskProperty ("IntermediateOutputPath", IntermediateOutputPath);
|
|
Log.LogTaskProperty ("NativeReferences", NativeReferences);
|
|
|
|
if (NativeReferences == null || NativeReferences.Length == 0)
|
|
return !Log.HasLoggedErrors;
|
|
|
|
var embeddedResources = new List<ITaskItem> ();
|
|
var nativeFrameworks = new List<ITaskItem> ();
|
|
var text = new StringBuilder ();
|
|
|
|
for (int i = 0; i < NativeReferences.Length; i++) {
|
|
NativeReferenceKind kind;
|
|
string value;
|
|
|
|
value = NativeReferences[i].GetMetadata ("Kind") ?? string.Empty;
|
|
if (!Enum.TryParse (value, out kind)) {
|
|
Log.LogError (null, null, null, NativeReferences[i].ItemSpec, 0, 0, 0, 0, "Unknown native reference type: {0}", value);
|
|
continue;
|
|
}
|
|
|
|
var path = NativeReferences[i].ItemSpec;
|
|
var logicalName = Path.GetFileName (path);
|
|
|
|
var item = new TaskItem (path);
|
|
|
|
if (kind == NativeReferenceKind.Framework) {
|
|
nativeFrameworks.Add (item);
|
|
} else {
|
|
item.SetMetadata ("LogicalName", logicalName);
|
|
embeddedResources.Add (item);
|
|
}
|
|
|
|
text.AppendFormat ("[assembly: ObjCRuntime.LinkWith (\"{0}\"", logicalName);
|
|
AppendLinkTargetProperty (text, NativeReferences[i]);
|
|
AppendBooleanProperty (text, NativeReferences[i], "IsCxx");
|
|
AppendBooleanProperty (text, NativeReferences[i], "NeedsGccExceptionHandling");
|
|
AppendBooleanProperty (text, NativeReferences[i], "SmartLink", true);
|
|
AppendBooleanProperty (text, NativeReferences[i], "ForceLoad");
|
|
AppendStringProperty (text, NativeReferences[i], "Frameworks");
|
|
AppendStringProperty (text, NativeReferences[i], "WeakFrameworks");
|
|
AppendStringProperty (text, NativeReferences[i], "LinkerFlags");
|
|
text.Append (")]");
|
|
text.AppendLine ();
|
|
}
|
|
|
|
var linkWith = Path.Combine (IntermediateOutputPath, "LinkWithAttributes.cs");
|
|
Directory.CreateDirectory (Path.GetDirectoryName (linkWith));
|
|
File.WriteAllText (linkWith, text.ToString ());
|
|
|
|
EmbeddedResources = embeddedResources.ToArray ();
|
|
NativeFrameworks = nativeFrameworks.ToArray ();
|
|
LinkWithAttributes = new TaskItem (linkWith);
|
|
|
|
return !Log.HasLoggedErrors;
|
|
}
|
|
}
|
|
}
|