2011-03-03 96 views
0

这看起来应该很简单,但我无法从该参考中找到它,而且我的google-fu显然很弱。在MSBuild中包含具有单独指定目录的文件

我只想单独指定文件名和基础文件夹中生成文件...

<?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> 

当我运行此,第一次警告显示这两个文件的预期,但第二次警告只能说明第一个文件(因为直串字符串将文件夹名称放在第一个文件夹上,但不是第二个文件夹)。

我该如何获得ItemGroup“TestFilesGroup”包含给定“TestFiles”和“TestFileRoot”属性的文件?

回答

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 
+0

谢谢你的非常详细的解答。花了我一段时间来弄清这些模式是如何相关的,但现在我已经开始工作了。 – Zarigani 2011-04-06 20:19:05

相关问题