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

  • TheBlindBat

    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



  • *jsd*

    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

  • taogeh

    Duh.  That works great.  Thanks.
  • AH_OF

    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.

  • vasanthaprabu

    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.
  • knechod

    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)' != ''".

  • Act_of_Bob

    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.
  • Testing for empty item list in a condition