Skip to content

Commit

Permalink
Merge branch 'master' of github.com:microsoft/cswinrt into fnptrs
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky committed Jul 10, 2020
2 parents 3e15a45 + c5efd9f commit fd1746f
Show file tree
Hide file tree
Showing 76 changed files with 2,404 additions and 1,258 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ TestWinRT
_build/
global.json
.nuget
.nupkg
nuget/Microsoft.Windows.CsWinRT.Prerelease.targets
55 changes: 55 additions & 0 deletions Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<Platforms>x64;x86</Platforms>
<TargetFrameworks>netcoreapp2.0;net5.0;netcoreapp3.1</TargetFrameworks>
<UseWinmd>false</UseWinmd>
<BenchmarkWinmdSupport Condition="'$(BenchmarkWinmdSupport)' == ''">false</BenchmarkWinmdSupport>
<!-- Controls whether to build using WinMDs or the projection. -->
<UseWinmd Condition="'$(TargetFramework)' == 'netcoreapp3.1' And $(BenchmarkWinmdSupport) == true">true</UseWinmd>
<ApplicationManifest Condition="$(UseWinmd) == true">Benchmarks.manifest</ApplicationManifest>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" Condition="$(UseWinmd) == true"/>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.3" Condition="$(UseWinmd) == false"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Projections\Windows\Windows.csproj" Condition="$(UseWinmd) == false" />
<ProjectReference Include="..\Projections\Benchmark\Benchmark.csproj" Condition="$(UseWinmd) == false" />
<ProjectReference Include="..\TestWinRT\BenchmarkComponent\BenchmarkComponent.vcxproj" Condition="$(UseWinmd) == true" />

<!-- The Benchmark / BenchmarkCompnent reference doesn't seem to bring over the dll when building with dotnet cli, so including both dll and winmd as includes. -->
<None Include="$(MSBuildThisFileDirectory)..\_build\$(Platform)\$(Configuration)\BenchmarkComponent\bin\BenchmarkComponent\BenchmarkComponent.dll">
<Link>BenchmarkComponent.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>True</Visible>
</None>

<Reference Include="BenchmarkComponent.winmd" Condition="$(UseWinmd) == true">
<HintPath>$(MSBuildThisFileDirectory)..\_build\$(Platform)\$(Configuration)\BenchmarkComponent\bin\BenchmarkComponent\BenchmarkComponent.winmd</HintPath>
<IsWinMDFile>true</IsWinMDFile>
</Reference>

<!-- When building for NetCoreApp 3.1, we test the WinMD scenario via reg free winrt, so it needs to be in the bin folder for the generated project to reference it. -->
<None Include="Benchmarks.manifest" Condition="$(UseWinmd) == true">
<Link>Benchmarks.manifest</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>True</Visible>
</None>

</ItemGroup>

<Target Name="FilterProjection" BeforeTargets="CoreCompile" Condition="$(UseWinmd) == false">
<ItemGroup>
<!--Remove references to projection source winmds to prevent compile conflict warnings-->
<ReferencePathWithRefAssemblies Remove="@(ReferencePathWithRefAssemblies)" Condition="%(ReferencePathWithRefAssemblies.Filename) == 'BenchmarkComponent'" />
<!--Also remove ReferencePath winmds to prevent error NETSDK1130 false positive-->
<ReferencePath Remove="@(ReferencePath)" Condition="%(ReferencePath.Filename) == 'BenchmarkComponent'" />
</ItemGroup>
</Target>

</Project>
12 changes: 12 additions & 0 deletions Benchmarks/Benchmarks.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Benchmarks.app"/>

<file name="BenchmarkComponent.dll">
<activatableClass
name="BenchmarkComponent.ClassWithMultipleInterfaces"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>

</assembly>
95 changes: 95 additions & 0 deletions Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using BenchmarkDotNet.Running;
using System;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.CsProj;
using BenchmarkDotNet.Toolchains.DotNetCli;
using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Characteristics;
using System.IO;

