Testing for empty item list in a condition

I am setting up a dependency property group (to be used in a Target's DependsOnTargets attribute).  I would like to have a dependency optionally show up depending on whether an item list exists and is non empty.  So far, this is the best I could come up with:

<PropertyGroup>
   <OtherLibFilesTemp>@(OtherLibFiles->'%(identity)')
   </OtherLibFilesTemp>
   <OtherLibTargets Condition="'$(OtherLibFilesTemp)' != ''">OtherLibTargets</OtherLibTargets>
   <BuildLibDependsOn>
       PrepareOutputDir;
       CompileVcSource;
       CompileMCppSource;
       $(OtherLibTargets)
    </BuildLibDependsOn>
</PropertyGroup>


Is there a way to do this without introducing the OtherLibFilesTemp node


Answer this question

Testing for empty item list in a condition

  • Brian Mains

    Duh.  That works great.  Thanks.
  • Galb

    I see.  In my case, I wanted to allow for project files (that in my .targets files) to optionally be able to have their own Target called "Other".  This is because my top level target "BuildLib" (in my .targets file) creates an archive lib from a bunch of .obj files.  I was going to allow project files to optionally add to the "ObjFiles" item list that BuildLib uses in an "Other" target and then have the BuildLib target in my .targets file execute that target conditionally.  I guess I could always have the project file add onto the BuildLibDependsOn property but I thought there should be a simpler way.
  • HuyN_MS

    Doh!  That doesn't work when my property group/targets are imported into a msbuild project that doesn't have the OtherLibFiles item defined.  I get:

    error MSB4057: The target "OtherLibTargets" does not exist in the project.

  • lex3001

    Hey Keith,

    In our .targets files we usually put the "Other" target in the dependency chain and then put a condition on it, making it run only when the item list is not empty. Your target will not run (nor will any of its dependencies) if the condition evaluates to false. This should be equivalent to what you're trying to do.
    Putting item lists inside conditions for properties is not usually what you want, since MSBuild evaluates all properties before evaluating item lists.

    thanks,
    Lukasz

  • Sarim Ghani

    BTW, I'm doing this because there are times when we need to compile certain .c/cpp files with different compile flags (like no debug) in a particular project file.  Therefore I want to allow folks to create custom Targets in their project files but still have that Target contribute to the overall BuildLib target defined in my .targets file.
  • Senthil84

    BTW, if I stick the test for an empty item list into the condition like so:

    <PropertyGroup>
      <Other Condition="
    '@(OtherFiles)' != ''">Other</Other >
      <BuildLibDependsOn>
        PrepareOutputDir;
        CompileVcSource;
        CompileMCppSource;
        $(Other)
      </BuildLibDependsOn>
    </PropertyGroup>


    I get this error:

    error MSB4099: A reference to an item list at position 2 is not allowed in this condition "'@(OtherFiles)' != ''".

  • Julie Lerman

    You can consider having an empty "Other" target in the main .targets file and then overriding it only in the leaf projects that need to redefine it. If you define multiple targets with the same name, the last one wins (obviously, it's important to put the leaf project target after the Import). This way you can have an extensible target in the dependency chain that doesn't do anything unless it's overriden in the leaf project.

    thanks,
    Lukasz



  • Testing for empty item list in a condition