Skip to content

Commit

Permalink
Generate fake WinMD for XAML compiler
Browse files Browse the repository at this point in the history
Generate fake WinMD from projection dlls instead of swapping WinMDs and projections around
  • Loading branch information
driver1998 committed Aug 10, 2024
1 parent 8f6d768 commit 3ac2565
Show file tree
Hide file tree
Showing 18 changed files with 213 additions and 457 deletions.
13 changes: 13 additions & 0 deletions BuildTasks/BuildTasks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>DisposableMemory.ModernUAP.BuildTasks</AssemblyName>
<LangVersion>8</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.10.4" PrivateAssets="all" ExcludeAssets="Runtime"/>
<PackageReference Include="Mono.Cecil" Version="$(_PkgMono_Cecil_Version)" PrivateAssets="all"/>
</ItemGroup>
</Project>
73 changes: 73 additions & 0 deletions BuildTasks/GenerateFakeWinMD.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Mono.Cecil;

namespace DisposableMemory.ModernUAP.BuildTasks
{
public class GenerateFakeWinMD : Task
{
[Required]
public ITaskItem[] SourceProjectionDlls { get; set; }

[Required]
public string TargetWinMD { get; set; }

public override bool Execute()
{
try
{
Log.LogMessage(MessageImportance.High, "Generating Fake WinMD...");

var assemblyName = new AssemblyNameDefinition("Windows.FakeWinMetadata", new Version(0, 0, 0, 0));
using var outputAssembly = AssemblyDefinition.CreateAssembly(assemblyName, "Windows.FakeWinMetadata.dll", ModuleKind.Dll);
outputAssembly.Name.IsWindowsRuntime = true;

var outputModule = outputAssembly.MainModule;
MethodReference fowardedToAttrCtor = outputModule.ImportReference(typeof(TypeForwardedToAttribute).GetConstructor(new Type[] { typeof(Type) }));

var sourceAssemblyList = SourceProjectionDlls.Select(p => p.ItemSpec).ToList();
Log.LogMessage(MessageImportance.High, "Source projections: \n" + string.Join("\n", sourceAssemblyList));

foreach (var sourceAssemblyFile in sourceAssemblyList)
{
using var sourceAssembly = AssemblyDefinition.ReadAssembly(sourceAssemblyFile);
foreach (var type in sourceAssembly.MainModule.Types)
{
if (string.IsNullOrEmpty(type.Namespace))
{
continue;
}
if (!type.IsPublic)
{
continue;
}
if (!type.CustomAttributes.Any(p => p.AttributeType.FullName == "WinRT.WindowsRuntimeTypeAttribute"))
{
continue;
}

var attr = new CustomAttribute(fowardedToAttrCtor);
var typeRef = outputModule.ImportReference(type);
var attrParam = new CustomAttributeArgument(outputModule.ImportReference(typeof(Type)), typeRef);
attr.ConstructorArguments.Add(attrParam);
outputAssembly.CustomAttributes.Add(attr);
outputModule.ExportedTypes.Add(new ExportedType(typeRef.Namespace, typeRef.Name, typeRef.Module, typeRef.Scope));
}
}

outputAssembly.Write(TargetWinMD);
Log.LogMessage(MessageImportance.High, "Output file: " + TargetWinMD);
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, showStackTrace: true);
return false;
}

}
}
}
69 changes: 69 additions & 0 deletions BuildTasks/NativeAotFixup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.Text.RegularExpressions;

