Skip to content

Commit 7916e74

Browse files
authored
[windows][msbuild] Copy entire directory when the native reference is a framework (#11868)
The entire `.framework` directory needs to be copied back to Windows when a native reference is a [xc]framework. Otherwise important files will be missing and the app bundle will be unusable. Fix https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1339824
1 parent cd9a87c commit 7916e74

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

msbuild/Xamarin.iOS.Tasks/Tasks/MTouch.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,18 @@ public IEnumerable<ITaskItem> GetAdditionalItemsToBeCopied ()
5252
if (NativeReferences == null)
5353
yield break;
5454

55-
foreach (var nativeRef in NativeReferences
56-
.Where (x => Directory.Exists (x.ItemSpec))
57-
.Select (x => x.ItemSpec))
58-
foreach (var item in GetItemsFromNativeReference (nativeRef))
59-
yield return item;
55+
foreach (var nativeRef in NativeReferences) {
56+
var path = nativeRef.ItemSpec;
57+
// look for frameworks, if the library is part of one then bring all related files
58+
var dir = Path.GetDirectoryName (path);
59+
if ((Path.GetExtension (dir) == ".framework") && Directory.Exists (dir)) {
60+
foreach (var item in GetItemsFromNativeReference (dir)) {
61+
// don't return the native library itself (it's the original input, not something additional)
62+
if (item.ItemSpec != path)
63+
yield return item;
64+
}
65+
}
66+
}
6067
}
6168

6269
public override void Cancel ()

tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MTouchTaskTests.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45

56
using Microsoft.Build.Utilities;
67

@@ -9,7 +10,7 @@
910

1011
namespace Xamarin.iOS.Tasks
1112
{
12-
class CustomMTouchTask : MTouchTaskBase
13+
class CustomMTouchTask : MTouch
1314
{
1415
public CustomMTouchTask ()
1516
{
@@ -298,6 +299,54 @@ public void ReferenceFrameworkFileResolution_WhenResolutionFails(string targetFr
298299
}
299300
}
300301

302+
[Test]
303+
public void NativeReference_None ()
304+
{
305+
// non-framework native references do not have to copy anything else (back to Windows)
306+
307+
Task.NativeReferences = null;
308+
var items = Task.GetAdditionalItemsToBeCopied ().ToArray ();
309+
Assert.That (items.Count (), Is.EqualTo (0), "null");
310+
311+
Task.NativeReferences = new TaskItem [] { };
312+
items = Task.GetAdditionalItemsToBeCopied ().ToArray ();
313+
Assert.That (items.Count (), Is.EqualTo (0), "none");
314+
315+
var temp = Cache.CreateTemporaryDirectory ();
316+
var native_lib = Path.Combine (temp, "libFoo");
317+
File.WriteAllText (native_lib, "fake lib");
318+
Task.NativeReferences = new [] { new TaskItem (native_lib) };
319+
items = Task.GetAdditionalItemsToBeCopied ().ToArray ();
320+
Assert.That (items.Count (), Is.EqualTo (0), "non-framework path");
321+
}
322+
323+
[Test]
324+
public void NativeReference_Framework ()
325+
{
326+
var temp = Cache.CreateTemporaryDirectory ();
327+
var fx = Path.Combine (temp, "project", "Universal.xcframework", "macos-arm64_x86_64", "Universal.framework");
328+
Directory.CreateDirectory (fx);
329+
330+
var native_lib = Path.Combine (fx, "Universal");
331+
File.WriteAllText (native_lib, "fake lib");
332+
333+
// other files
334+
File.WriteAllText (Path.Combine (fx, "Info.plist"), "fake info.plist");
335+
var headers = Path.Combine (fx, "Headers");
336+
Directory.CreateDirectory (headers);
337+
File.WriteAllText (Path.Combine (headers, "Universal.h"), "fake headers");
338+
var signature = Path.Combine (fx, "_CodeSignature");
339+
Directory.CreateDirectory (signature);
340+
File.WriteAllText (Path.Combine (signature, "CodeResources"), "fake resources");
341+
342+
// a native reference to a framework needs to bring (all of) the framework files (back to Windows)
343+
344+
Task.NativeReferences = new [] { new TaskItem (native_lib) };
345+
var items = Task.GetAdditionalItemsToBeCopied ().ToArray ();
346+
// 3 additional files (as we do not duplicate the TaskItem for the native library itself)
347+
Assert.That (items.Count (), Is.EqualTo (3), "framework files");
348+
}
349+
301350
class TempSdk : IDisposable
302351
{
303352
MonoTouchSdk sdk;

0 commit comments

Comments
 (0)