Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit ab36985

Browse files
kzuadalon
authored andcommitted
Refactor and simplify targets for better maintainability
The new Legacy.targets file contains old property names > new property names so we can freely improve the main targets while still keeping existing projects working. For now, we have PrimaryOutputPackageFileKind > PrimaryOutputKind. This renaming was made because the PrimaryOutputKind affects more than just the primary output file, so the existing property was confusing. We also added a new Inference.targets file that is the one that now centralizes the None/Content/Reference/packages.config/project.json inference. The entire inference mechanism can be disabled with a single new property, InferPackageContents=false. This allows authors who want full control over the contents by simply manipulating PackageFile items to disable all the inferred content. This fixes NuGet/Home#5167. The existing behavior that generates the reference/intersection assembly was also moved into its own standalone ReferenceAssembly.targets for easier maintainability. Finally, a new IncludeProjectReferencesInPackage has been added to allow projects to opt out of main output inclusion (IncludeOutputInPackage=false, or InferPackageContents=false) but still allow the GetPackageContents to traverse project references. This fixes issue NuGet/Home#4188.
1 parent 99bdb59 commit ab36985

13 files changed

Lines changed: 432 additions & 299 deletions

src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.props

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,32 @@ Copyright (c) .NET Foundation. All rights reserved.
2525

2626
<PrimaryOutputFrameworkSpecific>false</PrimaryOutputFrameworkSpecific>
2727
</PropertyGroup>
28+
29+
<!--
30+
Properties relevant to Visual Studio:
31+
$(BuildingInsideVisualStudio) This will indicate whether this project is building inside the IDE. When
32+
building via MSBuild, this property will not be set.
33+
$(DesignTimeBuild) Visual Studio uses this property to indicate whether it's performing a
34+
design time build or a full build. A design time build is designed to do
35+
minimal amount of work; the intent of those builds is to expose information
36+
around resolved dependencies and properties back to Visual Studio without
37+
actually producing assets on disk.
38+
-->
39+
<PropertyGroup>
40+
<!-- We don't want to build in case we're performing a design time build as we are expected to not
41+
produce any assets.
42+
We also don't want to build the references in cases where we build inside the IDE. The reason
43+
is that Visual Studio already built our dependencies. Doing it again can regress performance.
44+
However, the real issue is that it impacts correctness as this can result in building the same
45+
project simultaneously from different projects.
46+
Most particularly on the correctness side, this shows up when VS is doing a "rebuild". NuProj
47+
will end up causing multiple build breaks being reported because it will re-delete outputs that
48+
VS just produced and that other project references that are building in parallel now expect to
49+
be there. -->
50+
<BuildProjectReferences Condition="'$(BuildProjectReferences)' == '' and ('$(BuildingInsideVisualStudio)' == 'true' or '$(DesignTimeBuild)' == 'true')">false</BuildProjectReferences>
51+
<!-- By default we will build (and if applicable, clean) all project references. But this can be used
52+
to disable that. -->
53+
<BuildProjectReferences Condition="'$(BuildProjectReferences)' == ''">true</BuildProjectReferences>
54+
</PropertyGroup>
55+
2856
</Project>

src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Compatibility.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Copyright (c) .NET Foundation. All rights reserved.
1313

1414
<PropertyGroup>
1515
<PackOnBuild Condition="'$(GeneratePackageOnBuild)' == 'true'">true</PackOnBuild>
16-
<PrimaryOutputPackageFileKind Condition="'$(IsTool)' == 'true'">tool</PrimaryOutputPackageFileKind>
16+
<PrimaryOutputKind Condition="'$(IsTool)' == 'true'">tool</PrimaryOutputKind>
1717
</PropertyGroup>
1818

