289 строки
7.7 KiB
C#
289 строки
7.7 KiB
C#
// Copyright (C) 2011,2012 Xamarin, Inc. All rights reserved.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
|
|
using Xamarin.Utils;
|
|
using Xamarin.Localization.MSBuild;
|
|
|
|
namespace Xamarin.MacDev.Tasks {
|
|
public abstract class BTouchTaskBase : XamarinToolTask {
|
|
|
|
public string OutputPath { get; set; }
|
|
|
|
[Required]
|
|
public string BTouchToolPath { get; set; }
|
|
|
|
[Required]
|
|
public string BTouchToolExe { get; set; }
|
|
|
|
public ITaskItem[] ObjectiveCLibraries { get; set; }
|
|
|
|
public ITaskItem[] AdditionalLibPaths { get; set; }
|
|
|
|
public bool AllowUnsafeBlocks { get; set; }
|
|
|
|
[Required]
|
|
public string BaseLibDll { get; set; }
|
|
|
|
[Required]
|
|
public ITaskItem[] ApiDefinitions { get; set; }
|
|
|
|
public string AttributeAssembly { get; set; }
|
|
|
|
public ITaskItem[] CoreSources { get; set; }
|
|
|
|
public string DefineConstants { get; set; }
|
|
|
|
public bool EmitDebugInformation { get; set; }
|
|
|
|
public string ExtraArgs { get; set; }
|
|
|
|
public int Verbosity { get; set; }
|
|
|
|
public string GeneratedSourcesDir { get; set; }
|
|
|
|
public string GeneratedSourcesFileList { get; set; }
|
|
|
|
public string Namespace { get; set; }
|
|
|
|
public ITaskItem[] NativeLibraries { get; set; }
|
|
|
|
public string OutputAssembly { get; set; }
|
|
|
|
public bool ProcessEnums { get; set; }
|
|
|
|
[Required]
|
|
public string ProjectDir { get; set; }
|
|
|
|
public ITaskItem[] References { get; set; }
|
|
|
|
public ITaskItem[] Resources { get; set; }
|
|
|
|
public ITaskItem[] Sources { get; set; }
|
|
|
|
bool IsDotNet {
|
|
get { return TargetFramework.IsDotNet; }
|
|
}
|
|
|
|
string DotNetPath {
|
|
get {
|
|
// Return the dotnet executable we're executing with.
|
|
var dotnet_path = Environment.GetEnvironmentVariable ("DOTNET_HOST_PATH");
|
|
if (string.IsNullOrEmpty (dotnet_path))
|
|
throw new InvalidOperationException ($"DOTNET_HOST_PATH is not set");
|
|
return dotnet_path;
|
|
}
|
|
}
|
|
|
|
protected override string ToolName {
|
|
get {
|
|
if (IsDotNet)
|
|
return Path.GetFileName (DotNetPath);
|
|
|
|
return Path.GetFileNameWithoutExtension (ToolExe);
|
|
}
|
|
}
|
|
|
|
protected override string GenerateFullPathToTool ()
|
|
{
|
|
// If we're building a .NET app, executing bgen using the same
|
|
// dotnet binary as we're executed with, instead of using the
|
|
// wrapper bgen script, because that script will try to use the
|
|
// system dotnet, which might not exist or not have the version we
|
|
// need.
|
|
if (IsDotNet)
|
|
return DotNetPath;
|
|
|
|
return Path.Combine (ToolPath, ToolExe);
|
|
}
|
|
|
|
protected virtual void HandleReferences (CommandLineBuilder cmd)
|
|
{
|
|
if (References != null) {
|
|
foreach (var item in References)
|
|
cmd.AppendSwitchIfNotNull ("-r ", Path.GetFullPath (item.ItemSpec));
|
|
}
|
|
}
|
|
|
|
protected override string GenerateCommandLineCommands ()
|
|
{
|
|
var cmd = new CommandLineBuilder ();
|
|
|
|
if (IsDotNet)
|
|
cmd.AppendFileNameIfNotNull (Path.Combine (BTouchToolPath, BTouchToolExe));
|
|
|
|
#if DEBUG
|
|
cmd.AppendSwitch ("/v");
|
|
#endif
|
|
|
|
cmd.AppendSwitch ("/nostdlib");
|
|
cmd.AppendSwitchIfNotNull ("/baselib:", BaseLibDll);
|
|
cmd.AppendSwitchIfNotNull ("/out:", OutputAssembly);
|
|
|
|
cmd.AppendSwitchIfNotNull ("/attributelib:", AttributeAssembly);
|
|
|
|
string dir;
|
|
if (!string.IsNullOrEmpty (BaseLibDll)) {
|
|
dir = Path.GetDirectoryName (BaseLibDll);
|
|
cmd.AppendSwitchIfNotNull ("/lib:", dir);
|
|
}
|
|
|
|
if (ProcessEnums)
|
|
cmd.AppendSwitch ("/process-enums");
|
|
|
|
if (EmitDebugInformation)
|
|
cmd.AppendSwitch ("/debug");
|
|
|
|
if (AllowUnsafeBlocks)
|
|
cmd.AppendSwitch ("/unsafe");
|
|
|
|
cmd.AppendSwitchIfNotNull ("/ns:", Namespace);
|
|
|
|
if (!string.IsNullOrEmpty (DefineConstants)) {
|
|
var strv = DefineConstants.Split (new [] { ';' });
|
|
var sanitized = new List<string> ();
|
|
|
|
foreach (var str in strv) {
|
|
if (str != string.Empty)
|
|
sanitized.Add (str);
|
|
}
|
|
|
|
if (sanitized.Count > 0)
|
|
cmd.AppendSwitchIfNotNull ("/d:", string.Join (";", sanitized.ToArray ()));
|
|
}
|
|
|
|
//cmd.AppendSwitch ("/e");
|
|
|
|
foreach (var item in ApiDefinitions)
|
|
cmd.AppendFileNameIfNotNull (Path.GetFullPath (item.ItemSpec));
|
|
|
|
if (CoreSources != null) {
|
|
foreach (var item in CoreSources)
|
|
cmd.AppendSwitchIfNotNull ("/s:", Path.GetFullPath (item.ItemSpec));
|
|
}
|
|
|
|
if (Sources != null) {
|
|
foreach (var item in Sources)
|
|
cmd.AppendSwitchIfNotNull ("/x:", Path.GetFullPath (item.ItemSpec));
|
|
}
|
|
|
|
if (AdditionalLibPaths != null) {
|
|
foreach (var item in AdditionalLibPaths)
|
|
cmd.AppendSwitchIfNotNull ("/lib:", Path.GetFullPath (item.ItemSpec));
|
|
}
|
|
|
|
HandleReferences (cmd);
|
|
|
|
if (Resources != null) {
|
|
foreach (var item in Resources) {
|
|
var args = new List<string> ();
|
|
string id;
|
|
|
|
args.Add (item.ToString ());
|
|
id = item.GetMetadata ("LogicalName");
|
|
if (!string.IsNullOrEmpty (id))
|
|
args.Add (id);
|
|
|
|
cmd.AppendSwitchIfNotNull ("/res:", args.ToArray (), ",");
|
|
}
|
|
}
|
|
|
|
if (NativeLibraries != null) {
|
|
foreach (var item in NativeLibraries) {
|
|
var args = new List<string> ();
|
|
string id;
|
|
|
|
args.Add (item.ToString ());
|
|
id = item.GetMetadata ("LogicalName");
|
|
if (string.IsNullOrEmpty (id))
|
|
id = Path.GetFileName (args[0]);
|
|
args.Add (id);
|
|
|
|
cmd.AppendSwitchIfNotNull ("/link-with:", args.ToArray (), ",");
|
|
}
|
|
}
|
|
|
|
if (GeneratedSourcesDir != null)
|
|
cmd.AppendSwitchIfNotNull ("/tmpdir:", Path.GetFullPath (GeneratedSourcesDir));
|
|
|
|
if (GeneratedSourcesFileList != null)
|
|
cmd.AppendSwitchIfNotNull ("/sourceonly:", Path.GetFullPath (GeneratedSourcesFileList));
|
|
|
|
cmd.AppendSwitch ($"/target-framework={TargetFrameworkMoniker}");
|
|
|
|
if (!string.IsNullOrEmpty (ExtraArgs)) {
|
|
var extraArgs = CommandLineArgumentBuilder.Parse (ExtraArgs);
|
|
var target = OutputAssembly;
|
|
string projectDir;
|
|
|
|
if (ProjectDir.StartsWith ("~/", StringComparison.Ordinal)) {
|
|
// Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host,
|
|
// it simply uses paths relative to "~/". Expand these paths to their full path equivalents.
|
|
var home = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile);
|
|
|
|
projectDir = Path.Combine (home, ProjectDir.Substring (2));
|
|
} else {
|
|
projectDir = ProjectDir;
|
|
}
|
|
|
|
var customTags = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase) {
|
|
{ "projectdir", projectDir },
|
|
// Apparently msbuild doesn't propagate the solution path, so we can't get it.
|
|
// { "solutiondir", proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory },
|
|
};
|
|
// OutputAssembly is optional so it can be null
|
|
if (target != null) {
|
|
var d = Path.GetDirectoryName (target);
|
|
var n = Path.GetFileName (target);
|
|
customTags.Add ("targetpath", Path.Combine (d, n));
|
|
customTags.Add ("targetdir", d);
|
|
customTags.Add ("targetname", n);
|
|
customTags.Add ("targetext", Path.GetExtension (target));
|
|
}
|
|
|
|
for (int i = 0; i < extraArgs.Length; i++) {
|
|
var argument = extraArgs[i];
|
|
cmd.AppendTextUnquoted (" ");
|
|
cmd.AppendTextUnquoted (StringParserService.Parse (argument, customTags));
|
|
}
|
|
}
|
|
|
|
var v = VerbosityUtils.Merge (ExtraArgs, (LoggerVerbosity) Verbosity);
|
|
if (v.Length > 0) {
|
|
foreach (var arg in v) {
|
|
cmd.AppendTextUnquoted (" ");
|
|
cmd.AppendTextUnquoted (arg);
|
|
}
|
|
}
|
|
|
|
return cmd.ToString ();
|
|
}
|
|
|
|
public override bool Execute ()
|
|
{
|
|
if (!IsDotNet) {
|
|
ToolExe = BTouchToolExe;
|
|
ToolPath = BTouchToolPath;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty (SessionId) &&
|
|
!string.IsNullOrEmpty (GeneratedSourcesDir) &&
|
|
!Directory.Exists (GeneratedSourcesDir)) {
|
|
Directory.CreateDirectory (GeneratedSourcesDir);
|
|
}
|
|
|
|
if (ApiDefinitions.Length == 0) {
|
|
Log.LogError (MSBStrings.E0097);
|
|
return false;
|
|
}
|
|
|
|
return base.Execute ();
|
|
}
|
|
}
|
|
}
|