Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfbjarne committed Oct 28, 2024
1 parent 08ab072 commit 64c425d
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 118 deletions.
149 changes: 97 additions & 52 deletions msbuild/Xamarin.MacDev.Tasks/BundleResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.Build.Utilities;

using Xamarin.Utils;
using Xamarin.MacDev.Tasks;

namespace Xamarin.MacDev {
public static class BundleResource {
Expand Down Expand Up @@ -57,95 +58,139 @@ public static IList<string> SplitResourcePrefixes (string prefix)
.ToList ();
}

[Obsolete ("DO NOT USE")]
public static string GetVirtualProjectPath (string projectDir, ITaskItem item, bool isVSBuild)
static void Log (Task? task, string msg)
{
return GetVirtualProjectPath (null, projectDir, item, "");
if (task is not null) {
task.Log.LogMessage (MessageImportance.Low, msg);
} else {
Console.WriteLine (msg);
}
}

public static string GetVirtualProjectPath (XamarinTask task, string projectDir, ITaskItem item)
{
return GetVirtualProjectPath (task, projectDir, item, !string.IsNullOrEmpty (task.SessionId));
}

public static string GetVirtualProjectPath (string projectDir, ITaskItem item, string macProjectDir)
public static string GetVirtualProjectPath (XamarinToolTask task, string projectDir, ITaskItem item)
{
return GetVirtualProjectPath (null, projectDir, item, macProjectDir);
return GetVirtualProjectPath (task, projectDir, item, !string.IsNullOrEmpty (task.SessionId));
}

public static string GetVirtualProjectPath (Task? task, string projectDir, ITaskItem item, string macProjectDir)
public static string GetVirtualProjectPath (Task task, string projectDir, ITaskItem item, bool isVSBuild)
{
var link = item.GetMetadata ("Link");

// Note: if the Link metadata exists, then it will be the equivalent of the ProjectVirtualPath
if (!string.IsNullOrEmpty (link)) {
if (Path.DirectorySeparatorChar != '\\') {
task?.Log.LogWarning ($"GetVirtualProjectPath ({projectDir}, {item.ItemSpec}, {macProjectDir}) => Link={link.Replace ('\\', '/')} (original {link})");
Log (task, $"GetVirtualProjectPath ({projectDir}, {item.ItemSpec}, {isVSBuild}) => Link={link.Replace ('\\', '/')} (original {link})");
return link.Replace ('\\', '/');
}

task?.Log.LogWarning ($"GetVirtualProjectPath ({projectDir}, {item.ItemSpec}, {macProjectDir}) => Link={link.Replace ('\\', '/')}");
Log (task, $"GetVirtualProjectPath ({projectDir}, {item.ItemSpec}, {isVSBuild}) => Link={link.Replace ('\\', '/')}");
return link;
}

var isDefaultItem = item.GetMetadata ("IsDefaultItem") == "true";
var msbuildProjectFullPath = item.GetMetadata ("MSBuildProjectFullPath");
var definingProjectFullPath = item.GetMetadata ("DefiningProjectFullPath");
var localDefiningProjectFullPath = item.GetMetadata ("LocalDefiningProjectFullPath");
var path = item.GetMetadata ("FullPath");
var localMSBuildProjectFullPath = item.GetMetadata ("LocalMSBuildProjectFullPath");
var localDefiningProjectFullPath = item.GetMetadata ("LocalDefiningProjectFullPath").Replace ('\\', '/');
string path;
string baseDir;

if (isDefaultItem) {
baseDir = msbuildProjectFullPath;
} else if (!string.IsNullOrEmpty (localDefiningProjectFullPath)) {
baseDir = Path.GetDirectoryName (localDefiningProjectFullPath);
} else if (!string.IsNullOrEmpty (definingProjectFullPath)) {
baseDir = Path.GetDirectoryName (definingProjectFullPath);
} else if (projectDir.Length > 2 && projectDir [1] == ':' && !string.IsNullOrEmpty (macProjectDir)) {
baseDir = macProjectDir;
baseDir = baseDir.Replace ("~", Environment.GetEnvironmentVariable ("HOME"));
} else {
baseDir = projectDir;
string rv;

if (string.IsNullOrEmpty (localDefiningProjectFullPath)) {
task.Log.LogError ($"The item {item.ItemSpec} does not have a 'LocalDefiningProjectFullPath' value set.");
return "placeholder";
}

var originalBaseDir = baseDir;
var originalPath = path;

baseDir = PathUtils.ResolveSymbolicLinks (baseDir);
path = PathUtils.ResolveSymbolicLinks (path);

var rv2 = PathUtils.AbsoluteToRelative (baseDir, path);
task?.Log.LogWarning ($"GetVirtualProjectPath ({projectDir}, {item.ItemSpec}, {macProjectDir})\n" +
$"\t\t\t\tisDefaultItem={isDefaultItem}\n" +
$"\t\t\t\tMSBuildProjectFullPath={msbuildProjectFullPath}\n" +
$"\t\t\t\tDefiningProjectFullPath={definingProjectFullPath}\n" +
$"\t\t\t\tLocalDefiningProjectFullPath={localDefiningProjectFullPath}\n" +
$"\t\t\t\tFullPath={path} ({originalPath})\n" +
$"\t\t\t\tbaseDir={baseDir} ({originalBaseDir})\n" +
$"\t\t\t\t ==> {rv2}");
return rv2;
}
if (string.IsNullOrEmpty (localMSBuildProjectFullPath)) {
task.Log.LogError ($"The item {item.ItemSpec} does not have a 'LocalMSBuildProjectFullPath' value set.");
return "placeholder";
}

[Obsolete ("DO NOT USE")]
public static string GetLogicalName (string projectDir, IList<string> prefixes, ITaskItem item, bool isVSBuild)
{
return GetLogicalName (null, projectDir, prefixes, item, "");
if (isVSBuild) {
// 'path' is full path on Windows
path = PathUtils.PathCombineWindows (projectDir, item.ItemSpec);

// 'baseDir' is the base directory in Windows
if (isDefaultItem) {
baseDir = Path.GetDirectoryName (localMSBuildProjectFullPath);
} else {
baseDir = Path.GetDirectoryName (localDefiningProjectFullPath);
}

rv = PathUtils.AbsoluteToRelativeWindows (baseDir, path);
// Make it a mac-style path
rv = rv.Replace ('\\', '/');

Log (task, $"GetVirtualProjectPath\n" +
$"\t\t\t{projectDir}\n" +
$"\t\t\t{item.ItemSpec}\n" +
$"\t\t\t{isVSBuild}\n" +
$"\t\t\t\tisDefaultItem={isDefaultItem}\n" +
$"\t\t\t\tLocalMSBuildProjectFullPath={localMSBuildProjectFullPath}\n" +
$"\t\t\t\tLocalDefiningProjectFullPath={localDefiningProjectFullPath}\n" +
$"\t\t\t\tpath={path}\n" +
$"\t\t\t\tbaseDir={baseDir}\n" +
$"\t\t\t\t ==> {rv}");
} else {
path = Path.Combine (projectDir, item.ItemSpec);

if (isDefaultItem) {
baseDir = Path.GetDirectoryName (localMSBuildProjectFullPath);
} else if (!string.IsNullOrEmpty (localDefiningProjectFullPath)) {
baseDir = Path.GetDirectoryName (localDefiningProjectFullPath);
} else {
baseDir = projectDir;
}

var originalBaseDir = baseDir;
var originalPath = path;

baseDir = PathUtils.ResolveSymbolicLinks (baseDir);
path = PathUtils.ResolveSymbolicLinks (path);

rv = PathUtils.AbsoluteToRelative (baseDir, path);
Log (task, $"GetVirtualProjectPath\n" +
$"\t\t\t{projectDir}\n" +
$"\t\t\t{item.ItemSpec}\n" +
$"\t\t\t{isVSBuild}\n" +
$"\t\t\t\tisDefaultItem={isDefaultItem}\n" +
$"\t\t\t\tLocalMSBuildProjectFullPath={localMSBuildProjectFullPath}\n" +
$"\t\t\t\tLocalDefiningProjectFullPath={localDefiningProjectFullPath}\n" +
$"\t\t\t\tpath={path} ({originalPath})\n" +
$"\t\t\t\tbaseDir={baseDir} ({originalBaseDir})\n" +
$"\t\t\t\t ==> {rv}");
}

return rv;
}

public static string GetLogicalName (string projectDir, IList<string> prefixes, ITaskItem item, string macProjectDir)
static bool GetISVSBuild (Task task)
{
return GetLogicalName (null, projectDir, prefixes, item, macProjectDir);
if (task is XamarinTask xt)
return !string.IsNullOrEmpty (xt.SessionId);
if (task is XamarinToolTask xtt)
return !string.IsNullOrEmpty (xtt.SessionId);
return false;
}

public static string GetLogicalName (Task? task, string projectDir, IList<string> prefixes, ITaskItem item, string macProjectDir)
public static string GetLogicalName (Task task, string projectDir, IList<string> prefixes, ITaskItem item)
{
var logicalName = item.GetMetadata ("LogicalName");

if (!string.IsNullOrEmpty (logicalName)) {
if (Path.DirectorySeparatorChar != '\\') {
task?.Log.LogWarning ($"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}, {macProjectDir}) => has LogicalName={logicalName.Replace ('\\', '/')} (original {logicalName})");
task?.Log.LogMessage (MessageImportance.Low, $"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}) => has LogicalName={logicalName.Replace ('\\', '/')} (original {logicalName})");
return logicalName.Replace ('\\', '/');
}
task?.Log.LogWarning ($"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}, {macProjectDir}) => has LogicalName={logicalName}");
task?.Log.LogMessage (MessageImportance.Low, $"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}) => has LogicalName={logicalName}");
return logicalName;
}

var vpath = GetVirtualProjectPath (task, projectDir, item, macProjectDir);
var vpath = GetVirtualProjectPath (task, projectDir, item, GetISVSBuild (task));
int matchlen = 0;

foreach (var prefix in prefixes) {
Expand All @@ -154,11 +199,11 @@ public static string GetLogicalName (Task? task, string projectDir, IList<string
}

if (matchlen > 0) {
task?.Log.LogWarning ($"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}, {macProjectDir}) => has LogicalName={vpath.Substring (matchlen)} with vpath {vpath} substring {matchlen}");
task?.Log.LogMessage (MessageImportance.Low, $"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}) => has LogicalName={vpath.Substring (matchlen)} with vpath {vpath} substring {matchlen}");
return vpath.Substring (matchlen);
}

task?.Log.LogWarning ($"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}, {macProjectDir}) => has LogicalName={vpath.Substring (matchlen)} with vpath {vpath}");
task?.Log.LogMessage (MessageImportance.Low, $"GetLogicalName ({projectDir}, {string.Join (";", prefixes)}, {item.ItemSpec}) => has LogicalName={vpath.Substring (matchlen)} with vpath {vpath}");
return vpath;
}
}
Expand Down
8 changes: 4 additions & 4 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ bool IsMessagesExtension {

protected override void AppendCommandLineArguments (IDictionary<string, string?> environment, CommandLineArgumentBuilder args, ITaskItem [] items)
{
var assetDirs = new HashSet<string> (items.Select (x => BundleResource.GetVirtualProjectPath (ProjectDir, x, !string.IsNullOrEmpty (SessionId))));
var assetDirs = new HashSet<string> (items.Select (x => BundleResource.GetVirtualProjectPath (this, ProjectDir, x)));

if (!string.IsNullOrEmpty (XSAppIconAssets)) {
int index = XSAppIconAssets.IndexOf (".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
Expand Down Expand Up @@ -210,7 +210,7 @@ public override bool Execute ()
var specs = new PArray ();

for (int i = 0; i < ImageAssets.Length; i++) {
var vpath = BundleResource.GetVirtualProjectPath (ProjectDir, ImageAssets [i], !string.IsNullOrEmpty (SessionId));
var vpath = BundleResource.GetVirtualProjectPath (this, ProjectDir, ImageAssets [i]);

// Ignore MacOS .DS_Store files...
if (Path.GetFileName (vpath).Equals (".DS_Store", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -251,7 +251,7 @@ public override bool Execute ()
items.Clear ();

for (int i = 0; i < ImageAssets.Length; i++) {
var vpath = BundleResource.GetVirtualProjectPath (ProjectDir, ImageAssets [i], !string.IsNullOrEmpty (SessionId));
var vpath = BundleResource.GetVirtualProjectPath (this, ProjectDir, ImageAssets [i]);
var clone = false;
ITaskItem item;

Expand Down Expand Up @@ -302,7 +302,7 @@ public override bool Execute ()

// Note: `items` contains only the Contents.json files at this point
for (int i = 0; i < items.Count; i++) {
var vpath = BundleResource.GetVirtualProjectPath (ProjectDir, items [i], !string.IsNullOrEmpty (SessionId));
var vpath = BundleResource.GetVirtualProjectPath (this, ProjectDir, items [i]);
var path = items [i].GetMetadata ("FullPath");

// get the parent (which will typically be .appiconset, .launchimage, .imageset, .iconset, etc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public static bool TryCreateItemWithLogicalName (Task task, ITaskItem item, stri
if (!string.IsNullOrEmpty (publishFolderType))
return false;

var logicalName = BundleResource.GetLogicalName (projectDir, prefixes, item, !string.IsNullOrEmpty (sessionId));
var logicalName = BundleResource.GetLogicalName (task, projectDir, prefixes, item);
// We need a physical path here, ignore the Link element
var path = item.GetMetadata ("FullPath");

Expand Down
2 changes: 1 addition & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/CompileAppManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void RegisterFonts (PDictionary plist)
var prefixes = BundleResource.SplitResourcePrefixes (ResourcePrefix);
const string logicalNameKey = "_ComputedLogicalName_";
foreach (var item in FontFilesToRegister) {
var logicalName = BundleResource.GetLogicalName (ProjectDir, prefixes, item, !string.IsNullOrEmpty (SessionId));
var logicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, item);
item.SetMetadata (logicalNameKey, logicalName);
}

Expand Down
4 changes: 2 additions & 2 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/CompileSceneKitAssets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public override bool Execute ()
if (!TryGetScnAssetsPath (asset.ItemSpec, out var scnassets))
continue;

var bundleName = BundleResource.GetLogicalName (ProjectDir, prefixes, asset, !string.IsNullOrEmpty (SessionId));
var bundleName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, asset);
var output = new TaskItem (Path.Combine (intermediate, bundleName));

if (!modified.Contains (scnassets) && (!File.Exists (output.ItemSpec) || File.GetLastWriteTimeUtc (asset.ItemSpec) > File.GetLastWriteTimeUtc (output.ItemSpec))) {
Expand Down Expand Up @@ -211,7 +211,7 @@ public override bool Execute ()

var tasks = new List<Task> ();
foreach (var item in items) {
var bundleDir = BundleResource.GetLogicalName (ProjectDir, prefixes, new TaskItem (item), !string.IsNullOrEmpty (SessionId));
var bundleDir = BundleResource.GetLogicalName (this, ProjectDir, prefixes, new TaskItem (item));
var output = Path.Combine (intermediate, bundleDir);

tasks.Add (CopySceneKitAssets (item.ItemSpec, output, intermediate));
Expand Down
2 changes: 1 addition & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public override bool Execute ()
Directory.CreateDirectory (coremlcOutputDir);

foreach (var model in Models) {
var logicalName = BundleResource.GetLogicalName (ProjectDir, prefixes, model, !string.IsNullOrEmpty (SessionId));
var logicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, model);
var bundleName = GetPathWithoutExtension (logicalName) + ".mlmodelc";
var outputPath = Path.Combine (coremlcOutputDir, bundleName);
var outputDir = Path.GetDirectoryName (outputPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public override bool Execute ()
var prefixes = BundleResource.SplitResourcePrefixes (ResourcePrefix);

foreach (var item in Items) {
var logical = BundleResource.GetLogicalName (ProjectDir, prefixes, item, !string.IsNullOrEmpty (SessionId));
var logical = BundleResource.GetLogicalName (this, ProjectDir, prefixes, item);

if (logical == LogicalName) {
Log.LogMessage (MessageImportance.Low, MSBStrings.M0149, LogicalName, item.ItemSpec);
Expand Down
2 changes: 1 addition & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public override bool Execute ()

var prefixes = BundleResource.SplitResourcePrefixes (ResourcePrefix);
var intermediate = Path.Combine (IntermediateOutputPath, MetalPath);
var logicalName = BundleResource.GetLogicalName (ProjectDir, prefixes, SourceFile!, !string.IsNullOrEmpty (SessionId));
var logicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, SourceFile!);
var path = Path.Combine (intermediate, logicalName);
var args = new List<string> ();
var dir = Path.GetDirectoryName (path);
Expand Down
2 changes: 1 addition & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public override bool Execute ()
var bundleResources = new List<ITaskItem> ();
foreach (var asset in ColladaAssets) {
var inputScene = asset.ItemSpec;
var logicalName = BundleResource.GetLogicalName (ProjectDir, prefixes, asset, !string.IsNullOrEmpty (SessionId));
var logicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, asset);
var outputScene = Path.Combine (DeviceSpecificIntermediateOutputPath, logicalName);
var args = GenerateCommandLineCommands (inputScene, outputScene);
listOfArguments.Add (new (args, asset));
Expand Down
4 changes: 2 additions & 2 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/TextureAtlas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ protected override IEnumerable<ITaskItem> EnumerateInputs ()
// group the atlas textures by their parent .atlas directories
var prefixes = BundleResource.SplitResourcePrefixes (ResourcePrefix);
foreach (var item in AtlasTextures) {
var vpp = BundleResource.GetVirtualProjectPath (this, ProjectDir, item, MacProjectDir);
var vpp = BundleResource.GetVirtualProjectPath (this, ProjectDir, item);
var atlas = Path.GetDirectoryName (vpp);
Log.LogWarning ($"Processing atlas {item.ItemSpec} with LogicalName={item.GetMetadata ("LogicalName")} VirtualProjectPath={vpp} and atlas name {atlas}");

if (!atlases.TryGetValue (atlas, out var tuple)) {
tuple.Items = new List<ITaskItem> ();
var itemLogicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, item, MacProjectDir);
var itemLogicalName = BundleResource.GetLogicalName (this, ProjectDir, prefixes, item);
tuple.LogicalName = Path.GetDirectoryName (itemLogicalName);
atlases.Add (atlas, tuple);
Log.LogWarning ($" => created new atlas {atlas} with new LogicalName {tuple.LogicalName} and itemLogicalName {itemLogicalName}");
Expand Down
Loading

0 comments on commit 64c425d

Please sign in to comment.