1919
</Project>
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<!--
2+
***********************************************************************************************
3+
Microsoft.NuGet.Build.Packaging.Inference.targets
4+
5+
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6+
created a backup copy. Incorrect changes to this file will make it
7+
impossible to load or build your projects from the command-line or the IDE.
8+
9+
Copyright (c) .NET Foundation. All rights reserved.
10+
***********************************************************************************************
11+
-->
12+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
13+
<UsingTask TaskName="NuGet.Build.Packaging.Tasks.ReadLegacyJsonDependencies" AssemblyFile="NuGet.Build.Packaging.Tasks.dll" />
14+
<UsingTask TaskName="NuGet.Build.Packaging.Tasks.ReadLegacyConfigDependencies" AssemblyFile="NuGet.Build.Packaging.Tasks.dll" />
15+
16+
<PropertyGroup>
17+
<!-- Infer PackageReference elements from packages.config/project.json files in the project -->
18+
<InferLegacyPackageReferences Condition="'$(InferLegacyPackageReferences)' == ''">true</InferLegacyPackageReferences>
19+
20+
<!-- The Kind of primary output (build, symbols and doc) set if IncludeOutputsInPackage = true -->
21+
<PrimaryOutputKind Condition="'$(PrimaryOutputKind)' == ''">Lib</PrimaryOutputKind>
22+
<!-- Optionally can tweak whether the primary output is TF-specific or not. -->
23+
<PrimaryOutputFrameworkSpecific Condition="'$(PrimaryOutputKind)' == ''">true</PrimaryOutputFrameworkSpecific>
24+
25+
<!-- Whether to include @(Content) items with CopyToOutputDirectory != '' in the package -->
26+
<IncludeContentInPackage Condition="'$(IncludeContentInPackage)' == ''">true</IncludeContentInPackage>
27+
<!-- Whether to include @(None) items with CopyToOutputDirectory != '' in the package -->
28+
<IncludeNoneInPackage Condition="'$(IncludeNoneInPackage)' == ''">true</IncludeNoneInPackage>
29+
<!-- Whether to include @(BuiltProjectOutputGroupOutput), @(DocumentationProjectOutputGroupOutput) and @(SatelliteDllsProjectOutputGroupOutput) items in the package -->
30+
<IncludeOutputsInPackage Condition="'$(IncludeOutputsInPackage)' == ''">true</IncludeOutputsInPackage>
31+
<!-- Whether to include @(DebugSymbolsProjectOutputGroupOutput) items in the package -->
32+
<IncludeSymbolsInPackage Condition="'$(IncludeSymbolsInPackage)' == '' and '$(IncludeOutputsInPackage)' == 'true' and '$(Configuration)' == 'Debug'">true</IncludeSymbolsInPackage>
33+
<!-- Whether to include framework references (%(ReferencePath.ResolvedFrom)' == '{TargetFrameworkDirectory}') in the package -->
34+
35+
<!-- Only default to true if the project isn't a nuget packaging project itself and its primary output is lib. -->
36+
<IncludeFrameworkReferencesInPackage Condition="'$(IncludeFrameworkReferencesInPackage)' == '' and '$(IsPackagingProject)' != 'true' and '$(PrimaryOutputKind)' == 'Lib'">true</IncludeFrameworkReferencesInPackage>
37+
</PropertyGroup>
38+
39+
<PropertyGroup>
40+
<GetPackageContentsDependsOn>
41+
$(GetPackageContentsDependsOn);
42+
InferPackageContents
43+
</GetPackageContentsDependsOn>
44+
</PropertyGroup>
45+
46+
<Target Name="InferPackageContents" DependsOnTargets="$(InferPackageContentsDependsOn)" Returns="@(PackageFile)">
47+
<!-- Determine whether primary output is framework specific -->
48+
<ItemGroup Condition="'$(PrimaryOutputFrameworkSpecific)' == ''">
49+
<_PrimaryOutputKind Include="@(PackageItemKind->'%(FrameworkSpecific)')" Condition="'%(Identity)' == '$(PrimaryOutputKind)'" />
50+
</ItemGroup>
51+
<PropertyGroup Condition="'$(PrimaryOutputFrameworkSpecific)' == ''">
52+
<PrimaryOutputFrameworkSpecific>@(_PrimaryOutputKind)</PrimaryOutputFrameworkSpecific>
53+
</PropertyGroup>
54+
55+
<ItemGroup>
56+
<_InferredPackageFile Include="@(BuiltProjectOutputGroupOutput -> '%(FinalOutputPath)')"
57+
Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'">
58+
<!-- Packaging projects don't contribute primary output -->
59+
<Kind>$(PrimaryOutputKind)</Kind>
60+
<FrameworkSpecific>$(PrimaryOutputFrameworkSpecific)</FrameworkSpecific>
61+
</_InferredPackageFile>
62+
63+
<!-- Remove when https://github.com/Microsoft/msbuild/pull/1076 ships -->
64+
<_DocumentationProjectOutputGroupOutput Include="@(DocumentationProjectOutputGroupOutput)"
65+
Condition="'$(IncludeOutputsInPackage)' == 'true'">
66+
<FinalOutputPath Condition="$([System.IO.Path]::IsPathRooted('%(FinalOutputPath)')) == 'false'">$(MSBuildProjectDirectory)\%(FinalOutputPath)</FinalOutputPath>
67+
</_DocumentationProjectOutputGroupOutput>
68+
<_InferredPackageFile Include="@(_DocumentationProjectOutputGroupOutput -> '%(FinalOutputPath)')"
69+
Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'">
70+
<!-- Packaging projects don't contribute primary docs -->
71+
<Kind>$(PrimaryOutputKind)</Kind>
72+
<FrameworkSpecific>$(PrimaryOutputFrameworkSpecific)</FrameworkSpecific>
73+
</_InferredPackageFile>
74+
75+
<_InferredPackageFile Include="@(DebugSymbolsProjectOutputGroupOutput -> '%(FinalOutputPath)')"
76+
Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IncludeSymbolsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'">
77+
<!-- Packaging projects don't contribute primary symbols -->
78+
<Kind>$(PrimaryOutputKind)</Kind>
79+
<FrameworkSpecific>$(PrimaryOutputFrameworkSpecific)</FrameworkSpecific>
80+
</_InferredPackageFile>
81+
82+
<!-- Change to %(FinalOutputPath) when https://github.com/Microsoft/msbuild/pull/1115 ships -->
83+
<_InferredPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput -> '%(FullPath)')"
84+
Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'">
85+
<!-- Packaging projects don't contribute satellite dlls -->
86+
<Kind>$(PrimaryOutputKind)</Kind>
87+
<FrameworkSpecific>$(PrimaryOutputFrameworkSpecific)</FrameworkSpecific>
88+
</_InferredPackageFile>
89+
90+
<!-- NOTE: Content is opt-out (must have IncludeInPackage=false to exclude if IncludeContentInPackage=true) -->
91+
<!-- @ContentFilesProjectOutputGroupOutput = @(ContentWithTargetPath -> '%(FullPath)') -->
92+
<_InferredPackageFile Include="@(ContentWithTargetPath->'%(FullPath)')"
93+
Condition="
94+
'%(ContentWithTargetPath.IncludeInPackage)' == 'true' or
95+
'%(ContentWithTargetPath.Kind)' != '' or
96+
('$(IncludeContentInPackage)' == 'true' and '%(ContentWithTargetPath.IncludeInPackage)' != 'false')">
97+
<Kind Condition="'%(ContentWithTargetPath.Kind)' == '' and '%(ContentWithTargetPath.CopyToOutputDirectory)' != ''">$(PrimaryOutputKind)</Kind>
98+
<Kind Condition="'%(ContentWithTargetPath.Kind)' == '' and '%(ContentWithTargetPath.CopyToOutputDirectory)' == ''">Content</Kind>
99+
</_InferredPackageFile>
100+
101+
<!-- NOTE: None is also opt-out (must have IncludeInPackage=false to exclude if IncludeNoneInPackage=true, but only for those with CopyToOutput) -->
102+
<_InferredPackageFile Include="@(_NoneWithTargetPath->'%(FullPath)')"
103+
Condition="
104+
'%(_NoneWithTargetPath.IncludeInPackage)' == 'true' or
105+
'%(_NoneWithTargetPath.Kind)' != '' or
106+
('$(IncludeNoneInPackage)' == 'true' and '%(_NoneWithTargetPath.CopyToOutputDirectory)' != '' and '%(_NoneWithTargetPath.IncludeInPackage)' != 'false')">
107+
<Kind Condition="'%(_NoneWithTargetPath.Kind)' == '' and '%(_NoneWithTargetPath.CopyToOutputDirectory)' != ''">$(PrimaryOutputKind)</Kind>
108+
</_InferredPackageFile>
109+
110+
<_InferredPackageFile Include="@(PackageReference)" Condition="'%(Identity)' != 'NuGet.Build.Packaging'">
111+
<Kind>Dependency</Kind>
112+
</_InferredPackageFile>
113+
114+
<!-- We can't use %(FrameworkFile)==true because it's not defined for raw file references and
115+
it also includes mscorlib which we don't need
116+
TBD: maybe include ResolvedFrom=ImplicitlyExpandDesignTimeFacades too? -->
117+
<_InferredPackageFile Include="@(ReferencePath->'%(OriginalItemSpec)')"
118+
Condition="'$(IncludeFrameworkReferencesInPackage)' == 'true' and '%(ReferencePath.ResolvedFrom)' == '{TargetFrameworkDirectory}'">
119+
<Kind>FrameworkReference</Kind>
120+
</_InferredPackageFile>
121+
</ItemGroup>
122+
123+
<ItemGroup>
124+
<!--
125+
PackageId metadata on all PackageFile items means we can tell appart which ones came from which dependencies
126+
NOTE: if PackageId is empty, we won't generate a manifest and it means the files need to be packed with the
127+
current project.
128+
-->
129+
<PackageFile Include="@(_InferredPackageFile)">
130+
<Source>Implicit</Source>
131+
<PackageId Condition="'$(IsPackable)' == 'true'">$(PackageId)</PackageId>
132+
<Platform>$(Platform)</Platform>
133+
<TargetFrameworkMoniker Condition="'$(IsPackagingProject)' != 'true'">$(TargetFrameworkMoniker)</TargetFrameworkMoniker>
134+
</PackageFile>
135+
</ItemGroup>
136+
</Target>
137+
138+
<Target Name="_SetInferPackageContentsDependsOn" AfterTargets="_SetPropertiesFromCapabilities">
139+
<PropertyGroup>
140+
<!-- NOTE: this avoids taking dependencies on targets that are only available when the project supports the concept of references -->
141+
<_SupportsReferences Condition="
142+
$(_AllProjectCapabilities.Contains('AssemblyReferences')) or
143+
$(_AllProjectCapabilities.Contains('COMReferences')) or
144+
$(_AllProjectCapabilities.Contains('ProjectReferences')) or
145+
$(_AllProjectCapabilities.Contains('WinRTReferences')) or
146+
$(_AllProjectCapabilities.Contains('SDKReferences'))">true</_SupportsReferences>
147+
148+
<!-- Only depend on ResolveReferences if we need to include framework references -->
149+
<InferPackageContentsDependsOn Condition="'$(IncludeFrameworkReferencesInPackage)' == 'true' and '$(_SupportsReferences)' == 'true'">
150+
ResolveReferences
151+
</InferPackageContentsDependsOn>
152+
<InferPackageContentsDependsOn>
153+
$(InferPackageContentsDependsOn);
154+
GetPackageTargetPath
155+
</InferPackageContentsDependsOn>
156+
<InferPackageContentsDependsOn Condition="$(_AllProjectCapabilities.Contains('AllTargetOutputGroups'))">
157+
$(InferPackageContentsDependsOn);
158+
AllProjectOutputGroups
159+
</InferPackageContentsDependsOn>
160+
</PropertyGroup>
161+
</Target>
162+
163+
<Target Name="ReadLegacyDependencies" BeforeTargets="InferPackageContents" Condition="'$(InferLegacyPackageReferences)' == 'true'">
164+
<PropertyGroup>
165+
<_ProjectJson>$(MSBuildProjectDirectory)\project.json</_ProjectJson>
166+
<_PackagesConfig>$(MSBuildProjectDirectory)\packages.config</_PackagesConfig>
167+
</PropertyGroup>
168+
169+
<ReadLegacyJsonDependencies ProjectJsonPath="$(_ProjectJson)" Condition="Exists('$(_ProjectJson)')">
170+
<Output TaskParameter="PackageReferences" ItemName="PackageReference" />
171+
</ReadLegacyJsonDependencies>
172+
173+
<ReadLegacyConfigDependencies PackagesConfigPath="$(_PackagesConfig)" Condition="Exists('$(_PackagesConfig)')">
174+
<Output TaskParameter="PackageReferences" ItemName="PackageReference" />
175+
</ReadLegacyConfigDependencies>
176+
</Target>
177+
178+
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!--
2+
***********************************************************************************************
3+
Microsoft.NuGet.Build.Packaging.Legacy.targets
4+
5+
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6+
created a backup copy. Incorrect changes to this file will make it
7+
impossible to load or build your projects from the command-line or the IDE.
8+
9+
Copyright (c) .NET Foundation. All rights reserved.
10+
***********************************************************************************************
11+
-->
12+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
13+
<!-- This targets is used to adjust renamed properties, items and metadata -->
14+
15+
<PropertyGroup>
16+
<PrimaryOutputKind Condition="'$(PrimaryOutputKind)' == ''">$(PrimaryOutputPackageFileKind)</PrimaryOutputKind>
17+
18+
<!-- Previously, $(IncludeOutputsInPackage) == false disabled inclusion of project references -->
19+
<IncludeProjectReferencesInPackage Condition="'$(IncludeProjectReferencesInPackage)' == ''">$(IncludeOutputsInPackage)</IncludeProjectReferencesInPackage>
20+
</PropertyGroup>
21+
22+
</Project>

0 commit comments

Comments
 (0)