none
MSBuild.Task output for solution files

    Question

  • Hi,

    I have two questions.
    1) We are using MSBuild to organize a series of solutions. MSBuild does not seem to be able to capture the TargetOutputs parameter of the MSBuild task if you build a solution. As a matter of fact, it crashes. I would like to get a list of DLLs that were built as part of the solution. That does not appear to be possible with a solution and the MSBuild.Task output. It works fine for a single project.

    2) Is the scope of ItemNames which are populated through an output element limited to the current target? If I build a single project instead of a solution, the output parameter of the MSBuild task does return the DLL. If I reference the ItemName outside the scope of the current target, however, it is empty.

    Is there any way to populate such a list incrementally in sequential task so that in the end you'd have a list of all DLLs built in the various solution targets?

    I suppose you could accomplish this goal by cleaning the output directory and then reading in the files from that directory. That becomes cumbersome if not all solutions build to the same output directory, however.

    Any suggestions on how to best accomplish this? Thanks.


    <
    Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Test"><MSBuild Projects="Test.sln" >
    <
    Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects"/></MSBuild><Message Text="This is the list of built DLLs: @(AssembliesBuiltByChildProjects)"/></Target>
    <!--Message statement returns DLL when building a project, crashes MS build when building a solution-->

    <Target Name="Test"><MSBuild Projects="Test1.sln" >
    <
    Output TaskParameter="TargetOutputs" ItemName="AssembliesBuiltByChildProjects"/></MSBuild>
    </Target>

    <Target Name="Build"><MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Test,Test1" RunEachTargetSeparately="false" StopOnFirstFailure="true"/>
    <Message Text="This is the list of built DLLs returns nothing: @(AssembliesBuiltByChildProjects)"/>
    <!--Message statement returns empty string when referencing ItemName
    @(AssembliesBuiltByChildProjects). The same message statement in the Test target works. Anyway to make an ItemName visible to other targets-->

    </
    Target>

    </Project>

    Tuesday, June 14, 2005 8:01 PM

Answers

  • Hi Gerhardo,

    I'm sorry about the late response... You're right in 1), this is unfortunately not supported for building solution files. The MSBuild task will only return outputs for MSBuild project files.

    As for your second question... I'm not sure of how much value this will be to you since you can't get solution outputs from MSBuild, but here it is anyway. There's a problem with the MSBuild task that causes MSBuild to not know about items that were updated in the nested build (of a target in the same project file). Those items are available in all targets built after the one that contains the MSBuild task. To work around this, you can do two things: either consume produced items in a separate target called after your target containing the MSBuild task, or pass the necessary items via target outputs. Here's a short sample illustrating both methods:

    <Project DefaultTargets="Build;AfterBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Nested" Outputs="@(AppConfig)">

      <CreateItem Include="app.config" >
        <Output TaskParameter="Include" ItemName="AppConfig"/>
      </CreateItem>
      <Message Text="AppConfig in Nested: @(AppConfig)"/>
    </Target>

    <Target Name="Build">

      <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Nested">
        <Output TaskParameter="TargetOutputs" ItemName="ResultsOfNested"/>
      </MSBuild>

      <Message Text="ResultsOfNested in Build: @(ResultsOfNested)"/>
      <Message Text="AppConfig in Build: @(AppConfig)"/>
    </Target>

    <Target Name="AfterBuild">
      <Message Text="ResultsOfNested in AfterBuild: @(ResultsOfNested)"/>
      <Message Text="AppConfig in AfterBuild: @(AppConfig)"/>
    </Target>

    </Project>


    This produces the following results:
        AppConfig in Nested: app.config
        ResultsOfNested in Build: app.config
        AppConfig in Build: (<== this is the known problem)
        ResultsOfNested in AfterBuild: app.config
        AppConfig in AfterBuild: app.config

    thanks,
    Lukasz

    Saturday, June 25, 2005 1:35 AM
    Moderator

All replies

  • Hi Gerhardo,

    I'm sorry about the late response... You're right in 1), this is unfortunately not supported for building solution files. The MSBuild task will only return outputs for MSBuild project files.

    As for your second question... I'm not sure of how much value this will be to you since you can't get solution outputs from MSBuild, but here it is anyway. There's a problem with the MSBuild task that causes MSBuild to not know about items that were updated in the nested build (of a target in the same project file). Those items are available in all targets built after the one that contains the MSBuild task. To work around this, you can do two things: either consume produced items in a separate target called after your target containing the MSBuild task, or pass the necessary items via target outputs. Here's a short sample illustrating both methods:

    <Project DefaultTargets="Build;AfterBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Nested" Outputs="@(AppConfig)">

      <CreateItem Include="app.config" >
        <Output TaskParameter="Include" ItemName="AppConfig"/>
      </CreateItem>
      <Message Text="AppConfig in Nested: @(AppConfig)"/>
    </Target>

    <Target Name="Build">

      <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Nested">
        <Output TaskParameter="TargetOutputs" ItemName="ResultsOfNested"/>
      </MSBuild>

      <Message Text="ResultsOfNested in Build: @(ResultsOfNested)"/>
      <Message Text="AppConfig in Build: @(AppConfig)"/>
    </Target>

    <Target Name="AfterBuild">
      <Message Text="ResultsOfNested in AfterBuild: @(ResultsOfNested)"/>
      <Message Text="AppConfig in AfterBuild: @(AppConfig)"/>
    </Target>

    </Project>


    This produces the following results:
        AppConfig in Nested: app.config
        ResultsOfNested in Build: app.config
        AppConfig in Build: (<== this is the known problem)
        ResultsOfNested in AfterBuild: app.config
        AppConfig in AfterBuild: app.config

    thanks,
    Lukasz

    Saturday, June 25, 2005 1:35 AM
    Moderator
  • Hey Lukasz,

    Any plans for supporting TargetOutputs in the solution builds?  We're using Solutions to manage the project build order here and I'd hate to have to put together a manual MSBuild file just to gain access to TargetOutputs.

    Thanks,
    Colin

    Saturday, February 04, 2006 11:51 PM