The docs say:
NuGet packages may sometimes add custom build targets or properties to projects that consume that package. This can be achieved by adding a valid MSBuild file, in the form
<package_id>.targets
or<package_id>.props
within the build folders of the project.
While developing a library that provides custom build targets, I'd like to reference it via ProjectReference
so I don't have to repackage it to test the consumer after every change.
My test library is called Magic
. It contains a target file named Magic.targets
in the project root.
<Project>
<Target Name="CustomTarget" DependsOnTargets="Build">
<Message Importance="high" Text="fnord"/>
</Target>
</Project>
This file is not automatically copied to bin/Debug/netstandard2.0
. If I set its properties to copy, it appears under bin
but not in the corresponding location under obj
. It is not referenced in obj/Magic.csproj.nuget.g.targets
. No message is printed when I build the consuming project. I also tried <Warning Text="fnord"/>
with no effect.
I'm developing in Rider in case that makes a difference.
No, a project can't receive custom targets via a ProjectReference
.
An MSBuild project can reference another project with ProjectReference
and reference a NuGet package with PackageReference
. But they are different mechanisms.
ProjectReference
is much older than PackageReference
. NuGet's initial release was 7 years after MSBuild's. ProjectReference
doesn't know about NuGet, doesn't know about <package_id>
, and doesn't import MSBuild files from the referenced project.
MSBuild processes a project in two phases: evaluation followed by execution. Import
s are handled in the evaluation phase. ProjectReference
s are processed and resolved in the execution phase when the build
target is invoked. PackageReference
s are processed in the execution phase when the restore
target is invoked.
Files that only become available in the execution phase can't be Import
ed. It's too late. This is part of why msbuild -t:restore,build
can produce "incorrect behavior" and msbuild -t:build -restore
is recommended. The -restore
option essentially runs the restore
target, then forces a reload of the project (with a new evaluation) before running the targets in the -t
option.