visual-studiovisual-studio-2012msbuildmsbuild-taskcustom-build

Use filter metadata in custom build tool VS2012 MSBuild


I have a problem which I want to solve elgantly, but for now don't know how to do it.

In my C++ solution(VS2012) I have a project which contains all .dll files which have to be copied into the Output-Directory for complete deployment. I have also written a small Custom-Tool to do the copying.

The acutal problem is that we have to deploy different .dlls for different configurations (Win32/x64/Debug/Release) and we have to set the ExcludedFromBuildproperty for every file and every configuration manually. I would like to have this property set automatically depending on which filter the files are in. To better see which .dll is copied for which configuration, I have organized them in filters with the following structure.

When I look into the vcxproj.filters file then the entries look like the following one.

<CopyFiles Include="..\bin.x64\icudt54d.dll">
  <Filter>x64\Debug</Filter>
</CopyFiles>

So I thought, I should be able to access the filter inside my copy target using %(CopyFiles.Filter)

<Target Name="AddInputsAccordingToFilter">
  <ItemGroup>
    <CopyFiles Include="@(CopyFiles)" Condition="%(CopyFiles.Filter.StartsWith('$(Platform)') And %(CopyFiles.Filter.EndsWith('$(Configuration)')"/>
  </ItemGroup>
</Target>

But this never worked and when trying to figure out the problem, I found out that %(CopyFiles.Filter) is always empty because the .vcxproj.filters isn't imported in the .vcxproj file. I tried to manually add an import to the .vcxproj.filters file, but then the filters in Visual Studio were totally messed up.

Does anyone know a way to automate this process without messing up the project for Visual Studio?


Solution

  • .filters file does not participate in the build process, but it can be queried as any xml file by XmlPeek task. Try the following:

    <Target Name="AddInputsAccordingToFilter">
      <XmlPeek Namespaces="&lt;Namespace Prefix='n' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;"
                 XmlInputPath="$(MSBuildProjectFile).filters"
                 Query="/n:Project/n:ItemGroup/n:CopyFiles[starts-with(n:Filter, '$(Platform)')]/@Include">
        <Output TaskParameter="Result" ItemName="FilesToCopy" />
      </XmlPeek>
      <ItemGroup>
        <CopyFiles Include="@(FilesToCopy)"/>
      </ItemGroup>    
    </Target>
    

    Take into account that this solution relies on .filter file format which is undocumented.