Skip to content

Commit

Permalink
Support multiple authored runtime components (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
j0shuams authored Aug 6, 2021
1 parent 2c76f77 commit d481c07
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 41 deletions.
54 changes: 25 additions & 29 deletions nuget/Microsoft.Windows.CsWinRT.Authoring.Transitive.targets
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,40 @@
</PropertyGroup>

<PropertyGroup>
<!-- Local variables -->
<HostingSupport-Net5Dir>$(MSBuildThisFileDirectory)..\lib\net5.0*</HostingSupport-Net5Dir>
<HostingSupport-MetadataDir>$(HostingSupport-Net5Dir)\winmd</HostingSupport-MetadataDir>
<HostingSupport-RuntimesDir>$(MSBuildThisFileDirectory)..\runtimes</HostingSupport-RuntimesDir>
<HostingSupport-DependenciesDir>$(MSBuildThisFileDirectory)..\build\native</HostingSupport-DependenciesDir>
<HostingSupport-IsNative Condition="'$(TargetFramework)' == 'native' OR '$(TargetFramework)' == ''">true</HostingSupport-IsNative>
<HostingSupport-IsArmArch Condition="'$(Platform)' == 'arm' OR '$(Platform)' == 'arm64'">true</HostingSupport-IsArmArch>
</PropertyGroup>

<Target Name="CsWinRTAddAuthoredWinMDReference" Condition="'$(HostingSupport-IsNative)' == 'true'" Outputs="@(Reference)">
<!-- Add the WinMD file as a reference of the native app, so a projection can be made -->
<_NormalizedPlatform Condition="'$(Platform)' == 'Win32'">x86</_NormalizedPlatform>
<_NormalizedPlatform Condition="'$(_NormalizedPlatform)' == ''">$(Platform)</_NormalizedPlatform>
</PropertyGroup>

<ItemGroup>
<!-- Managed, WinRT and SDK.NET dlls -->
<HostingAssets Include="$(MSBuildThisFileDirectory)..\lib\net5.0*\*.dll"/>
<!-- Managed DLLs from packages the component depends on -->
<HostingAssets Include="$(MSBuildThisFileDirectory)..\build\native\*.dll"/>
<!-- Add the runtimeconfig.json -->
<HostingAssets Include="$(MSBuildThisFileDirectory)..\build\native\WinRT.Host.runtimeconfig.json"/>
<!-- Get the proper WinRT.Host.dll -->
<HostingAssets Include="$(MSBuildThisFileDirectory)..\runtimes\win-$(_NormalizedPlatform)\native\WinRT.Host.dll" />
</ItemGroup>

<!-- Add the WinMD file as a reference of the native app so a projection gets made -->
<Target Name="CsWinRTAddAuthoredWinMDReference" Condition="'$(TargetFramework)' == 'native' OR '$(TargetFramework)' == ''" Outputs="@(Reference)">

<ItemGroup>
<Reference Include="$(HostingSupport-MetadataDir)\*.winmd">
<Reference Include="$(MSBuildThisFileDirectory)..\lib\net5.0*\winmd\*.winmd">
<IsWinMDFile>true</IsWinMDFile>
<Implementation>WinRT.Host.dll</Implementation>
</Reference>
</ItemGroup>

</Target>

<Target Name="CsWinRTCopyAuthoringDlls" Condition="'$(HostingSupport-IsNative)' == 'true'" Outputs="@(ReferenceCopyLocalPaths)">
<!-- Make sure the runtime assets are available to the app -->
<Target Name="CsWinRTCopyAuthoringDlls" Condition="'$(TargetFramework)' == 'native' OR '$(TargetFramework)' == ''" Outputs="@(ReferenceCopyLocalPaths)">

<ItemGroup>
<!-- Managed, WinRT and SDK.NET dlls -->
<ReferenceCopyLocalPaths Include="$(HostingSupport-Net5Dir)\*.dll" />

<!-- Managed DLLs from packages the component depends on -->
<ReferenceCopyLocalPaths Include="$(HostingSupport-DependenciesDir)\*.dll" />

<!-- Add the runtimeconfig.json -->
<ReferenceCopyLocalPaths Include="$(HostingSupport-DependenciesDir)\WinRT.Host.runtimeconfig.json" />

<!-- Get the proper WinRT.Host.dll -->
<ReferenceCopyLocalPaths Include="$(HostingSupport-RuntimesDir)\win-$(Platform)\native\WinRT.Host.dll"
Condition="'$(Platform)' == 'x64' OR '$(Platform)' == 'x86' OR '$(HostingSupport-IsArmArch)' == 'true'" />

<!-- Treat Win32 platform as win-x86 architecture -->
<ReferenceCopyLocalPaths Include="$(HostingSupport-RuntimesDir)\win-x86\native\WinRT.Host.dll"
Condition="'$(Platform)' == 'Win32'"/>
<ReferenceCopyLocalPaths Include="@(HostingAssets)"/>
</ItemGroup>

</Target>

</Project>
103 changes: 91 additions & 12 deletions nuget/Microsoft.Windows.CsWinRT.Authoring.targets
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<CsWinRTAuthoringWinMDs Include="@(CsWinRTInputs)" />
<CsWinRTAuthoringDistinctWinMDs Include="@(CsWinRTAuthoringWinMDs->Distinct())" />
</ItemGroup>

<PropertyGroup>
<CsWinRTAuthoringInputs>$(CsWinRTAuthoringInputs) @(CsWinRTAuthoringDistinctWinMDs->'"%(FullPath)"', ' ') </CsWinRTAuthoringInputs>
</PropertyGroup>

</Target>

<!-- For Project Reference consumers, copy the necessary WinRT DLLs to output directory -->
<ItemGroup>

<CsWinRTAuthoringDependencyDlls Condition="Exists('$(CsWinRTPath)lib\net5.0\WinRT.Host.Shim.dll')" Include="$(CsWinRTPath)lib\net5.0\WinRT.Host.Shim.dll" />
<CsWinRTAuthoringDependencyDlls Condition="Exists('$(CsWinRTPath)lib\net5.0\WinRT.Runtime.dll')" Include="$(CsWinRTPath)lib\net5.0\WinRT.Runtime.dll" />

Expand All @@ -69,13 +72,16 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<TargetPath>WinRT.Host.dll</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

</ItemGroup>

<!-- Add the RuntimeConfig to output of project reference consumers -->
<Target Name="CsWinRTAuthoring_AddRuntimeDependenciesToContent"
AfterTargets="GenerateBuildRuntimeConfigurationFiles"
BeforeTargets="GetCopyToOutputDirectoryItems;_GetCopyToOutputDirectoryItemsFromThisProject">

<ItemGroup>

<AllItemsFullPathWithTargetPath Include="$(ProjectRuntimeConfigFilePath)">
<TargetPath>$([System.IO.Path]::GetFileName($(ProjectRuntimeConfigFilePath)))</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand All @@ -85,20 +91,15 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<TargetPath>$([System.IO.Path]::GetFileName($(ProjectRuntimeConfigFilePath)))</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AllPublishItemsFullPathWithTargetPath>

</ItemGroup>

</Target>

<!-- Update the project's output to include the generated WinMD.
ResolveableAssembly metadata decides who we can support:
if it is not present, we support C++, but not C#
=> solution: sdk1130 error becomes a warning
if it is present (as 'false'), we support C#, but not C++
=> solution: C++/WinRT targets need to use _ResolvedNativeProjectReferencePaths
-->
<Target Name="GetTargetPath" Returns="@(TargetPathWithTargetPlatformMoniker)">

<ItemGroup>

<TargetPathWithTargetPlatformMoniker Include="$(TargetDir)$(AssemblyName).winmd">
<BuildReference>true</BuildReference>
<WinMDFile>true</WinMDFile>
Expand All @@ -107,26 +108,34 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<FileType>winmd</FileType>
<Primary>true</Primary>
</TargetPathWithTargetPlatformMoniker>

</ItemGroup>

</Target>

<!-- Prevent C++ apps from thinking there is a framework mismatch by setting our target framework to blank.
Note, this does prevent C#/WinRT apps from cross-platform targeting, but a netcore3.1 app wouldn't use C#/WinRT anyway -->
<Target Name="GetTargetFrameworks" Returns="@(_ThisProjectBuildMetadata)">

<ItemGroup>

<_ThisProjectBuildMetadata Include="$(MSBuildProjectFullPath)">
<TargetFrameworks></TargetFrameworks>
<TargetFrameworkMonikers></TargetFrameworkMonikers>
<TargetPlatformMonikers></TargetPlatformMonikers>
<HasSingleTargetFramework>true</HasSingleTargetFramework>
<IsRidAgnostic>true</IsRidAgnostic>
</_ThisProjectBuildMetadata>

</ItemGroup>

</Target>

<!-- For project references, we need to copy the SDK.NET.dll to the output directory -->
<Target Name="CsWinRTCopySDKRefDllToOutDir" AfterTargets="ResolveRuntimePackAssets">

<ItemGroup>

<!-- Local item group to store the SDK.NET.dll -->
<CsWinRTSDKRefDll Include="@(RuntimePackAsset)" Condition="'%(RuntimePackAsset.DestinationSubPath)' == 'Microsoft.Windows.SDK.NET.dll'" />
<!-- Use the below item group to package up managed DLLs from one source -->
Expand All @@ -137,13 +146,80 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>Microsoft.Windows.SDK.NET.dll</TargetPath>
</_ThisProjectItemstoCopyToOutputDirectory>

</ItemGroup>

</Target>

<Target Name="CsWinRTGenerateTransitiveTargets" BeforeTargets="CsWinRTIncludeHostDlls">

<!-- Use the Authoring.Transitive targets as a template to rewrite for the authoring component -->
<Copy SourceFiles="$(MSBuildThisFileDirectory)Microsoft.Windows.CsWinRT.Authoring.Transitive.targets"
DestinationFolder="$(CsWinRTGeneratedFilesDir)" UseHardlinksIfPossible="false" SkipUnchangedFiles="true" />

<PropertyGroup>
<AuthoringTransitiveTargets>$(CsWinRTGeneratedFilesDir)\Microsoft.Windows.CsWinRT.Authoring.Transitive.targets</AuthoringTransitiveTargets>

<PeekQuery_Depends1>Project/PropertyGroup/ResolveReferencesDependsOn/text()</PeekQuery_Depends1>
<PokeQuery_Depends1>Project/PropertyGroup/ResolveReferencesDependsOn</PokeQuery_Depends1>

<PeekQuery_Depends2>Project/PropertyGroup/BuildDependsOn/text()</PeekQuery_Depends2>
<PokeQuery_Depends2>Project/PropertyGroup/BuildDependsOn</PokeQuery_Depends2>

<PeekQuery_Target1>Project/Target[@Name='CsWinRTAddAuthoredWinMDReference']/@Name</PeekQuery_Target1>
<PokeQuery_Target1>Project/Target[@Name='CsWinRTAddAuthoredWinMDReference']/@Name</PokeQuery_Target1>

<PeekQuery_Target2>Project/Target[@Name='CsWinRTCopyAuthoringDlls']/@Name</PeekQuery_Target2>
<PokeQuery_Target2>Project/Target[@Name='CsWinRTCopyAuthoringDlls']/@Name</PokeQuery_Target2>
</PropertyGroup>

<!-- Peeks -->

<XmlPeek XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PeekQuery_Depends1)">
<Output TaskParameter="Result" ItemName="Peeked_Depends1" />
</XmlPeek>

