msbuild - можно ли обмениваться элементами, определенными в дочернем проекте, с его родителем без использования импорта? - PullRequest
0 голосов
/ 08 ноября 2018

Вопрос

Как получить элементы, определенные в дочернем проекте, его родителю без использования элемента <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>

Building 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 s, но цель ребенка также выполняется:

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 голосов
/ 08 ноября 2018

Если вы используете метод 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>

Это должно предотвратить вызов дочерних целей при импорте.

...