【问题标题】:MSBuild: Output properties from imported projectsMSBuild:导入项目的输出属性
【发布时间】:2015-02-27 21:14:55
【问题描述】:

假设我有一个这样的build.proj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
         DefaultTargets="AfterBuild"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <CustomAfterMicrosoftCSharpTargets>$(MSBuildThisFileDirectory)Common.Build.targets</CustomAfterMicrosoftCSharpTargets>
        <Configuration>Release</Configuration>
        <Platform>Any CPU</Platform>
        <ProjectProperties>
            Configuration=$(Configuration);
            Platform=$(Platform);
            CustomAfterMicrosoftCSharpTargets=$(CustomAfterMicrosoftCSharpTargets);
        </ProjectProperties>
    </PropertyGroup>

    <ItemGroup>
        <ProjectToBuild Include="$(MSBuildThisFileDirectory)src\Proj\MyApp.csproj" />
    </ItemGroup>

    <Target Name="Build">
        <MSBuild Targets="Build"
                 Projects="@(ProjectToBuild)"
                 Properties="$(ProjectProperties)" />
    </Target>

    <Target Name="AfterBuild" DependsOn="Build">
        <Message Text="ChildProperty: $(ChildProperty)" />
    </Target>
</Project>

Common.Build.targets 中,我有一个Target,它创建了一个属性:

<Target Name="DoSomethingUseful">
    <!-- Do something useful -->
    <CreateProperty Value="SomeComputedThingy">
        <Output TaskParameter="Value" PropertyName="ChildProperty"/>
    </CreateProperty>
</Target>

现在,如果我构建 build.proj,我在消息中看不到 ChildProperty 的值。输出为空白:ChildProperty:

我的印象是,目标的任何输出在执行后都会合并回全局上下文。但它似乎只适用于目标文件的任何内容。

如何让ChildProperty 冒泡到父级build.proj

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    当您在依赖项目上调用&lt;MSBuild&gt; 任务时,请阅读任务的TargetOutputs 输出参数。请参阅MSDN 中的示例:

    <Target Name="BuildOtherProjects">
        <MSBuild
            Projects="@(ProjectReferences)"
            Targets="Build">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="AssembliesBuiltByChildProjects" />
        </MSBuild>
    </Target>
    

    您还需要确保您在相关项目中调用的目标正确填充了ReturnsOutput 参数(如果使用Returns,则优先)。例如:

    <Target Name="MyTarget" Inputs="..." Outputs="..." Returns="$(MyOutputValue)">
        <PropertyGroup>
            <MyOutputValue>set it here</MyOutputValue>
        </PropertyGroup>
    </Target>
    

    【讨论】:

    • 试过了,还是不行。 AssembliesBuiltByChildProjects 为空。这解释了原因:Only the outputs from the targets that were specified are returned, not any outputs that may exist on targets that those targets depend on.
    • @Mrchief,你为什么会期望它不是这样?当您在 C# 中调用返回某个对象的函数时,您不会看到返回是该函数调用的所有内容的某种聚合。当然,调用函数并不能直接类比在 MSBuild 中调用目标,但有点接近。当您需要特定目标的输出时,使用 MSBuild 任务或 CallTarget 任务调用它并使用输出值。
    • 我没想到会这样。我的问题特别是关于冒泡由其中一个子目标创建的属性。我可以在全局范围内创建一个属性,问题是 - 如何?一个子函数总是可以写一个全局变量,是吗?让我们不要进入全局变量是邪恶的辩论。我想要的只是冒泡一个属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多