<XmlPeek XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PeekQuery_Depends2)">
<Output TaskParameter="Result" ItemName="Peeked_Depends2" />
</XmlPeek>

<XmlPeek XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PeekQuery_Target1)">
<Output TaskParameter="Result" ItemName="Peeked_Target1" />
</XmlPeek>

<XmlPeek XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PeekQuery_Target2)">
<Output TaskParameter="Result" ItemName="Peeked_Target2" />
</XmlPeek>

<PropertyGroup>
<Flat_Peeked_Depends1>@(Peeked_Depends1)</Flat_Peeked_Depends1>
<Flat_Peeked_Depends2>@(Peeked_Depends2)</Flat_Peeked_Depends2>
<Flat_Peeked_Target1>@(Peeked_Target1)</Flat_Peeked_Target1>
<Flat_Peeked_Target2>@(Peeked_Target2)</Flat_Peeked_Target2>
</PropertyGroup>

<!-- Transform the fetched xml nodes -->
<PropertyGroup>
<Transformed1>$([System.String]::Copy('$(Flat_Peeked_Depends1)').Replace('CsWinRT','$(AssemblyName)'))</Transformed1>
<Transformed2>$([System.String]::Copy('$(Flat_Peeked_Depends2)').Replace('CsWinRT','$(AssemblyName)'))</Transformed2>
<Transformed3>$([System.String]::Copy('$(Flat_Peeked_Target1)').Replace('CsWinRT','$(AssemblyName)'))</Transformed3>
<Transformed4>$([System.String]::Copy('$(Flat_Peeked_Target2)').Replace('CsWinRT','$(AssemblyName)'))</Transformed4>
</PropertyGroup>

