msbuild-是否可以在不使用导入的情况下将子项目中定义的项目共享给其父项目?

时间:2018-11-07 23:32:25

标签: asp.net-core msbuild .net-core csproj

问题

如何在不使用<Import>元素的情况下将子项目中定义的项目获取到其父项目? 我要避免使用<Import>的原因是因为它还会导入在父项目上执行的目标,这是不希望的。

示例

说我有以下 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>

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>

构建parent.csproj,我得到以下构建输出消息:

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 ==========

可以看出,仅打印parent.csproj MyItem个项目。

<Import Project="..\child\child.csproj" />添加到parent.csproj会打印所有MyItem,但是也会执行子目标:

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 ==========

1 个答案:

答案 0 :(得分:1)

如果使用import方法,则可以向子目标添加条件,仅在未设置该标志时才执行。然后,在您的父母中,将标志设置为一个值。

孩子

<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>

然后,在您的父项目中

<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>

这应该防止子目标在导入时被调用。