aspnetcore/eng/targets/ResolveReferences.targets

175 lines
10 KiB
XML

<!--
The targets in this file are used to implement custom <Reference> resolution.
For more details, see /docs/ReferenceResolution.md.
Properties which can be set by projects. If unset, these will be inferred.
* UseLatestPackageReferences = resolve `<Reference>` items to the latest version of PackageReferences in eng/Dependencies.props.
* UseProjectReferences = prefer project references to packages
* IsProjectReferenceProvider = when true, the assembly in this project should be available as a ProjectReferenceProvider (see below).
Items used by the resolution strategy:
* BaselinePackageReference = a list of packages that were reference in the last release of the project currently building
* LatestPackageReference = a list of the latest versions of packages
* Reference = a list of the references which are needed for compilation or runtime
* ProjectReferenceProvider = a list which maps of assembly names to the project file that produces it
-->
<Project>
<PropertyGroup>
<ResolveReferencesDependsOn>
ResolveCustomReferences;
$(ResolveReferencesDependsOn);
</ResolveReferencesDependsOn>
</PropertyGroup>
<PropertyGroup>
<!--
Projects should only use the latest package references when:
* preparing a new major or minor release (i.e. a non-servicing builds)
* when a project is a test or sample project
* when a package is releasing a new patch (we like to update external dependencies in patches when possible)
-->
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' != 'true' ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' AND '$(IsImplementationProject)' == 'true' AND ( '$(IsServicingBuild)' != 'true' OR '$(IsPackable)' == 'true' ) ">true</UseLatestPackageReferences>
<UseLatestPackageReferences Condition=" '$(UseLatestPackageReferences)' == '' ">false</UseLatestPackageReferences>
<!--
Projects should only use the project references instead of baseline package references when:
* preparing a new major or minor release (i.e. a non-servicing builds)
* when a project is a test or sample project
We don't use project references between components in servicing builds between compontents to preserve the baseline as much as possible.
-->
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsServicingBuild)' != 'true' ">true</UseProjectReferences>
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' AND '$(IsImplementationProject)' != 'true' ">true</UseProjectReferences>
<UseProjectReferences Condition=" '$(UseProjectReferences)' == '' ">false</UseProjectReferences>
</PropertyGroup>
<ItemGroup>
<!-- Packages which are implicitly defined by the .NET Core SDK. -->
<_ImplicitPackageReference Include="@(PackageReference->WithMetadataValue('IsImplicitlyDefined', 'true'))" />
<!-- Capture a list of references which were set explicitly in the project. -->
<_ExplicitPackageReference Include="@(PackageReference)" Exclude="@(_ImplicitPackageReference)" />
<!-- Special case: ignore the reference to Internal.AspNetCore.Sdk, which is defined in eng/targets/Cpp.Common.props. -->
<_ExplicitPackageReference Remove="Internal.AspNetCore.Sdk" />
<_ExplicitPackageReference Remove="Microsoft.NETFramework.ReferenceAssemblies" />
<_UnusedProjectReferenceProvider Include="@(ProjectReferenceProvider)" Exclude="@(Reference)" />
<!--
Turn Reference items into a ProjectReference when UseProjectReferences is true.
Order matters. This comes before package resolution because projects should be used when possible instead of packages.
-->
<_ProjectReferenceByAssemblyName Condition="'$(UseProjectReferences)' == 'true'"
Include="@(ProjectReferenceProvider)"
Exclude="@(_UnusedProjectReferenceProvider)" />
<ProjectReference Include="@(_ProjectReferenceByAssemblyName->'%(ProjectPath)')" />
<Reference Remove="@(_ProjectReferenceByAssemblyName)" />
<!-- Use _ReferenceTemp to workaround issues in Visual Studio which causes a conflict between Reference, packages, and projects. -->
<_ReferenceTemp Include="@(Reference)" />
<Reference Remove="@(Reference)" />
</ItemGroup>
<!--
This target resolves remaining Referene items to Packages, if possible. If not, they are left as Reference items fo the SDK to resolve.
This executes on NuGet restore and during DesignTimeBuild. It should not run in the outer, cross-targeting build.
-->
<Target Name="ResolveCustomReferences" BeforeTargets="CollectPackageReferences;ResolveAssemblyReferencesDesignTime;ResolveAssemblyReferences" Condition=" '$(TargetFramework)' != '' ">
<ItemGroup>
<Reference Include="@(_ReferenceTemp)" />
<_ReferenceTemp Remove="@(_ReferenceTemp)" />
<!-- Identify if any references were present in the last release of this package, but have been removed. -->
<UnusedBaselinePackageReference Include="@(BaselinePackageReference)" Exclude="@(Reference);@(_ProjectReferenceByAssemblyName);@(PackageReference)" />
<!--
MSBuild does not provide a way to join on matching identities in a Condition,
but you can do a cartesian product of two item groups and filter out mismatched id's in a second pass.
-->
<_LatestPackageReferenceWithVersion Include="@(Reference)" Condition=" '$(UseLatestPackageReferences)' == 'true' ">
<Id>%(LatestPackageReference.Identity)</Id>
<Version>%(LatestPackageReference.Version)</Version>
</_LatestPackageReferenceWithVersion>
<_LatestPackageReferenceWithVersion Remove="@(_LatestPackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " />
<!-- Remove reference items that have been resolved to a LatestPackageReference item. -->
<Reference Remove="@(_LatestPackageReferenceWithVersion)" />
<PackageReference Include="@(_LatestPackageReferenceWithVersion)" IsImplicitlyDefined="true" />
<!-- Resolve references from BaselinePackageReference for servicing builds. -->
<_BaselinePackageReferenceWithVersion Include="@(Reference)" Condition=" '$(IsServicingBuild)' == 'true' OR '$(UseLatestPackageReferences)' != 'true' ">
<Id>%(BaselinePackageReference.Identity)</Id>
<Version>%(BaselinePackageReference.Version)</Version>
</_BaselinePackageReferenceWithVersion>
<_BaselinePackageReferenceWithVersion Remove="@(_BaselinePackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " />
<!-- Remove reference items that have been resolved to a BaselinePackageReference item. -->
<PackageReference Include="@(_BaselinePackageReferenceWithVersion)" IsImplicitlyDefined="true" />
<Reference Remove="@(_BaselinePackageReferenceWithVersion)" />
<!-- For PrivateAssets=All references, like .Sources packages, fallback to LatestPackageReferences. -->
<_PrivatePackageReferenceWithVersion Include="@(Reference->WithMetadataValue('PrivateAssets', 'All'))">
<Id>%(LatestPackageReference.Identity)</Id>
<Version>%(LatestPackageReference.Version)</Version>
</_PrivatePackageReferenceWithVersion>
<_PrivatePackageReferenceWithVersion Remove="@(_PrivatePackageReferenceWithVersion)" Condition="'%(Id)' != '%(Identity)' " />
<!-- Remove reference items that have been resolved to a LatestPackageReference item. -->
<PackageReference Include="@(_PrivatePackageReferenceWithVersion)" IsImplicitlyDefined="true" />
<Reference Remove="@(_PrivatePackageReferenceWithVersion)" />
<!-- Free up memory for unnecessary items -->
<_LatestPackageReferenceWithVersion Remove="@(_LatestPackageReferenceWithVersion)" />
<_BaselinePackageReferenceWithVersion Remove="@(_BaselinePackageReferenceWithVersion)" />
<_PrivatePackageReferenceWithVersion Remove="@(_PrivatePackageReferenceWithVersion)" />
<_ImplicitPackageReference Remove="@(_ImplicitPackageReference)" />
</ItemGroup>
<!-- TODO: when we finish https://github.com/aspnet/AspNetCore/issues/4246, introduce errors to force projects to use custom resolution.
<Error Condition="@(_ExplicitPackageReference->Count()) != 0"
Text="PackageReference items are not allowed. Use &lt;Reference&gt; instead. " /> -->
<ItemGroup>
<_ExplicitPackageReference Remove="@(_ExplicitPackageReference)" />
</ItemGroup>
<Warning Condition="@(UnusedBaselinePackageReference->Count()) != 0"
Text="Package references changed since the last release. This could be a breaking change. References removed:%0A - @(UnusedBaselinePackageReference, '%0A -')" />
<Error Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework' AND '%(Reference.Identity)' != '' AND ! Exists('%(Reference.Identity)')"
Code="MSB3245"
Text="Could not resolve this reference. Could not locate the package or project for &quot;%(Reference.Identity)&quot;" />
</Target>
<!-- These targets are used to generate the map of assembly name to project files. See also the /t:GenerateProjectList target in build/repo.targets. -->
<Target Name="GetReferencesProvided" Returns="@(ProvidesReference)">
<ItemGroup>
<_TargetFramework Remove="@(_TargetFramework)" />
<_TargetFramework Include="$(TargetFramework)" Condition="'$(TargetFramework)' != '' "/>
<_TargetFramework Include="$(TargetFrameworks)" Condition="'$(TargetFramework)' == '' "/>
</ItemGroup>
<MSBuild Projects="$(MSBuildProjectFullPath)"
Targets="_GetReferencesProvided"
Properties="TargetFramework=%(_TargetFramework.Identity)">
<Output TaskParameter="TargetOutputs" ItemName="ProvidesReference" />
</MSBuild>
</Target>
<Target Name="_GetReferencesProvided" Returns="@(ProvidesReference)">
<ItemGroup Condition=" '$(IsProjectReferenceProvider)' == 'true' ">
<ProvidesReference Include="$(AssemblyName)">
<ProjectFileRelativePath>$([MSBuild]::MakeRelative($(RepositoryRoot), $(MSBuildProjectFullPath)))</ProjectFileRelativePath>
</ProvidesReference>
</ItemGroup>
</Target>
</Project>