<!-- Change the target names -->
<XmlPoke XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PokeQuery_Depends1)" Value="$(Transformed1)"/>
<XmlPoke XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PokeQuery_Depends2)" Value="$(Transformed2)"/>
<XmlPoke XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PokeQuery_Target1)" Value="$(Transformed3)"/>
<XmlPoke XmlInputPath="$(AuthoringTransitiveTargets)" Query="$(PokeQuery_Target2)" Value="$(Transformed4)"/>

</Target>

<!-- When an authored component makes a nupkg, add the necessary hosting assets to the package -->
<Target Name="CsWinRTIncludeHostDlls" BeforeTargets="AfterBuild" Outputs="@(Content)">
<Target Name="CsWinRTIncludeHostDlls" DependsOnTargets="CsWinRTGenerateTransitiveTargets" BeforeTargets="AfterBuild" Outputs="@(Content)">

<!-- When packing, include all necessary DLLs and the targets file for DLL copying on the native side -->
<ItemGroup>

<!-- We must pack any managed DLLs the component depends on, because a native consumer won't restore them -->
<Content Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.AssetType)' == 'runtime'">
<Pack>true</Pack>
Expand All @@ -168,8 +244,8 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<PackagePath>lib\$(TargetFramework)\winmd</PackagePath>
</Content>

