Skip to content

Commit 653a2f1

Browse files
committed
Improve warning details in log output
Build acceleration works best when all referenced projects produce a reference assembly each. We recently added a message highlighting when this was not the case, but didn't explain which project needed to be modified in order to fix this issue. This change tracks and logs which projects need updating. The TargetPath is printed for those projects, which will generally also identify the target framework and so is therefore more helpful than just the .csproj file.
1 parent ca4a25d commit 653a2f1

21 files changed

+91
-73
lines changed

docs/build-acceleration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,12 @@ Looking through the build output with the following points in mind:
102102

103103
- ⛔ If you see:
104104

105-
> This project has enabled build acceleration, but at least one referenced project does not produce reference assemblies. Ensure all referenced projects, both direct and indirect, have the 'ProduceReferenceAssembly' MSBuild property set to 'true'.
105+
> This project has enabled build acceleration, but not all referenced projects produce a reference assembly. Ensure projects producing the following outputs have the 'ProduceReferenceAssembly' MSBuild property set to 'true': '<path1>', '<path2>'.
106106
107107
Then build acceleration will not know whether it is safe to copy a modified output DLL from a referenced project or not. We rely on the use of reference assemblies to convey this information. To address this, ensure all referenced projects have the `ProduceReferenceAssembly` property set to `true`. You may like to add this to your `Directory.Build.props` file alongside the `AccelerateBuildsInVisualStudio` property. Note that projects targeting `net5.0` or later produce reference assemblies by default. Projects that target .NET Standard may require this to be specified manually (see https://github.com/dotnet/project-system/issues/8865).
108108

109+
This message lists the referenced projects that are not producing a reference assembly. The `TargetPath` of those projects is used, as this can help disambiguate between target frameworks in multi-targeting projects.
110+
109111
- ✅ You should see a section listing items to copy:
110112

111113
```

src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.FileSystemOperationAggregator.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,26 @@ internal sealed class FileSystemOperationAggregator
5858
public bool? IsAccelerationEnabled { get; internal set; }
5959

6060
/// <summary>
61-
/// Gets whether all referenced projects produce reference assemblies or not.
61+
/// Gets paths to the target of any projects that do not produce a reference assembly, or
62+
/// <see langword="null"/> if none exist.
6263
/// </summary>
6364
/// <remarks>
6465
/// Build acceleration works best when all referenced projects produce reference assemblies.
65-
/// This flag allows us to prompt the user when they have enabled build acceleration, but
66+
/// This collecting allows us to prompt the user when they have enabled build acceleration, but
6667
/// they are referencing projects that do not produce reference assemblies.
6768
/// </remarks>
68-
public bool AllReferencesProduceReferenceAssemblies { get; internal set; } = true;
69+
public IReadOnlyList<string>? TargetsWithoutReferenceAssemblies => _targetsWithoutReferenceAssemblies;
70+
71+
private List<string>? _targetsWithoutReferenceAssemblies;
72+
73+
internal void AddTargetsWithoutReferenceAssemblies(IReadOnlyList<string> targetsWithoutReferenceAssemblies)
74+
{
75+
if (targetsWithoutReferenceAssemblies is { Count: > 0 })
76+
{
77+
_targetsWithoutReferenceAssemblies ??= new();
78+
_targetsWithoutReferenceAssemblies.AddRange(targetsWithoutReferenceAssemblies);
79+
}
80+
}
6981

7082
public BuildAccelerationResult AccelerationResult
7183
{
@@ -197,7 +209,7 @@ private sealed class ConfiguredFileSystemOperationAggregator
197209
private readonly FileSystemOperationAggregator _parent;
198210
private readonly bool? _isBuildAccelerationEnabled;
199211

200-
public ConfiguredFileSystemOperationAggregator(FileSystemOperationAggregator parent, bool? isBuildAccelerationEnabled, bool referencesProduceReferenceAssemblies)
212+
public ConfiguredFileSystemOperationAggregator(FileSystemOperationAggregator parent, bool? isBuildAccelerationEnabled, IReadOnlyList<string>? targetsWithoutReferenceAssemblies)
201213
{
202214
_parent = parent;
203215
_isBuildAccelerationEnabled = isBuildAccelerationEnabled;
@@ -213,9 +225,9 @@ public ConfiguredFileSystemOperationAggregator(FileSystemOperationAggregator par
213225
_parent.IsAccelerationEnabled = false;
214226
}
215227

216-
if (referencesProduceReferenceAssemblies is false)
228+
if (targetsWithoutReferenceAssemblies is not null)
217229
{
218-
_parent.AllReferencesProduceReferenceAssemblies = false;
230+
_parent.AddTargetsWithoutReferenceAssemblies(targetsWithoutReferenceAssemblies);
219231
}
220232
}
221233

src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/BuildUpToDateCheck.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ private async Task<bool> IsUpToDateInternalAsync(
10581058

10591059
bool? isBuildAccelerationEnabled = IsBuildAccelerationEnabled(copyInfo.IsComplete, implicitState);
10601060

1061-
var configuredFileSystemOperations = new ConfiguredFileSystemOperationAggregator(fileSystemOperations, isBuildAccelerationEnabled, copyInfo.AllReferencesProduceReferenceAssemblies);
1061+
var configuredFileSystemOperations = new ConfiguredFileSystemOperationAggregator(fileSystemOperations, isBuildAccelerationEnabled, copyInfo.TargetsWithoutReferenceAssemblies);
10621062

10631063
string outputFullPath = Path.Combine(implicitState.MSBuildProjectDirectory, implicitState.OutputRelativeOrFullPath);
10641064

@@ -1113,12 +1113,12 @@ private async Task<bool> IsUpToDateInternalAsync(
11131113
logger.Minimal(nameof(Resources.FUTD_AccelerationCandidate));
11141114
}
11151115

1116-
if (fileSystemOperations.IsAccelerationEnabled is true && fileSystemOperations.AllReferencesProduceReferenceAssemblies is false)
1116+
if (fileSystemOperations.IsAccelerationEnabled is true && fileSystemOperations.TargetsWithoutReferenceAssemblies is { Count: > 0 })
11171117
{
11181118
// This project is configured to use build acceleration, but some of its references do not
11191119
// produce reference assemblies. Log a message to let the user know that they may be able
11201120
// to improve their build performance by enabling the production of reference assemblies.
1121-
logger.Minimal(nameof(Resources.FUTD_NotAllReferencesProduceReferenceAssemblies));
1121+
logger.Minimal(nameof(Resources.FUTD_NotAllReferencesProduceReferenceAssemblies_1), string.Join(", ", fileSystemOperations.TargetsWithoutReferenceAssemblies.Select(s => $"'{s}'")));
11221122
}
11231123

11241124
logger.Verbose(nameof(Resources.FUTD_Completed), sw.Elapsed.TotalMilliseconds);

src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/CopyItemAggregator.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public CopyItemsResult TryGatherCopyItemsForProject(string targetPath, BuildUpTo
3838
// results is strictly an improvement over ignoring what results we do have.
3939
bool isComplete = true;
4040

41-
// Whether all referenced projects have ProduceReferenceAssembly set to true. The originating project
42-
// is not included in this check (targetPath).
43-
bool allReferencesProduceReferenceAssemblies = true;
41+
// Lazily populated list of referenced projects not having ProduceReferenceAssembly set to true.
42+
// The originating project is not included in this check (targetPath).
43+
List<string>? referencesNotProducingReferenceAssembly = null;
4444

4545
List<ProjectCopyData>? contributingProjects = null;
4646

@@ -67,7 +67,8 @@ public CopyItemsResult TryGatherCopyItemsForProject(string targetPath, BuildUpTo
6767
if (!data.ProduceReferenceAssembly && project != targetPath)
6868
{
6969
// One of the referenced projects does not produce a reference assembly.
70-
allReferencesProduceReferenceAssemblies = false;
70+
referencesNotProducingReferenceAssembly ??= new();
71+
referencesNotProducingReferenceAssembly.Add(data.TargetPath);
7172
}
7273

7374
foreach (string referencedProjectTargetPath in data.ReferencedProjectTargetPaths)
@@ -83,7 +84,7 @@ public CopyItemsResult TryGatherCopyItemsForProject(string targetPath, BuildUpTo
8384
}
8485
}
8586

86-
return new(GenerateCopyItems(), isComplete, allReferencesProduceReferenceAssemblies);
87+
return new(GenerateCopyItems(), isComplete, referencesNotProducingReferenceAssembly);
8788

8889
IEnumerable<(string Path, ImmutableArray<CopyItem> CopyItems)> GenerateCopyItems()
8990
{

src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/UpToDate/ICopyItemAggregator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ internal interface ICopyItemAggregator
3535
/// </summary>
3636
/// <param name="ItemsByProject">A sequence of items by project, that are reachable from the current project</param>
3737
/// <param name="IsComplete">Indicates whether we have items from all reachable projects.</param>
38-
/// <param name="AllReferencesProduceReferenceAssemblies">Indicates whether all referenced projects produce reference assemblies.</param>
38+
/// <param name="TargetsWithoutReferenceAssemblies">
39+
/// A list of target paths for projects that do not produce reference assemblies, or <see langword="null"/> if
40+
/// all reachable projects do in fact produce reference assemblies.
41+
/// </param>
3942
internal record struct CopyItemsResult(
4043
IEnumerable<(string Path, ImmutableArray<CopyItem> CopyItems)> ItemsByProject,
4144
bool IsComplete,
42-
bool AllReferencesProduceReferenceAssemblies);
45+
IReadOnlyList<string>? TargetsWithoutReferenceAssemblies);
4346

4447
/// <summary>
4548
/// Models the set of copy items a project produces, along with some details about the project.

src/Microsoft.VisualStudio.ProjectSystem.Managed/Resources.Designer.cs

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.VisualStudio.ProjectSystem.Managed/Resources.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@ This project was loaded using the wrong project type, likely as a result of rena
449449
<value>This project appears to be a candidate for build acceleration. To opt in, set the 'AccelerateBuildsInVisualStudio' MSBuild property to 'true'. See https://aka.ms/vs-build-acceleration.</value>
450450
<comment>Do not translate 'AccelerateBuildsInVisualStudio' or 'true'.</comment>
451451
</data>
452-
<data name="FUTD_NotAllReferencesProduceReferenceAssemblies" xml:space="preserve">
453-
<value>This project has enabled build acceleration, but at least one referenced project does not produce reference assemblies. Ensure all referenced projects, both direct and indirect, have the 'ProduceReferenceAssembly' MSBuild property set to 'true'. See https://aka.ms/vs-build-acceleration.</value>
452+
<data name="FUTD_NotAllReferencesProduceReferenceAssemblies_1" xml:space="preserve">
453+
<value>This project has enabled build acceleration, but not all referenced projects produce a reference assembly. Ensure projects producing the following outputs have the 'ProduceReferenceAssembly' MSBuild property set to 'true': {0}. See https://aka.ms/vs-build-acceleration for more information.</value>
454454
<comment>Do not translate 'ProduceReferenceAssembly' or 'true'.</comment>
455455
</data>
456456
<data name="FUTD_AccelerationDisabledCopyItemsIncomplete" xml:space="preserve">

src/Microsoft.VisualStudio.ProjectSystem.Managed/xlf/Resources.cs.xlf

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.VisualStudio.ProjectSystem.Managed/xlf/Resources.de.xlf

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.VisualStudio.ProjectSystem.Managed/xlf/Resources.es.xlf

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)