namespace BuildTasks
{
public class NativeAotFixup : Task
{
[Required]
public string ObjDirectory { get; set; }

public override bool Execute()
{
try
{
{
var xamlTypeInfoCs = Path.Combine(ObjDirectory, "XamlTypeInfo.g.cs");
if (!File.Exists(xamlTypeInfoCs))
{
Log.LogError("XamlTypeInfo.g.cs does not exist in " + ObjDirectory);
return false;
}
var str = File.ReadAllText(xamlTypeInfoCs);
str = Regex.Replace(str,
"public sealed class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider",
"public sealed partial class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider");
str = Regex.Replace(str,
"internal class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType",
"internal partial class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType");
str = Regex.Replace(str,
"internal class XamlUserType : global::(.*?)_XamlTypeInfo.XamlSystemBaseType",
"internal partial class XamlUserType : global::$1_XamlTypeInfo.XamlSystemBaseType");
str = Regex.Replace(str,
"internal class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember",
"internal partial class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember");
File.WriteAllText(xamlTypeInfoCs, str);
}

var pagePass2CsList = Directory.GetFiles(ObjDirectory, "*.g.cs");
foreach (var pagePass2Cs in pagePass2CsList)
{
var filename = Path.GetFileName(pagePass2Cs);
if (string.Equals(filename, "App.g.cs", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(filename, "XamlTypeInfo.g.cs", StringComparison.InvariantCultureIgnoreCase))
{
continue;
}

var path = Path.Combine(ObjDirectory, filename);

var str = File.ReadAllText(path);
str = Regex.Replace(str,
"private class (.*?_obj\\d*_Bindings) :(\\s+global::Windows.UI.Xaml.(?:IDataTemplateExtension|Markup.IDataTemplateComponent|Markup.IXamlBindScopeDiagnostics|Markup.IComponentConnector),)",
"private partial class $1 :$2");
File.WriteAllText(path, str);
}

return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, showStackTrace: true);
return false;
}
}
}
}
6 changes: 6 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_PkgMono_Cecil_Version>0.11.5</_PkgMono_Cecil_Version>
</PropertyGroup>
</Project>
31 changes: 7 additions & 24 deletions ModernXamlCompiler.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,20 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33502.453
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SystemInteropServicesWindowsRuntimeShim", "shims\SystemInteropServicesWindowsRuntimeShim\SystemInteropServicesWindowsRuntimeShim.csproj", "{67C08941-8DA6-410D-885B-DD8ADF0AADB2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SystemRuntimeWindowsRuntimeShim", "shims\SystemRuntimeWindowsRuntimeShim\SystemRuntimeWindowsRuntimeShim.csproj", "{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SystemRuntimeWindowsRuntimeXamlShim", "shims\SystemRuntimeWindowsRuntimeXamlShim\SystemRuntimeWindowsRuntimeXamlShim.csproj", "{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A}"
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "ModernXamlCompiler", "ModernXamlCompiler\ModernXamlCompiler.msbuildproj", "{909246B3-1658-4E63-8030-4DB48442248A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shims", "Shims", "{59A8A63D-C0F4-4A65-A90B-D696DFA9B0CF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projections", "Projections", "{F3E8B257-26E3-4527-B03D-3302576A2F47}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUIProjection", "projections\WinUI\WinUIProjection.csproj", "{A678867C-D533-49BE-81A5-B0DDE7FEC701}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUIProjection", "Projections\WinUI\WinUIProjection.csproj", "{A678867C-D533-49BE-81A5-B0DDE7FEC701}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildTasks", "BuildTasks\BuildTasks.csproj", "{8ED633AD-A29E-4919-8F5B-5D564F62BB9B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{67C08941-8DA6-410D-885B-DD8ADF0AADB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67C08941-8DA6-410D-885B-DD8ADF0AADB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67C08941-8DA6-410D-885B-DD8ADF0AADB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67C08941-8DA6-410D-885B-DD8ADF0AADB2}.Release|Any CPU.Build.0 = Release|Any CPU
{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0}.Release|Any CPU.Build.0 = Release|Any CPU
{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A}.Release|Any CPU.Build.0 = Release|Any CPU
{909246B3-1658-4E63-8030-4DB48442248A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{909246B3-1658-4E63-8030-4DB48442248A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{909246B3-1658-4E63-8030-4DB48442248A}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -43,14 +25,15 @@ Global
{A678867C-D533-49BE-81A5-B0DDE7FEC701}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A678867C-D533-49BE-81A5-B0DDE7FEC701}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A678867C-D533-49BE-81A5-B0DDE7FEC701}.Release|Any CPU.Build.0 = Release|Any CPU
{8ED633AD-A29E-4919-8F5B-5D564F62BB9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8ED633AD-A29E-4919-8F5B-5D564F62BB9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8ED633AD-A29E-4919-8F5B-5D564F62BB9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8ED633AD-A29E-4919-8F5B-5D564F62BB9B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{67C08941-8DA6-410D-885B-DD8ADF0AADB2} = {59A8A63D-C0F4-4A65-A90B-D696DFA9B0CF}
{ECE5D9A3-78B7-43B8-8904-08196DEFE4E0} = {59A8A63D-C0F4-4A65-A90B-D696DFA9B0CF}
{08CDDB70-E1D7-40E3-A5E8-B26EA3E0944A} = {59A8A63D-C0F4-4A65-A90B-D696DFA9B0CF}
{A678867C-D533-49BE-81A5-B0DDE7FEC701} = {F3E8B257-26E3-4527-B03D-3302576A2F47}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Expand Down
33 changes: 19 additions & 14 deletions ModernXamlCompiler/ModernXamlCompiler.msbuildproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<PropertyGroup>
<PackageId>DisposableMemory.ModernNetUAP.XamlCompiler</PackageId>
<Version>0.1.0</Version>
<Version>0.2.0</Version>
<Authors>driver1998</Authors>
<Description>UWP (Windows.UI.Xaml) Xaml Compiler support for Modern .NET</Description>
<PackageProjectUrl>https://github.com/driver1998/ModernNetUAP.XamlCompiler</PackageProjectUrl>
Expand All @@ -14,27 +14,32 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\shims\SystemInteropServicesWindowsRuntimeShim\SystemInteropServicesWindowsRuntimeShim.csproj">
<ProjectReference Include="..\BuildTasks\BuildTasks.csproj">
<OutputItemType>Content</OutputItemType>
<IncludeAssets>all</IncludeAssets>
<Pack>true</Pack>
<PackagePath>shims</PackagePath>
</ProjectReference>
<ProjectReference Include="..\shims\SystemRuntimeWindowsRuntimeShim\SystemRuntimeWindowsRuntimeShim.csproj">
<OutputItemType>Content</OutputItemType>
<Pack>true</Pack>
<PackagePath>shims</PackagePath>
</ProjectReference>
<ProjectReference Include="..\shims\SystemRuntimeWindowsRuntimeXamlShim\SystemRuntimeWindowsRuntimeXamlShim.csproj">
<OutputItemType>Content</OutputItemType>
<Pack>true</Pack>
<PackagePath>shims</PackagePath>
<PackagePath>tasks</PackagePath>
</ProjectReference>
</ItemGroup>


<ItemGroup>
<None Include="build\*" Pack="true" PackagePath="build"/>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="$(_PkgMono_Cecil_Version)" PrivateAssets="all" GeneratePathProperty="true"/>
</ItemGroup>

<Target
Name="CopyProjectReferencesToPackage"
AfterTargets="ResolveReferences">

<ItemGroup>
<Content Include="$(PkgMono_Cecil)/lib/netstandard2.0/**/*.dll">
<Pack>true</Pack>
<PackagePath>tasks</PackagePath>
</Content>
</ItemGroup>
</Target>
</Project>
Loading

0 comments on commit 3ac2565

Please sign in to comment.