namespace Benchmarks
{
public class Program
{
static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new CustomConfig().Config);

private class CustomConfig : Attribute, IConfigSource
{
public IConfig Config { get; } = DefaultConfig.Instance;

public CustomConfig()
{
// Test CsWinRT projection
var job = Job.Default
.WithPlatform(BenchmarkDotNet.Environments.Platform.X64)
.WithArguments(
new Argument[] {
new MsBuildArgument("/p:platform=x64")
}
).AsDefault();

// Test WinMD support
#if NETCOREAPP3_1
// BenchmarkDotNet will rebuild the project with a project reference to this project when this project's output exe is ran. It
// will be ran from the same folder as where we have the application manifest binplaced which we want to embed in the new exe.
string manifestFile = Path.Combine(
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
"Benchmarks.manifest");

var winmdJob = Job.Default
.WithPlatform(BenchmarkDotNet.Environments.Platform.X64)
.WithToolchain(new NetCore3ToolChainWithNativeExecution())
.WithArguments(
new Argument[] {
new MsBuildArgument("/p:platform=x64"),
new MsBuildArgument("/p:ApplicationManifest=" + manifestFile),
new MsBuildArgument("/p:BenchmarkWinmdSupport=true")
}
)
.WithId("WinMD NetCoreApp31");

// Optimizer needs to be diabled as it errors on WinMDs
Config = Config.WithOption(ConfigOptions.DisableOptimizationsValidator, true)
.AddJob(winmdJob);
#else
Config = Config.AddJob(job);
#endif
}
}

// Custom tool chain for building the benchmark with WinMDs as we need to execute the
// exe version of the benchmark rather than the dll version which runs under dotnet cli.
// This is because we need to be able to embed a side by side manifest for reg free winrt
// and we need COM to be able to find the WinMDs.
private class NetCore3ToolChainWithNativeExecution : Toolchain
{
public NetCore3ToolChainWithNativeExecution()
: base("netcoreapp3.1-native",
new CsProjGeneratorWithNativeExe(NetCoreAppSettings.NetCoreApp31),
CsProjCoreToolchain.NetCoreApp31.Builder,
new Executor())
{
}

public override bool IsSupported(BenchmarkCase benchmarkCase, ILogger logger, IResolver resolver)
{
return CsProjCoreToolchain.NetCoreApp31.IsSupported(benchmarkCase, logger, resolver);
}
}

private class CsProjGeneratorWithNativeExe : CsProjGenerator
{
public CsProjGeneratorWithNativeExe(NetCoreAppSettings settings)
:base(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.RuntimeFrameworkVersion)
{
}

protected override string GetExecutableExtension()
{
return ".exe";
}
}
}
}
79 changes: 79 additions & 0 deletions Benchmarks/QueryInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using BenchmarkComponent;
using BenchmarkDotNet.Attributes;
using Windows.ApplicationModel.Chat;

namespace Benchmarks
{
[MemoryDiagnoser]
public class QueryInterfacePerf
{
ClassWithMultipleInterfaces instance;
ChatMessage message;

[GlobalSetup]
public void Setup()
{
instance = new ClassWithMultipleInterfaces();
message = new ChatMessage();
}

[Benchmark]
public int QueryDefaultInterface()
{
return instance.DefaultIntProperty;
}

[Benchmark]
public int QueryNonDefaultInterface()
{
return instance.IntProperty;
}

[Benchmark]
public bool QueryNonDefaultInterface2()
{
return instance.BoolProperty;
}

[Benchmark]
public void QueryDefaultInterfaceSetProperty()
{
instance.DefaultIntProperty = 4;
}

[Benchmark]
public void QueryNonDefaultInterfaceSetProperty()
{
instance.IntProperty = 4;
}

[Benchmark]
public bool QuerySDKDefaultInterface()
{
return message.IsForwardingDisabled;
}

[Benchmark]
public bool QuerySDKNonDefaultInterface()
{
return message.IsSeen;
}

// The following 2 benchmarks try to benchmark the time taken for the first call
// rather than the mean time over several calls. It has the overhead of the object
// construction, but it can be used to track regressions to performance.
[Benchmark]
public int ConstructAndQueryDefaultInterfaceFirstCall()
{
ClassWithMultipleInterfaces instance2 = new ClassWithMultipleInterfaces();
return instance2.DefaultIntProperty;
}

[Benchmark]
public int ConstructAndQueryNonDefaultInterfaceFirstCall()
{
ClassWithMultipleInterfaces instance2 = new ClassWithMultipleInterfaces();
return instance2.IntProperty;
}
}
}
20 changes: 16 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
<VCProjectVersion>15.0</VCProjectVersion>
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
<CppWinRTVerbosity>high</CppWinRTVerbosity>
<MicrosoftWinUIVersion>3.0.0-preview1.200419.0-CI</MicrosoftWinUIVersion>
<MicrosoftWinUIVersion>3.0.0-preview1.200515.3</MicrosoftWinUIVersion>
<!-- Temporary fallback until Microsoft.WinUI nuget supports Net5 TFM -->
<AssetTargetFallback>netcoreapp5.0</AssetTargetFallback>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' != 'net5.0'">
<DefineConstants>$(DefineConstants);MANUAL_IUNKNOWN</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(VisualStudioVersion)' == '15.0'">
Expand All @@ -25,16 +31,20 @@
<BuildPlatform>$(Platform)</BuildPlatform>
<BuildPlatform Condition="'$(Platform)'=='Win32'">x86</BuildPlatform>
<BuildOutDir Condition="'$(BuildOutDir)'==''">$([MSBuild]::NormalizeDirectory('$(SolutionDir)_build', '$(BuildPlatform)', '$(Configuration)'))</BuildOutDir>
<CsWinRTDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', 'cswinrt', 'bin'))</CsWinRTDir>
<CsWinRTDir Condition="'$(Platform)'=='ARM' or '$(Platform)'=='ARM64'">$([MSBuild]::NormalizeDirectory('$(SolutionDir)_build', 'x86', '$(Configuration)', 'cswinrt', 'bin'))</CsWinRTDir>
<CsWinRTExe>$(CsWinRTDir)cswinrt.exe</CsWinRTExe>
<CsWinRTPath>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', 'cswinrt', 'bin'))</CsWinRTPath>
<CsWinRTPath Condition="'$(Platform)'=='ARM' or '$(Platform)'=='ARM64'">$([MSBuild]::NormalizeDirectory('$(SolutionDir)_build', 'x86', '$(Configuration)', 'cswinrt', 'bin'))</CsWinRTPath>
</PropertyGroup>

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
<OutDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin'))</OutDir>
<IntDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj'))</IntDir>
</PropertyGroup>

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
Expand Down Expand Up @@ -79,4 +89,6 @@

