Skip to content

Commit fed0ce3

Browse files
committed
feat: add custom props/targets to customize project build
1 parent f3ac0c1 commit fed0ce3

8 files changed

Lines changed: 76 additions & 5 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project>
2+
<!-- Define properties for benchmark project. -->
3+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$BENCHMARK_PROJ$'">
4+
5+
</PropertyGroup>
6+
7+
<!-- Define properties for DllGatherer.csproj. -->
8+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$GATHERER_PROJ$'">
9+
10+
</PropertyGroup>
11+
12+
<!-- Define properties for BenchmarkDotNet.Autogenerated.csproj. -->
13+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$AUTOGENERATED_PROJ$'">
14+
15+
</PropertyGroup>
16+
</Project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project>
2+
<!-- Define properties for benchmark project. -->
3+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$BENCHMARK_PROJ$'">
4+
5+
</PropertyGroup>
6+
7+
<!-- Define properties for DllGatherer.csproj. -->
8+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$GATHERER_PROJ$'">
9+
10+
</PropertyGroup>
11+
12+
<!-- Define properties for BenchmarkDotNet.Autogenerated.csproj. -->
13+
<PropertyGroup Condition="'$(MSBuildProjectFile)' == '$AUTOGENERATED_PROJ$'">
14+
15+
</PropertyGroup>
16+
</Project>

src/BenchmarkDotNet/Templates/CsProj.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<Project Sdk="$SDKNAME$">
2+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.props" />
23

34
<PropertyGroup>
45
<ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
@@ -46,4 +47,5 @@
4647

4748
$RUNTIMESETTINGS$
4849

50+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.targets" />
4951
</Project>

src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<Project Sdk="Microsoft.NET.Sdk" DefaultTarget="Publish">
1+
<Project Sdk="Microsoft.NET.Sdk" DefaultTarget="Publish">
2+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.props" />
3+
24
<PropertyGroup>
35
<OriginalCSProjPath>$CSPROJPATH$</OriginalCSProjPath>
46
<MonoPropsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Mono.props'))</MonoPropsPath>
@@ -71,7 +73,6 @@
7173
</AotInputAssemblies>
7274
</ItemGroup>
7375

74-
7576
<MonoAOTCompiler
7677
CompilerBinaryPath="$COMPILERBINARYPATH$"
7778
Mode="Normal"
@@ -91,4 +92,5 @@
9192
</Target>
9293

9394
<Import Project="$(MonoTargetsPath)" Condition="Exists($(MonoTargetsPath))" />
95+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.targets" />
9496
</Project>

src/BenchmarkDotNet/Templates/R2RCsProj.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<Project Sdk="Microsoft.NET.Sdk" DefaultTarget="Publish">
2+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.props" />
23

34
<!-- Properties same as standard CsProj.txt template -->
45
<PropertyGroup>
@@ -71,4 +72,6 @@
7172
</Crossgen2Pack>
7273
</ItemGroup>
7374
</Target>
75+
76+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.targets" />
7477
</Project>

src/BenchmarkDotNet/Templates/WasmCsProj.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<Project Sdk="$SDKNAME$" DefaultTargets="publish">
1+
<Project Sdk="$SDKNAME$" DefaultTargets="publish">
2+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.props" />
3+
24
<PropertyGroup>
35
<OriginalCSProjPath>$CSPROJPATH$</OriginalCSProjPath>
46
<WasmPropsPath>$([System.IO.Path]::ChangeExtension('$(OriginalCSProjPath)', '.Wasm.props'))</WasmPropsPath>
@@ -59,4 +61,5 @@ $CORECLR_OVERRIDES$
5961
</Target>
6062

6163
<Import Project="$(WasmTargetsPath)" Condition="Exists($(WasmTargetsPath))" />
64+
<Import Project="$(MSBuildThisFileDirectory)BenchmarkDotNet.Build.targets" />
6265
</Project>

