Skip to content

Commit

Permalink
[dotnet/msbuild] Copy binding resource packages to output directories…
Browse files Browse the repository at this point in the history
… together with CopyLocal assemblies. Fixes #13910. (#17806)

With a project structure like this:

* Executable project references a library project.
* The library project references a binding project (or assembly).

The binding project's assembly will be copied to the library project's
output directory during the build. Unless we also make sure any binding
resource packages are copied as well, the executable project won't find those,
and the final app won't contain any native bits from the binding project.

The solution is to add any binding resource packages to the list of
files to be copied to the library's output directory.

Fixes #13910.
  • Loading branch information
rolfbjarne authored Mar 22, 2023
1 parent e86c77a commit 7ea0044
Show file tree
Hide file tree
Showing 40 changed files with 358 additions and 8 deletions.
77 changes: 77 additions & 0 deletions dotnet/targets/Xamarin.Shared.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -1956,6 +1956,83 @@ global using nfloat = global::System.Runtime.InteropServices.NFloat%3B
</ItemGroup>
</Target>

<Target Name="_CopyLocalBindingResources" AfterTargets="ResolveAssemblyReferences" BeforeTargets="CopyFilesToOutputDirectory">
<!--
We need to copy binding resource packages (either zipped or as a
.resources bundle) together with the binding assembly when the
binding assembly is copied around. This typically happens when
another library project references the binding project, in which
case the ResolveAssemblyReference task will add the binding
library to the ReferenceCopyLocalPaths item group (when building
the library project), which will cause the binding assembly to be
copied to the output directory for the other library project.
If this isn't done, then any projects referencing the library
project (and not the binding project), won't see any binding
resource packages from the binding project.
This is not good (https://github.com/xamarin/xamarin-macios/issues/13910).
This is a target that runs after the ReferenceCopyLocalPaths item
group has been populated by the ResolveAssemblyReferences target,
and will add any binding resource packages to the
ReferenceCopyLocalPaths item group.
This is somewhat complicated by the fact that we can have
.resources bundles (i.e. directories), so we need to expand those
to all their contained files.
-->

<ItemGroup>
<!-- List all potential compressed binding resource packages next to the assemblies we're copying to the output directory -->
<_CompressedBindingPackagesFromReferencedAssembliesCandidates Include="@(ReferenceCopyLocalPaths -> '%(RootDir)%(Directory)%(Filename).resources.zip')" />
<!-- We only care about those that actually exist, and we don't want duplicates either -->
<_CompressedBindingPackagesFromReferencedAssemblies Include="@(_CompressedBindingPackagesFromReferencedAssembliesCandidates->Distinct())" Condition="Exists('%(Identity)')" />

<!-- List all potential binding resource packages next to the assemblies we're copying to the output directory -->
<_BindingPackagesFromReferencedAssembliesDirectoriesCandidates Include="@(ReferenceCopyLocalPaths -> '%(RootDir)%(Directory)%(Filename).resources')" />
<!-- We only care about those that actually exist, and we don't want duplicates either -->
<_BindingPackagesFromReferencedAssembliesDirectoriesExists Include="@(_BindingPackagesFromReferencedAssembliesDirectoriesCandidates->Distinct())" Condition="Exists('%(Identity)')" />
</ItemGroup>

<!--
We need to expand items in an item group using globs, which is
kind of tricky, because globs in item transformations aren't
treated as globs. The workaround is to use a custom task for this.
Note that this task should run remotely from Windows when there's
a Mac connected, but locally when there's not a Mac connected (for
Hot Restart builds for instance), so we're not conditioning this
task on IsMacEnabled.
-->
<GetFileSystemEntries
SessionId="$(BuildSessionId)"
DirectoryPath="@(_BindingPackagesFromReferencedAssembliesDirectoriesExists)"
Pattern="*"
Recursive="true"
IncludeDirectories="false"
>
<Output TaskParameter="Entries" ItemName="_BindingPackagesFromReferencedAssemblies" />
</GetFileSystemEntries>

<ItemGroup>
<!-- We need to set the 'DestinationSubDirectory' metadata to indicate the actual target directory for items we expanded using a wildcard -->
<_BindingPackagesFromReferencedAssembliesWithDestinationDir Include="@(_BindingPackagesFromReferencedAssemblies)">
<DestinationSubDirectory>$([System.IO.Path]::GetFileName('%(OriginalItemSpec)'))\$([System.IO.Path]::GetDirectoryName('%(RecursiveDir)'))\</DestinationSubDirectory>
</_BindingPackagesFromReferencedAssembliesWithDestinationDir>
<!-- Add what we found to ReferenceCopyLocalPaths. Note that binding resource packages should generally not be published, so we're setting PublishFolderType=None -->
<ReferenceCopyLocalPaths Include="@(_CompressedBindingPackagesFromReferencedAssemblies)">
<PublishFolderType>None</PublishFolderType>
</ReferenceCopyLocalPaths>
<ReferenceCopyLocalPaths Include="@(_BindingPackagesFromReferencedAssembliesWithDestinationDir)">
<PublishFolderType>None</PublishFolderType>
</ReferenceCopyLocalPaths>
</ItemGroup>
</Target>

<!-- Import existing targets -->

<PropertyGroup>
Expand Down
31 changes: 23 additions & 8 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/GetFileSystemEntriesTaskBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

#nullable enable

