【问题标题】:MSBuild batch task outputMSBuild 批处理任务输出
【发布时间】:2014-07-02 04:33:08
【问题描述】:

我有几个项目的解决方案(插件)。对于每个解决方案,都有定义的元数据范围:

<ItemGroup>
    <Plugins Include="Plugin1\Plugin1.sln">
        <Disabled>false</Disabled>
        <ProjectDirectory>plugin1\</ProjectDirectory>
        <ProjectName>Plugin1</ProjectName>
    </Plugins>
    <Plugins Include="Plugin2\Plugin2.sln">
        <Disabled>true</Disabled>
        <ProjectDirectory>plugin2\</ProjectDirectory>
        <ProjectName>Plugin2</ProjectName>
    </Plugins>
    <Plugins Include="Plugin3\Plugin3.sln">
        <Disabled>false</Disabled>
        <ProjectDirectory>plugin3\</ProjectDirectory>
        <ProjectName>Plugin3</ProjectName>
    </Plugins>
</ItemGroup>

我需要通过运行自己的构建脚本来构建非Disabled插件,并将结果目录添加到插件元数据中以进行后续处理(例如:将每个插件构建输出复制到自己的文件夹中)。

但我找不到连接它的方法。

以下是我的目标:

<Target Name="BuildPlugin" Inputs="%(Plugins.Identity)" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
    <MSBuild
        Condition="!%(Disabled)"
        Projects='%(ProjectDirectory)BuildProject.target'
        Targets="Clean;Build;" >

            <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
    </MSBuild>

    <ItemGroup>
        <Plugins Condition="%(ProjectName)=%(Plugins.ProjectName)">
            <PluginOutput>%(PluginOutput.Identity)</PluginOutput>
        </Plugins>
    </ItemGroup>

    <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)"  Condition="%(Plugins.Disabled)" />
</Target>

BuildProject.target 返回输出目录(例如:Plugin1\Plugin1\bin\Release\

在这种情况下,构建失败并出现下一个错误:

错误 MSB4096:项目列表“PluginOutput”未定义 元数据“项目名称”。为了使用这个元数据,要么限定 它通过指定 %(PluginOutput.ProjectName),或确保所有项目 在此列表中定义此元数据的值。

错误 MSB4113:指定条件“%(Plugins.Disabled)”计算结果为 "" 而不是布尔值。

但如果删除ItemGroupMessage 任务的条件

<Target Name="BuildPlugin" Inputs="%(Plugins.Identity)" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
    <MSBuild
        Condition="!%(Disabled)"
        Projects='%(ProjectDirectory)BuildProject.target'
        Targets="Clean;Build;" >

            <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
    </MSBuild>

    <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)"  />
</Target>

似乎 msbuild 正确地批处理插件。 BuildPluginMessage 任务产生的目标输出是:

 BuildPlugin:
   Plugin1
     Plugin1\Plugin1\bin\Release\
 BuildPlugin:
   Plugin2
 BuildPlugin:
   Plugin3
     Plugin3\Plugin3\bin\Release

但在这种情况下,我无法过滤禁用的插件并将插件输出文件夹添加到元数据。

有什么想法吗?

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    以下应该可以工作

    <Target Name="BuildPlugin" Outputs="%(Plugins.Identity -> %(PluginOutput.Identity))" Returns="%(PluginOutput.Identity)">
        <MSBuild 
            Condition="!%(Plugins.Disabled)"
            Projects='%(Plugins.ProjectDirectory)BuildProject.target'
            Targets="Clean;Build;" >
                <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
        </MSBuild>
    
    
        <Message Text="%(Plugins.ProjectName) %(PluginOutput.Identity)" Condition="!%(Plugins.Disabled)"/>
    </Target>
    

    【讨论】:

    • %(Plugins.Disabled)Message 任务条件中计算为空字符串,但适用于 MSBuild 任务。似乎在 Message 任务中 msbuild 尝试仅在 PluginOutput 中查找元数据
    • 嗯,不这么认为。如果删除条件,您是否正确获得 %(Plugins.ProjectName) 的值?
    • 我不完全明白为什么 - 但是是的,没有限制 Message 任务会产生正确的输出,唯一的问题是包括来自 Plugins ItemGroup 的所有项目
    • 很抱歉提出这个建议,但我也经常这样做。您是否检查了条件中 Disabled 的拼写?如果它出来是空的,可能就是这个问题
    • 已经检查了好几次,但感谢您的建议。打印错误是最危险的问题(:
    【解决方案2】:

    由于缺少 BuildProject.target,我无法测试所有步骤,但这应该可以:

    <Target  Name="BuildPlugin"
         Inputs="%(Plugins.Identity)"
         Outputs="%(Plugins.Identity)\dummy.txt"
         Returns="%(PluginOutput.Identity)">
    
     <PropertyGroup> <!-- transform Metadata to Properties -->
       <ProjectName>%(Plugins.ProjectName)</ProjectName>
       <PluginDisabled>%(Plugins.Disabled)</PluginDisabled>
     </PropertyGroup>
    
     <MSBuild
         Condition="'$(PluginDisabled)' != 'true'"
         Projects='%(Plugins.ProjectDirectory)BuildProject.target'
         Targets="Clean;Build;" >
       <Output ItemName="PluginOutput" TaskParameter="TargetOutputs"/>
     </MSBuild>
    
     <ItemGroup>
        <!-- batching 2 ItemGroups in one task is usually not working or creates side effects-->
       <Plugins Condition="'%(PluginOutput.ProjectName)' == '$(ProjectName)'">
         <PluginOutput>%(PluginOutput.Identity)</PluginOutput>
       </Plugins>
     </ItemGroup>
    
       <!-- batching 2 ItemGroups in one task is usually not working or creates side effects-->
     <Message Text="$(ProjectName) %(PluginOutput.Identity)"  Condition="$(PluginDisabled)" />
    </Target>
    

    【讨论】:

    • 我在问题中添加了对 BuildProject.target 输出的解释:它返回插件输出目录
    • 所以在这种情况下绑定Condition="'%(PluginOutput.ProjectName)' == '$(ProjectName)'" 将不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多