0

I have the following MSBuild .proj file content:

<ItemGroup>
  <Exclude Include="*2.*"></Exclude>
</ItemGroup>

<ItemGroup>
  <!-- I have 3 files in the current directory: File1.cpp, File2.cpp and File3.cpp -->
  <ModuleInclude Include="*.cpp" Exclude="@(Exclude)"></ModuleInclude>

  <!-- I have 3 files in the Subfolder directory: eFile1.h, eFile2.h and eFile3.h -->
  <ModuleInclude Include="Subfolder\*.h" Exclude="@(Exclude->'Subfolder\%(identity)')"></ModuleInclude>
</ItemGroup>

<Target Name="Default">
  <Message Text="ModuleIncludes: %(ModuleInclude.identity)" />
  <Message Text="Excluded Items: @(Exclude)" />
  <Message Text="Excluded Subfolder Items: @(Exclude->'Subfolder\%(identity)')" />
</Target>

I see the following output:

ModuleIncludes: File1.cpp
ModuleIncludes: File3.cpp
ModuleIncludes: Subfolder\eFile1.h
ModuleIncludes: Subfolder\eFile2.h
ModuleIncludes: Subfolder\eFile3.h
Excluded Items: File2.cpp
Excluded Subfolder Items: Subfolder\File2.cpp

What I really need is to have the following Subfolder files included

ModuleIncludes: Subfolder\eFile1.h
ModuleIncludes: Subfolder\eFile3.h

The excluded subfolder items therefore should be:

Excluded Subfolder Items: Subfolder\eFile2.h

To be able to get such an output I would need the expression

Subfolder\*2.*

The syntax that I am using

@(Exclude->'Subfolder\%(identity)')

does not give me what I need. What would the correct syntax be? Or is this not possible?

Sami Islam
  • 65
  • 1
  • 6

1 Answers1

0

If you want to deal with wildcards as text, use properties instead of items:

<PropertyGroup>
  <FileExcludes>*2.*</FileExcludes>
</PropertyGroup>
<ItemGroup>
  <ModuleInclude Include="*.cpp" Exclude="$(FileExcludes)"></ModuleInclude>
  <ModuleInclude Include="Subfolder\*.h" Exclude="Subfolder\$(FileExcludes)"></ModuleInclude>
</ItemGroup>

You can even use an exclude pattern here that will match regardless of the subfolder:

<PropertyGroup>
  <FileExcludes>**\*2.*</FileExcludes>
</PropertyGroup>
<ItemGroup>
  <ModuleInclude Include="*.cpp" Exclude="$(FileExcludes)"></ModuleInclude>
  <ModuleInclude Include="Subfolder\*.h" Exclude="$(FileExcludes)"></ModuleInclude>
</ItemGroup>

If you really need it as a list to prepend non-local folders, use metadata items:

<PropertyGroup>
  <FileExclude Include="2">
    <Pattern>**\*2.*</Pattern>
  </FileExclude>
</PropertyGroup>
<ItemGroup>
  <ModuleInclude Include="*.cpp" Exclude="@(FileExclude)"></ModuleInclude>
  <ModuleInclude Include="..\shared-folder\*.h" Exclude="@(FileExclude->'shared-folder\%(Pattern)')"></ModuleInclude>
</ItemGroup>
Martin Ullrich
  • 94,744
  • 25
  • 252
  • 217
  • I tried using the exclude pattern defined as properties but that did not work. The second ModuleInclude in your example: `` would only work if my Subfolder is under the same tree as my current folder. What I would like to have is to use any folder (in any location) and reuse my exclusion pattern for that. Moreover I have a list of exclude patterns. If I define them as a single property then I cannot prepend a folder location to each of them. That is why I defined them as an item list. – Sami Islam Aug 05 '18 at 09:58
  • 1
    Ah yes for folders outside of the project cone the pattern won't work, you should include that in the question. – Martin Ullrich Aug 06 '18 at 01:45
  • Try the last example I added using item metadata, couldn't validate it though as not on a windows computer this weekend. – Martin Ullrich Aug 06 '18 at 01:49