<Import Project="Strings.props" />

<Import Condition="'$(MSBuildProjectExtension)' == '.csproj'" Project="nuget\Microsoft.Windows.CsWinRT.props" />

</Project>
13 changes: 4 additions & 9 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
<!--NOTE: Directory.Build.* files are temporary until C#/WinRT nuget contains msbuild support-->
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ResolveAssemblyReferencesDependsOn Condition="'$(RemoveWindowsReference)'=='true'">$(ResolveAssemblyReferencesDependsOn);RemoveWindowsReference</ResolveAssemblyReferencesDependsOn>

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'" >
<GeneratedFilesDir>$([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', 'Generated Files'))</GeneratedFilesDir>
</PropertyGroup>

<!--Remove Windows.Winmd reference to prevent compile collisions-->
<Target Name="RemoveWindowsReference" Outputs="@(Reference)">
<ItemGroup>
<Reference Remove="Windows"/>
</ItemGroup>
</Target>
<Import Condition="'$(MSBuildProjectExtension)' == '.csproj'" Project="nuget\Microsoft.Windows.CsWinRT.targets" />

<ItemGroup Condition="'$(MSBuildProjectExtension)' == '.csproj'">
<PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="3.7.0-3.20302.9" />
Expand Down
65 changes: 65 additions & 0 deletions Projections/Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
<Platforms>x64;x86</Platforms>
<LangVersion>8</LangVersion>
</PropertyGroup>

<PropertyGroup>
<GenerateTestProjection Condition="'$(GenerateTestProjection)$(Configuration)' == 'Release'">true</GenerateTestProjection>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>8305;0618</NoWarn>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<ProjectReference Include="..\..\TestWinRT\BenchmarkComponent\BenchmarkComponent.vcxproj" />
<ProjectReference Include="..\..\WinRT.Runtime\WinRT.Runtime.csproj" />
<ProjectReference Include="..\..\cswinrt\cswinrt.vcxproj" />
<ProjectReference Include="..\Windows\Windows.csproj" />
</ItemGroup>

<Target Name="GenerateProjection" Condition="'$(GenerateTestProjection)' == 'true'">
<ItemGroup>
<ReferenceWinMDs Include="@(ReferencePath)" Condition="'%(ReferencePath.WinMDFile)' == 'true'" />
<!--Do not publish projection source winmds -->
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="%(ReferenceCopyLocalPaths.Filename) == 'BenchmarkComponent'" />
</ItemGroup>
<PropertyGroup>
<CsWinRTVerbosity>high</CsWinRTVerbosity>
<CsWinRTResponseFile>$(GeneratedFilesDir)cswinrt_benchmark.rsp</CsWinRTResponseFile>
<CsWinRTCommand>$(CsWinRTExe) %40"$(CsWinRTResponseFile)"</CsWinRTCommand>
</PropertyGroup>
<PropertyGroup>
<CsWinRTParams>
-verbose
-in 10.0.18362.0
-in @(ReferenceWinMDs->'"%(FullPath)"', ' ')
-out "$(GeneratedFilesDir.TrimEnd('\'))"
-exclude Windows
-include BenchmarkComponent
</CsWinRTParams>
</PropertyGroup>
<MakeDir Directories="$(GeneratedFilesDir)" />
<WriteLinesToFile File="$(CsWinRTResponseFile)" Lines="$(CsWinRTParams)" Overwrite="true" WriteOnlyWhenDifferent="true" />
<Message Text="$(CsWinRTCommand)" Importance="$(CsWinRTVerbosity)" />
<Exec Command="$(CsWinRTCommand)" />
</Target>

<Target Name="IncludeProjection" DependsOnTargets="GenerateProjection" BeforeTargets="CoreCompile">
<ItemGroup>
<Compile Include="$(GeneratedFilesDir)*.cs" Exclude="@(Compile)" />
<!--Remove references to projection source winmds to prevent compile conflict warnings-->
<ReferencePathWithRefAssemblies Remove="@(ReferencePathWithRefAssemblies)" Condition="%(ReferencePathWithRefAssemblies.Filename) == 'BenchmarkComponent'" />
<!--Also remove ReferencePath winmds to prevent error NETSDK1130 false positive-->
<ReferencePath Remove="@(ReferencePath)" Condition="%(ReferencePath.Filename) == 'BenchmarkComponent'" />
</ItemGroup>
</Target>

</Project>
Loading

0 comments on commit fd1746f

Please sign in to comment.