src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace BenchmarkDotNet.Toolchains.CsProj
1919
public class CsProjGenerator : DotNetCliGenerator, IEquatable<CsProjGenerator>
2020
{
2121
private const string DefaultSdkName = "Microsoft.NET.Sdk";
22+
private const string DllGathererProjectName = "DllGatherer.csproj";
23+
private const string AutogeneratedProjectName = "BenchmarkDotNet.Autogenerated.csproj";
2224

2325
private static readonly ImmutableArray<string> SettingsWeWantToCopy = new[]
2426
{
@@ -58,11 +60,32 @@ protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPar
5860
}
5961

6062
protected override string GetProjectFilePath(string buildArtifactsDirectoryPath)
61-
=> Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.csproj");
63+
=> Path.Combine(buildArtifactsDirectoryPath, AutogeneratedProjectName);
6264

6365
protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)
6466
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker);
6567

68+
protected override async ValueTask GenerateCustomBuildHooksAsync(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger, CancellationToken cancellationToken)
69+
{
70+
var benchmark = buildPartition.RepresentativeBenchmarkCase;
71+
var benchmarkProjectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);
72+
73+
var propsPath = Path.Combine(artifactsPaths.BuildArtifactsDirectoryPath, "BenchmarkDotNet.Build.props");
74+
var props = GetTemplateContent("BenchmarkDotNet.Build.props.txt");
75+
await File.WriteAllTextAsync(propsPath, props.ToString(), cancellationToken).ConfigureAwait(false);
76+
77+
var targetsPath = Path.Combine(artifactsPaths.BuildArtifactsDirectoryPath, "BenchmarkDotNet.Build.targets");
78+
var targets = GetTemplateContent("BenchmarkDotNet.Build.targets.txt");
79+
await File.WriteAllTextAsync(targetsPath, targets.ToString(), cancellationToken).ConfigureAwait(false);
80+
81+
string GetTemplateContent(string templateName)
82+
=> new StringBuilder(ResourceHelper.LoadTemplate(templateName))
83+
.Replace("$BENCHMARK_PROJ$", benchmarkProjectFile.Name)
84+
.Replace("$GATHERER_PROJ$", DllGathererProjectName)
85+
.Replace("$AUTOGENERATED_PROJ$", AutogeneratedProjectName)
86+
.ToString();
87+
}
88+
6689
protected override ValueTask GenerateBuildScriptAsync(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, CancellationToken cancellationToken)
6790
{
6891
string projectFilePath = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, NullLogger.Instance).FullName;
@@ -115,7 +138,7 @@ private async ValueTask<string> GenerateBuildProject(BuildPartition buildPartiti
115138
}
116139

117140
private static string GetDllGathererPath(string filePath)
118-
=> Path.Combine(Path.GetDirectoryName(filePath)!, $"DllGatherer{Path.GetExtension(filePath)}");
141+
=> Path.Combine(Path.GetDirectoryName(filePath)!, $"{Path.GetFileNameWithoutExtension(DllGathererProjectName)}{Path.GetExtension(filePath)}");
119142

120143
protected async ValueTask GatherReferencesAsync(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger, CancellationToken cancellationToken)
121144
{

src/BenchmarkDotNet/Toolchains/GeneratorBase.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public async ValueTask<GenerateResult> GenerateProjectAsync(BuildPartition build
3434
// There is no async file copy API, so we just do it synchronously. We are likely on a ThreadPool thread here anyway if this generator is ran in parallel.
3535
CopyAllRequiredFiles(artifactsPaths);
3636

37+
await GenerateCustomBuildHooksAsync(buildPartition, artifactsPaths, logger, cancellationToken).ConfigureAwait(false);
3738
await GenerateCodeAsync(buildPartition, artifactsPaths, cancellationToken).ConfigureAwait(false);
3839
await GenerateAppConfigAsync(buildPartition, artifactsPaths, cancellationToken).ConfigureAwait(false);
3940
await GenerateNuGetConfigAsync(artifactsPaths, cancellationToken).ConfigureAwait(false);
@@ -101,6 +102,11 @@ [PublicAPI] protected virtual void CopyAllRequiredFiles(ArtifactsPaths artifacts
101102
/// </summary>
102103
[PublicAPI] protected virtual ValueTask GenerateProjectAsync(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger, CancellationToken cancellationToken) => new();
103104

105+
/// <summary>
106+
/// generates .props and .targets files to customize build.
107+
/// </summary>
108+
[PublicAPI] protected virtual ValueTask GenerateCustomBuildHooksAsync(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger, CancellationToken cancellationToken) => new();
109+
104110
/// <summary>
105111
/// generates a script can be used when debugging compilation issues
106112
/// </summary>

0 commit comments

Comments
 (0)