none
MSBuild DependsOnTargets in nested proj invoked but should not? RRS feed

  • Question

  • Hi, 
    I'm having a problematic behaviour with msbuild that some projects/targets are 
    skipped (maybe correct) but DependsOnTargets are run but should also be skipped?
    This difference leads to unbuilt dependencies etc.

    In the example below 'someCsProj.csproj' is built fine in 'projA.proj', then that msbuild file invokes 
    projB.proj using the msbuild task which invokes the 'PreBuild' target but skips 'someCsProj.csproj/Build' since 
    it's already built but this leads to missing dependencies (disk is cleaned in prebuild).

    Specific question: Why is the DependsOnTargets in projB run but not the MSBuild task 'someCsProj.csproj' ?
     I cannot see how they get different properties etc. We get into an invalid state when PreBuild is run but not the MSBuild task later. 
     Shouldn't the same 'Target skipped. Previously built successfully' rules apply to both targets?

    build is invoked with 'msbuild.exe projA.proj /t:Build'
    Example files, 

    'projA.proj':
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="common.proj" />
      <Target Name="Build" DependsOnTargets="PreBuild">
        <Message Text="Build in projA" />
        <MSBuild Projects="someCsProj.csproj" Targets="Build" />
        <MSBuild Projects="projB.proj" Targets="Build" />
      </Target>
    </Project>

    'projB.proj':
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="common.proj" />
      <Target Name="Build" DependsOnTargets="PreBuild">            <!-- prebuild is run -->
        <Message Text="Build in projB, first" />
        <MSBuild Projects="someCsProj.csproj" Targets="Build" />   <!-- this is not run -->
        <Message Text="Build in projB, second" />
      </Target>
    </Project>

    'common.proj':
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Target Name="PreBuild">
        <Message Text="*** cleaning and init etc" />
      </Target>
    </Project>

    Friday, February 14, 2020 10:17 PM

All replies

  • Hi omtslug2,

    Sorry for delay in reply. 

    According to your description, you need to put the <Import ...> into the file button, otherwise the msbuild will just run common.proj, which is like:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Target Name="Build" DependsOnTargets="PreBuild">           
        <Message Text="Build in projB, first" />
        <MSBuild Projects="someCsProj.csproj" Targets="Build" />   
        <Message Text="Build in projB, second" />
      </Target>
     <Import Project="common.proj" />
    </Project>

    The result on my side:

    Any feedback will be expected.

    Best Regards,

    Dylan


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com

    Monday, February 17, 2020 6:31 AM
  • Hi
    sorry I don't understand the comment regarding move import into the file button.
    I've moved the import down with no change to previous behaviour.

    My issue is that the DependsOnTargets in ProjB.proj is run while the MSBuild task in the same file is skipped with:
     Project "C:\temp\projB.proj" (3) is building "C:\temp\SomeNormalCsProj.csproj" (2:2) on node 1 (Build target(s)).
     Building with tools version "Current".
     Target "Build" skipped. Previously built successfully.

    In the prebuild we have some initialization and cleanup so when that's run again and then build of 
    dependencies are skipped we get into an invalid state.
    Either both common.proj/Build and SomeNormalCsProj.csproj/Build shall be run or none

    (in the original post I didn't include a SomeNormalCsProj.csproj, in your run you get errors due to that)
    Monday, February 17, 2020 3:23 PM
  • Hi omtslug2,

    Thank you for feedback.

    In general, the target could not run twice in one build process. But "DependsOnTargets" ("PreBuild") will ignore this rule, and must run before the current target("Build" in ProjA and ProjB) runs. 

    If the current target has a condition attribute, the "DependsOnTargets" will not execute only if the condition attribute is false。

    Please refer this doc:Target build order, for "DependsOnTargets".

    Any feedback will be expected.

    Best Regards,

    Dylan


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com

    Wednesday, February 19, 2020 7:58 AM