从作为字符串的文件到对msbuild中的文件的引用

时间:2012-02-09 18:27:56

标签: msbuild

背景

随着项目和解决方案规模的扩大,CopyLocal=true导致大量构建速度下降(请参阅here),我试图找出一个适用于nuget并执行的基于约定的良好解决方案增量构建,只在必要时复制程序集及其相关文件,喜欢pdb。

这是我到目前为止所拥有的:

<!--
    Assumptions: each project copies all of its required dependencies
    to the same output directory.

    I have two basic options here. I can look at @(Reference) and pull
    the HintPath information to copy the correct assemblies, or I can
    use @(ReferencePath) which gives me a list of all the different
    required assemblies. The latter doesn't allow me to distinguish
    system ones from ones that I have explicitly included. I could
    probably include the non-system ones by filtering to some sub-
    directory of the solution.
-->
<ItemGroup>
  <_AssembliesToCopy Include="..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll" />
  <_AssembliesToCopy Include="..\..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll" />
  <!-- ... -->
</ItemGroup>
<PropertyGroup>
  <AfterBuildDependsOn>
    $(AfterBuildDependsOn);
    CopyReferencedAssemblies;
    CopyFilesRelatedToReferencedAssemblies
  </AfterBuildDependsOn>
</PropertyGroup>
<Target Name="AfterBuild" DependsOnTargets="$(AfterBuildDependsOn)" />
<Target Name="CopyFilesRelatedToReferencedAssemblies"
  Inputs="@(_ReferenceRelatedPaths)"
  Outputs="@(_ReferenceRelatedPaths->'$(OutputPath)%(Filename)%(Extension)')"
  DependsOnTargets="ResolveReferences"
  >
  <Copy
      SourceFiles="@(_ReferenceRelatedPaths)"
      DestinationFiles="@(_ReferenceRelatedPaths->'$(OutputPath)%(Filename)%(Extension)')"
      UseHardlinksIfPossible="true"
      />
</Target>

<Target Name="CopyReferencedAssemblies"
    Inputs="@(_AssembliesToCopy)"
    Outputs="@(_AssembliesToCopy->'$(OutputPath)%(Filename)%(Extension)')"
    DependsOnTargets="ResolveReferences"
    >
  <Copy
      SourceFiles="@(_AssembliesToCopy)"
      DestinationFiles="@(_AssembliesToCopy->'$(OutputPath)%(Filename)%(Extension)')"
      UseHardlinksIfPossible="true"
      />
</Target>

这完全符合我的需要。在新版本中,它会复制文件:

CopyReferencedAssemblies:
  Creating hard link to copy "..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll" to "..\..\build\bin\Debug\Moq.dll".
  Creating hard link to copy "..\..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll" to "..\..\build\bin\Debug\nunit.framework.dll".
CopyFilesRelatedToReferencedAssemblies:
Building target "CopyFilesRelatedToReferencedAssemblies" partially, because some output files are out of date with respect to their input files.
  Creating hard link to copy "c:\Project\packages\Moq.4.0.10827\lib\NET40\Moq.pdb" to "..\..\build\bin\Debug\Moq.pdb".
  Creating hard link to copy "c:\Project\packages\Moq.4.0.10827\lib\NET40\Moq.xml" to "..\..\build\bin\Debug\Moq.xml".
  Creating hard link to copy "c:\Project\packages\NUnit.2.5.10.11092\lib\nunit.framework.xml" to "..\..\build\bin\Debug\nunit.framework.xml".

当文件是最新的时,它什么都不做:

CopyReferencedAssemblies:
Skipping target "CopyReferencedAssemblies" because all output files are up-to-date with respect to the input files.
CopyFilesRelatedToReferencedAssemblies:
Skipping target "CopyFilesRelatedToReferencedAssemblies" because all output files are up-to-date with respect to the input files.

问题

我当前的解决方案存在的问题是,我必须重复项目参考中包含的HintPath已经提供的值:

<Reference Include="Moq">
  <HintPath>..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll</HintPath>
  <Private>False</Private>
</Reference>

成为额外的:

<_AssembliesToCopy Include="..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll" />

如何将%(Reference.HintPath)中找到的字符串集转换为文件引用?理想情况下,我想要一个我可以分配给_AssembliesToCopy的命令:

<_AssembliesToCopy Include="{{Change %(Reference.HintPath) to file ref}}"/>

1 个答案:

答案 0 :(得分:1)

这不起作用:

<Target Name="MyTarget">
  <ItemGroup>
    <_AssembliesToCopy Include="%(Reference.HintPath)" />
  </ItemGroup>
  ...then the Copy task using @(_AssembliesToCopy)
</Target>