包含在MSBuild中单独指定目录的文件

时间:2011-03-03 22:57:31

标签: msbuild

这看起来应该很简单,但是我无法从参考文献中解决这个问题,而且我的google-fu显然很弱。

我只想在构建文件中单独指定文件名和基本文件夹...

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <TestFilesWithFolder>
      B:\Root\Test1.*;
      B:\Root\Test2.*
    </TestFilesWithFolder>
    <TestFiles>Test1.*;Test2.*</TestFiles>
    <TestFileRoot>B:\Root</TestFileRoot>
  </PropertyGroup>
  <Target Name="Build">
    <ItemGroup>
      <TestFilesGroupWithFolder Include="$(TestFilesWithFolder)" />
      <TestFilesGroup Include="$(TestFileRoot)\$(TestFiles)" />
    </ItemGroup>
    <Warning Text="Source files with folder: @(TestFilesGroupWithFolder)" />
    <Warning Text="Source files: @(TestFilesGroup)" />
  </Target>
</Project>

当我运行它时,第一个警告按预期显示两个文件,但第二个警告仅显示第一个文件(因为直字符串concat将文件夹名称放在第一个而不是第二个)。

如何让ItemGroup“TestFilesGroup”包含“TestFiles”和“TestFileRoot”属性的文件?

1 个答案:

答案 0 :(得分:3)

可以将以分号分隔的事物列表转换为项目,这样可以实现这一点,但属性中的项目包含通配符,因此如果您希望MSBuild将它们视为列表中的项目,则可以MSBuild第一次看到它时,路径必须是有效的。可能有办法做到这一点,但我想不出一个。换句话说......

<ItemGroup>
    <TestFiles Include="$(TestFiles)" />
</ItemGroup>

...仅当$(TestFiles)包含没有通配符或实际存在的合格路径的分隔列表时才有效。

此外,MSBuild无法在Include属性中组成带有通配符的路径并同时对其进行评估,因此您需要一个技巧来首先单独组成完整路径,然后将其提供给Include属性。以下内容可行,但需要将分隔属性更改为一组项目。它在此项目列表上批量依赖目标,每个批处理目标执行计算一个项目的元值,该值存储在新的元值中。当原始目标执行时,它能够在后续的包含中使用该元值。

<PropertyGroup>
  <TestFilesWithFolder>
    D:\Code\Test1.*;
    D:\Code\Test2.*
  </TestFilesWithFolder>
  <TestFileRoot>D:\Code</TestFileRoot>
</PropertyGroup>
<ItemGroup>
  <TestFilePattern Include="TestFilePattern">
    <Pattern>Test1.*</Pattern>
  </TestFilePattern>
  <TestFilePattern Include="TestFilePattern">
    <Pattern>Test2.*</Pattern>
  </TestFilePattern>
</ItemGroup>
<Target Name="Compose" Outputs="%(TestFilePattern.Pattern)">
  <ItemGroup>
     <TestFilePattern Include="TestFilePattern">
        <ComposedPath>@(TestFilePattern->'$(TestFileRoot)\%(Pattern)')</ComposedPath>
     </TestFilePattern>
  </ItemGroup>
</Target>
<Target Name="Build" DependsOnTargets="Compose">
  <ItemGroup>    
    <TestFilesGroupWithFolder Include="$(TestFilesWithFolder)" /> 
  </ItemGroup>
  <Warning Text="Source files with folder: @(TestFilesGroupWithFolder)" />
  <ItemGroup>
    <ComposedTestFiles Include="%(TestFilePattern.ComposedPath)" />   
  </ItemGroup>
  <Warning Text="Source files: @(ComposedTestFiles)" />
</Target>

产生以下输出:

(Build target) ->
d:\Code\My.proj(80,5): warning : Source files with folder:
   D:\Code\Test1.txt;D:\Code\Test2.txt
d:\Code\My.proj(84,5): warning : Source files:
   D:\Code\Test1.txt;D:\Code\Test2.txt
相关问题