2016-04-21 16:40:25 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
using Microsoft.Build.Framework;
|
|
|
|
|
using Microsoft.Build.Utilities;
|
2020-03-14 00:46:28 +03:00
|
|
|
|
using Xamarin.Localization.MSBuild;
|
2016-04-21 16:40:25 +03:00
|
|
|
|
|
|
|
|
|
using Xamarin.MacDev;
|
|
|
|
|
|
|
|
|
|
namespace Xamarin.MacDev.Tasks
|
|
|
|
|
{
|
2020-05-13 16:44:59 +03:00
|
|
|
|
public abstract class XcodeToolTaskBase : XamarinTask
|
2016-04-21 16:40:25 +03:00
|
|
|
|
{
|
|
|
|
|
string toolExe;
|
|
|
|
|
|
|
|
|
|
#region Inputs
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string IntermediateOutputPath { get; set; }
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string ProjectDir { get; set; }
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string ResourcePrefix { get; set; }
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string SdkBinPath { get; set; }
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string SdkDevPath { get; set; }
|
|
|
|
|
|
|
|
|
|
[Required]
|
|
|
|
|
public string SdkUsrPath { get; set; }
|
|
|
|
|
|
|
|
|
|
public string ToolExe {
|
|
|
|
|
get { return toolExe ?? ToolName; }
|
|
|
|
|
set { toolExe = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ToolPath { get; set; }
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Outputs
|
|
|
|
|
|
|
|
|
|
[Output]
|
|
|
|
|
public ITaskItem[] BundleResources { get; set; }
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
protected abstract string DefaultBinDir {
|
|
|
|
|
get;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected string DeveloperRootBinDir {
|
|
|
|
|
get { return Path.Combine (SdkDevPath, "usr", "bin"); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected string DevicePlatformBinDir {
|
|
|
|
|
get { return Path.Combine (SdkDevPath, "Platforms", "iPhoneOS.platform", "Developer", "usr", "bin"); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected string SimulatorPlatformBinDir {
|
|
|
|
|
get { return Path.Combine (SdkDevPath, "Platforms", "iPhoneSimulator.platform", "Developer", "usr", "bin"); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected abstract string ToolName { get; }
|
|
|
|
|
|
|
|
|
|
protected abstract IEnumerable<ITaskItem> EnumerateInputs ();
|
|
|
|
|
|
|
|
|
|
protected abstract void AppendCommandLineArguments (IDictionary<string, string> environment, CommandLineBuilder args, ITaskItem input, ITaskItem output);
|
|
|
|
|
|
|
|
|
|
protected virtual string GetBundleRelativeOutputPath (IList<string> prefixes, ITaskItem input)
|
|
|
|
|
{
|
2016-10-26 20:08:11 +03:00
|
|
|
|
return BundleResource.GetLogicalName (ProjectDir, prefixes, input, !string.IsNullOrEmpty(SessionId));
|
2016-04-21 16:40:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual IEnumerable<ITaskItem> GetCompiledBundleResources (ITaskItem input, ITaskItem output)
|
|
|
|
|
{
|
|
|
|
|
yield return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual bool NeedsBuilding (ITaskItem input, ITaskItem output)
|
|
|
|
|
{
|
|
|
|
|
var dest = output.GetMetadata ("FullPath");
|
|
|
|
|
var src = input.GetMetadata ("FullPath");
|
|
|
|
|
|
2017-01-23 23:31:44 +03:00
|
|
|
|
return !File.Exists (dest) || File.GetLastWriteTimeUtc (src) > File.GetLastWriteTimeUtc (dest);
|
2016-04-21 16:40:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string GetFullPathToTool ()
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty (ToolPath))
|
|
|
|
|
return Path.Combine (ToolPath, ToolExe);
|
|
|
|
|
|
|
|
|
|
var path = Path.Combine (DefaultBinDir, ToolExe);
|
|
|
|
|
|
|
|
|
|
return File.Exists (path) ? path : ToolExe;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ProcessStartInfo GetProcessStartInfo (Dictionary<string, string> environment, string tool, string args)
|
|
|
|
|
{
|
|
|
|
|
var startInfo = new ProcessStartInfo (tool, args);
|
|
|
|
|
|
|
|
|
|
startInfo.WorkingDirectory = Environment.CurrentDirectory;
|
|
|
|
|
|
|
|
|
|
foreach (var variable in environment)
|
|
|
|
|
startInfo.EnvironmentVariables[variable.Key] = variable.Value;
|
|
|
|
|
|
|
|
|
|
startInfo.RedirectStandardOutput = true;
|
|
|
|
|
startInfo.RedirectStandardError = true;
|
|
|
|
|
startInfo.UseShellExecute = false;
|
|
|
|
|
startInfo.CreateNoWindow = true;
|
|
|
|
|
|
|
|
|
|
return startInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ExecuteTool (ITaskItem input, ITaskItem output)
|
|
|
|
|
{
|
|
|
|
|
var environment = new Dictionary<string, string> ();
|
|
|
|
|
var args = new CommandLineBuilder ();
|
|
|
|
|
|
|
|
|
|
environment.Add ("PATH", SdkBinPath);
|
|
|
|
|
environment.Add ("XCODE_DEVELOPER_USR_PATH", SdkUsrPath);
|
|
|
|
|
|
|
|
|
|
AppendCommandLineArguments (environment, args, input, output);
|
|
|
|
|
|
|
|
|
|
var startInfo = GetProcessStartInfo (environment, GetFullPathToTool (), args.ToString ());
|
|
|
|
|
|
|
|
|
|
using (var process = new Process ()) {
|
2020-03-14 00:46:28 +03:00
|
|
|
|
Log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, startInfo.FileName, startInfo.Arguments);
|
2016-04-21 16:40:25 +03:00
|
|
|
|
process.StartInfo = startInfo;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
process.Start ();
|
|
|
|
|
process.WaitForExit ();
|
|
|
|
|
} catch (Win32Exception ex) {
|
2020-03-14 00:46:28 +03:00
|
|
|
|
Log.LogError (MSBStrings.E0003, startInfo.FileName, ex.Message);
|
2016-04-21 16:40:25 +03:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-14 00:46:28 +03:00
|
|
|
|
Log.LogMessage (MessageImportance.Low, MSBStrings.M0116, startInfo.FileName);
|
2016-04-21 16:40:25 +03:00
|
|
|
|
|
|
|
|
|
return process.ExitCode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Execute ()
|
|
|
|
|
{
|
|
|
|
|
var prefixes = BundleResource.SplitResourcePrefixes (ResourcePrefix);
|
|
|
|
|
var intermediate = Path.Combine (IntermediateOutputPath, ToolName);
|
|
|
|
|
var bundleResources = new List<ITaskItem> ();
|
|
|
|
|
|
|
|
|
|
foreach (var input in EnumerateInputs ()) {
|
|
|
|
|
var relative = GetBundleRelativeOutputPath (prefixes, input);
|
|
|
|
|
ITaskItem output;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty (relative)) {
|
|
|
|
|
string illegal;
|
|
|
|
|
|
|
|
|
|
if (BundleResource.IsIllegalName (relative, out illegal)) {
|
2020-03-14 00:46:28 +03:00
|
|
|
|
Log.LogError (null, null, null, input.ItemSpec, 0, 0, 0, 0, MSBStrings.E0102, illegal);
|
2016-04-21 16:40:25 +03:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rpath = Path.Combine (intermediate, relative);
|
|
|
|
|
|
|
|
|
|
output = new TaskItem (rpath);
|
|
|
|
|
} else {
|
|
|
|
|
output = new TaskItem (intermediate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output.SetMetadata ("LogicalName", relative);
|
|
|
|
|
|
|
|
|
|
if (NeedsBuilding (input, output)) {
|
|
|
|
|
Directory.CreateDirectory (Path.GetDirectoryName (output.ItemSpec));
|
|
|
|
|
|
|
|
|
|
if (ExecuteTool (input, output) == -1)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bundleResources.AddRange (GetCompiledBundleResources (input, output));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BundleResources = bundleResources.ToArray ();
|
|
|
|
|
|
|
|
|
|
return !Log.HasLoggedErrors;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|