Skip to content

Commit

Permalink
[bgen] Fix assembly comparison. Fixes xamarin#19612.
Browse files Browse the repository at this point in the history
This fixes a regression in .NET 8, where we changed the temporary assembly name when
building using a project file / MSBuild - we started compiling the temporary binding
code in MSBuild instead of in the generator, and in the process we changed the name
of the temporary assembly. This broke logic in bgen that compared the assembly name
to check if a given type is from the temporary assembly or not.

Fix this by checking the actual temporary assembly instead of the name of the assembly
instead.

Fixes xamarin#19612.
  • Loading branch information
rolfbjarne committed Dec 11, 2023
1 parent d4c6cfc commit bda19bb
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/bgen/BindingTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class BindingTouch : IDisposable {
public MetadataLoadContext? universe;
public Frameworks? Frameworks;

Assembly? apiAssembly;
AttributeManager? attributeManager;
public AttributeManager AttributeManager => attributeManager!;

Expand Down Expand Up @@ -268,7 +269,7 @@ int Main3 (string [] args)
"mscorlib"
);

if (!TryLoadApi (tmpass, out Assembly? apiAssembly) || !TryLoadApi (LibraryInfo.BaseLibDll, out Assembly? baselib))
if (!TryLoadApi (tmpass, out apiAssembly) || !TryLoadApi (LibraryInfo.BaseLibDll, out Assembly? baselib))
return 1;

Frameworks = new Frameworks (CurrentPlatform);
Expand Down Expand Up @@ -372,6 +373,11 @@ int Main3 (string [] args)
return 0;
}

public bool IsApiAssembly (Assembly assembly)
{
return assembly == apiAssembly;
}

// If anything is modified in this function, check if the _CompileApiDefinitions MSBuild target needs to be updated as well.
string GetCompiledApiBindingsAssembly (LibraryInfo libraryInfo, string tmpdir, IEnumerable<string> refs, bool nostdlib, List<string> api_sources, List<string> core_sources, List<string> defines, IEnumerable<string> paths)
{
Expand Down
4 changes: 2 additions & 2 deletions src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4851,7 +4851,7 @@ void GenerateProtocolTypes (Type type, string class_visibility, string TypeName,
if (sb.Length > 0)
sb.Append (", ");
sb.Append (iface.Namespace).Append ('.');
if (iface.Assembly.GetName ().Name == "temp")
if (BindingTouch.IsApiAssembly (iface.Assembly))
sb.Append ('I');
else if (iface.IsClass)
sb.Append ('I');
Expand Down Expand Up @@ -5528,7 +5528,7 @@ public void Generate (Type type)
string pname = protocolType.Name;
// the extra 'I' is only required for the bindings being built, if it comes from something already
// built (e.g. monotouch.dll) then the interface will alreadybe prefixed
if (protocolType.Assembly.GetName ().Name == "temp")
if (BindingTouch.IsApiAssembly (protocolType.Assembly))
pname = "I" + pname;
var iface = TypeManager.FormatType (type, protocolType.Namespace, pname);
if (!implements_list.Contains (iface))
Expand Down
41 changes: 41 additions & 0 deletions tests/generator/BGenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
using Mono.Cecil;
using Mono.Cecil.Cil;

using Xamarin;
using Xamarin.Tests;
using Xamarin.Utils;

namespace GeneratorTests {
[TestFixture ()]
Expand Down Expand Up @@ -1432,6 +1434,45 @@ public void InternalDelegate ()
BuildFile (Profile.iOS, "tests/internal-delegate.cs");
}

#if NET
[Test]
public void Issue19612 ()
{
var profile = Profile.iOS;
var filename = Path.Combine (Configuration.SourceRoot, "tests", "generator", "issue19612.cs");

Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ());

// Compile the temporary assembly and pass the compiled assembly to the generator instead
// of relying on the generator to compile.
var tmpdir = Cache.CreateTemporaryDirectory ();
var tmpassembly = Path.Combine (tmpdir, "temporaryAssembly.dll");
var cscArguments = new List<string> ();
if (!StringUtils.TryParseArguments (Configuration.DotNetCscCommand, out var cscCommand, out var ex))
throw new InvalidOperationException ($"Unable to parse the .NET csc command '{Configuration.DotNetCscCommand}': {ex.Message}");
cscArguments.AddRange (cscCommand);
var cscExecutable = cscArguments [0];
cscArguments.RemoveAt (0);
cscArguments.Add (filename);
cscArguments.Add ($"/out:{tmpassembly}");
cscArguments.Add ("/target:library");
cscArguments.Add ($"/r:{Path.Combine (Configuration.DotNetBclDir, "System.Runtime.dll")}");
var tf = TargetFramework.Parse (BGenTool.GetTargetFramework (profile));
cscArguments.Add ($"/r:{Configuration.GetBindingAttributePath (tf)}");
cscArguments.Add ($"/r:{Configuration.GetBaseLibrary (tf)}");
var rv = ExecutionHelper.Execute (cscExecutable, cscArguments);
Assert.AreEqual (0, rv, "CSC exit code");

var bgen = new BGenTool ();
bgen.Profile = profile;
bgen.CompiledApiDefinitionAssembly = tmpassembly;
bgen.Defines = BGenTool.GetDefaultDefines (bgen.Profile);
bgen.CreateTemporaryBinding (filename);
bgen.AssertExecute ("build");
bgen.AssertNoWarnings ();
}
#endif

BGenTool BuildFile (Profile profile, params string [] filenames)
{
return BuildFile (profile, true, false, filenames);
Expand Down
6 changes: 6 additions & 0 deletions tests/generator/BGenTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class BGenTool : Tool {
public string? BaseLibrary;
public string? AttributeLibrary;
public bool ReferenceBclByDefault = true;
public string? CompiledApiDefinitionAssembly = null;
#else
public string BaseLibrary = None;
public string AttributeLibrary = None;
Expand Down Expand Up @@ -134,6 +135,11 @@ public static string GetTargetFramework (Profile profile)
sb.Add ($"--compile-command");
sb.Add (string.Join (" ", StringUtils.QuoteForProcess (CompileCommand.ToArray ())));
}

if (CompiledApiDefinitionAssembly is not null) {
sb.Add ($"--compiled-api-definition-assembly");
sb.Add (CompiledApiDefinitionAssembly);
}
#endif

TargetFramework? tf = null;
Expand Down
18 changes: 18 additions & 0 deletions tests/generator/issue19612.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

using Foundation;
using ObjCRuntime;
using UIKit;

namespace iosbindinglib {
[Protocol]
[BaseType(typeof(NSObject))]
public interface ReaderProtocol
{
}

[BaseType(typeof(NSObject))]
public interface Reader : ReaderProtocol
{
}
}

0 comments on commit bda19bb

Please sign in to comment.