Reputation: 9534
How do I get items defined in a child project to its parent without using the <Import>
element?
The reason I want to avoid <Import>
is because it also imports targets which execute at the parent project, which is not desired.
Say I have the following child.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<MyItem Include="some.file" />
</ItemGroup>
<Target Name="MyChildPreBuild" BeforeTargets="Build">
<Message Text="MyChildPreBuild" Importance="high" />
<Message Text="%(MyItem.FullPath)" Importance="high" />
</Target>
</Project>
And this is referenced by a parent.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<MyItem Include="some.other.file" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\child\child.csproj" />
</ItemGroup>
<Target Name="MyPreBuild" BeforeTargets="Build">
<Message Text="MyPreBuild" Importance="high" />
<Message Text="%(MyItem.FullPath)" Importance="high" />
</Target>
</Project>
Building parent.csproj
, I get the following build output message:
1>------ Rebuild All started: Project: child, Configuration: Debug Any CPU ------
1>child -> C:\Users\dan\test\child\bin\Debug\netstandard2.0\child.dll
2>------ Rebuild All started: Project: parent, Configuration: Debug Any CPU ------
2>parent -> C:\Users\dan\test\parent\bin\Debug\netstandard2.0\parent.dll
2>C:\Users\dan\test\parent\some.other.file
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========
As can be seen, only the parent.csproj
MyItem
items are printed.
Adding <Import Project="..\child\child.csproj" />
to parent.csproj
does print all of the MyItem
s but the child's target is executed as well:
1>------ Rebuild All started: Project: child, Configuration: Debug Any CPU ------
1>child -> C:\Users\dan\test\child\bin\Debug\netstandard2.0\child.dll
1>MyChildPreBuild
1>C:\Users\dan\test\child\some.file
2>------ Rebuild All started: Project: parent, Configuration: Debug Any CPU ------
2>C:\Users\dan\test\child\child.csproj : warning MSB4011: "C:\Program Files\dotnet\sdk\2.1.403\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props" cannot be imported again. It was already imported at "C:\Users\dan\test\parent\parent.csproj". This is most likely a build authoring error. This subsequent import will be ignored.
2>C:\Users\dan\test\parent\parent.csproj : warning MSB4011: "C:\Program Files\dotnet\sdk\2.1.403\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.targets" cannot be imported again. It was already imported at "C:\Users\dan\test\child\child.csproj". This is most likely a build authoring error. This subsequent import will be ignored.
2>parent -> C:\Users\dan\test\parent\bin\Debug\netstandard2.0\parent.dll
2>MyChildPreBuild
2>C:\Users\dan\test\parent\some.other.file
2>C:\Users\dan\test\parent\some.file
2>MyPreBuild
2>C:\Users\dan\test\parent\some.other.file
2>C:\Users\dan\test\parent\some.file
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========
Upvotes: 0
Views: 521
Reputation: 8672
If you use the import
method you can add a condition to the child targets to only execute when that flag is not set. Then, in your parent, set the flag to a value.
Child
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<MyItem Include="some.file" />
</ItemGroup>
<Target Name="MyChildPreBuild" BeforeTargets="Build" Condition="'$(ParentProject}'==''">
<Message Text="MyChildPreBuild" Importance="high" />
<Message Text="%(MyItem.FullPath)" Importance="high" />
</Target>
</Project>
And then, in your parent project
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ParentProject>parent.csproj</ParentProject>
</PropertyGroup>
<ItemGroup>
<MyItem Include="some.other.file" />
</ItemGroup>
<Import Project="..\child\child.csproj" />
<Target Name="MyPreBuild" BeforeTargets="Build">
<Message Text="MyPreBuild" Importance="high" />
<Message Text="%(MyItem.FullPath)" Importance="high" />
</Target>
</Project>
This should prevent the child targets from being called when imported.
Upvotes: 1