namespace Xamarin.MacDev.Tasks {
public abstract class GetFileSystemEntriesTaskBase : XamarinTask {
#region Inputs

[Required]
public string DirectoryPath { get; set; }
public ITaskItem [] DirectoryPath { get; set; } = Array.Empty<ITaskItem> ();

[Required]
public string Pattern { get; set; }
public string Pattern { get; set; } = string.Empty;

[Required]
public bool Recursive { get; set; }
Expand All @@ -26,18 +28,31 @@ public abstract class GetFileSystemEntriesTaskBase : XamarinTask {
#region Outputs

[Output]
public ITaskItem [] Entries { get; set; }
public ITaskItem [] Entries { get; set; } = Array.Empty<ITaskItem> ();

#endregion

public override bool Execute ()
{
var searchOption = Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
var entriesFullPath = IncludeDirectories ?
Directory.GetFileSystemEntries (DirectoryPath, Pattern, searchOption) :
Directory.GetFiles (DirectoryPath, Pattern, searchOption);

Entries = entriesFullPath.Select (v => new TaskItem (v)).ToArray ();
var entries = new List<ITaskItem> ();
foreach (var item in DirectoryPath) {
var path = item.ItemSpec.TrimEnd ('\\', '/');
var entriesFullPath = IncludeDirectories ?
Directory.GetFileSystemEntries (path, Pattern, searchOption) :
Directory.GetFiles (path, Pattern, searchOption);

foreach (var entry in entriesFullPath) {
var recursiveDir = entry.Substring (path.Length + 1);
var newItem = new TaskItem (entry);
item.CopyMetadataTo (newItem);
newItem.SetMetadata ("RecursiveDir", recursiveDir);
newItem.SetMetadata ("OriginalItemSpec", item.ItemSpec);
entries.Add (newItem);
}
}

Entries = entries.ToArray ();

return !Log.HasLoggedErrors;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Foundation;

namespace BindingWithUncompressedResourceBundle {
[BaseType (typeof (NSObject))]
interface MyNativeClass {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Foundation;

namespace BindingWithUncompressedResourceBundle {
[BaseType (typeof (NSObject))]
interface MyNativeClass {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace BindingWithUncompressedResourceBundle {
public class MyClass {
public MyClass ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BindingWithUncompressedResourceBundle {
public struct MyStruct {
public int A;
public int B;
}
}
8 changes: 8 additions & 0 deletions tests/dotnet/BindingWithUncompressedResourceBundle/MyClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace BindingWithUncompressedResourceBundle {
public class MyClass {
public MyClass ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BindingWithUncompressedResourceBundle {
public struct MyStruct {
public int A;
public int B;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Foundation;

namespace BindingWithUncompressedResourceBundle {
[BaseType (typeof (NSObject))]
interface MyNativeClass {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-ios</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace BindingWithUncompressedResourceBundle {
public class MyClass {
public MyClass ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BindingWithUncompressedResourceBundle {
public struct MyStruct {
public int A;
public int B;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Foundation;

namespace BindingWithUncompressedResourceBundle {
[BaseType (typeof (NSObject))]
interface MyNativeClass {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-macos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace BindingWithUncompressedResourceBundle {
public class MyClass {
public MyClass ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BindingWithUncompressedResourceBundle {
public struct MyStruct {
public int A;
public int B;
}
}
16 changes: 16 additions & 0 deletions tests/dotnet/BindingWithUncompressedResourceBundle/shared.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<IsBindingProject>true</IsBindingProject>
</PropertyGroup>

<Import Project="../../common/shared-dotnet.csproj" />

<ItemGroup>
<ObjcBindingApiDefinition Include="ApiDefinition.cs" />
<ObjcBindingCoreSource Include="StructsAndEnums.cs" />
<NativeReference Include="..\..\..\test-libraries\.libs\$(NativeLibName)\libtest.a">
<Kind>Static</Kind>
</NativeReference>
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions tests/dotnet/BindingWithUncompressedResourceBundle/shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TOP=../../../..
include $(TOP)/tests/common/shared-dotnet.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Foundation;

namespace BindingWithUncompressedResourceBundle {
[BaseType (typeof (NSObject))]
interface MyNativeClass {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-tvos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;
namespace BindingWithUncompressedResourceBundle {
public class MyClass {
public MyClass ()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BindingWithUncompressedResourceBundle {
public struct MyStruct {
public int A;
public int B;
}
}
10 changes: 10 additions & 0 deletions tests/dotnet/LibraryReferencingBindingLibrary/Library.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace LibraryReferencingBindingLibrary {
public class Library {
public static void DoSomething ()
{
Console.WriteLine (typeof (MyClassLibrary.MyClass));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-maccatalyst</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
2 changes: 2 additions & 0 deletions tests/dotnet/LibraryReferencingBindingLibrary/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TOP=../../..
include $(TOP)/tests/common/shared-dotnet-test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-ios</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>
1 change: 1 addition & 0 deletions tests/dotnet/LibraryReferencingBindingLibrary/iOS/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-macos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
11 changes: 11 additions & 0 deletions tests/dotnet/LibraryReferencingBindingLibrary/shared.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="../../common/shared-dotnet.csproj" />

<ItemGroup>
<Compile Include="../*.cs" />
<ProjectReference Include="../../BindingWithDefaultCompileInclude/$(_PlatformName)/BindingWithDefaultCompileInclude.csproj" />
<ProjectReference Include="../../BindingWithUncompressedResourceBundle/$(_PlatformName)/BindingWithUncompressedResourceBundle.csproj" />
<ProjectReference Include="../../../bindings-framework-test/dotnet/$(_PlatformName)/bindings-framework-test.csproj" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions tests/dotnet/LibraryReferencingBindingLibrary/shared.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TOP=../../../..
include $(TOP)/tests/common/shared-dotnet.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net$(BundledNETCoreAppTargetFrameworkVersion)-tvos</TargetFramework>
</PropertyGroup>
<Import Project="..\shared.csproj" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../shared.mk
Loading

6 comments on commit 7ea0044

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.