<!-- Custom targets that copy DLLs for consumers of the authored component. -->
<Content Include="$(CsWinRTPath)build\Microsoft.Windows.CsWinRT.Authoring.Transitive.targets">
<!-- Use a targets file generated for the component -->
<Content Include="$(AuthoringTransitiveTargets)">
<Pack>true</Pack>
<PackagePath>buildTransitive\$(AssemblyName).targets;build\$(AssemblyName).targets</PackagePath>
</Content>
Expand All @@ -196,11 +272,14 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<PackagePath>runtimes\win-arm64\native</PackagePath>
</Content>
</ItemGroup>

</Target>

<!-- Copy Authored winmd to output folder -->
<Target Name="CsWinRTPlaceWinMDInOutputFolder" BeforeTargets="AfterBuild">

<Copy SourceFiles="$(CsWinRTGeneratedFilesDir)\$(AssemblyName).winmd" DestinationFolder="$(TargetDir)" UseHardlinksIfPossible="false" SkipUnchangedFiles="true" />

</Target>

</Project>
2 changes: 2 additions & 0 deletions src/cswinrt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nuget", "Nuget", "{967889B0-4C40-4EA2-8F11-26ECB88205FF}"
ProjectSection(SolutionItems) = preProject
..\nuget\LICENSE = ..\nuget\LICENSE
..\nuget\Microsoft.Windows.CsWinRT.Authoring.targets = ..\nuget\Microsoft.Windows.CsWinRT.Authoring.targets
..\nuget\Microsoft.Windows.CsWinRT.Authoring.Transitive.targets = ..\nuget\Microsoft.Windows.CsWinRT.Authoring.Transitive.targets
..\nuget\Microsoft.Windows.CsWinRT.IIDOptimizer.targets = ..\nuget\Microsoft.Windows.CsWinRT.IIDOptimizer.targets
..\nuget\Microsoft.Windows.CsWinRT.nuspec = ..\nuget\Microsoft.Windows.CsWinRT.nuspec
..\nuget\Microsoft.Windows.CsWinRT.props = ..\nuget\Microsoft.Windows.CsWinRT.props
Expand Down

0 comments on commit d481c07

Please sign in to comment.