MSBuild错误地解析了自定义生成目标中的引用

时间:2015-03-06 10:54:16

标签: c# visual-studio msbuild

我必须创建一个自定义的MSBuild Target,因为我有多个带有命名约定的CS文件,所有文件(大多数是1-3个文件)都必须编译成一个程序集。为简单起见,我们假设每个DLL有1个文件。这意味着:

files/file1.cs
files/file2.cs
files/file3.cs

并且在输出中应该有File1.dll,File2.dll File3.dll

所以我创建了一个自定义的MSBuild目标,如下所示:

<ItemGroup>
    <CSFile Include="file\*.cs" Exclude="" />
</ItemGroup>

<ItemGroup>
    <Reference Include="System.dll"/>
    <Reference Include="..\libs\customdll.dll"/>
</ItemGroup>

<Target Name="CompileFiles" Inputs="@(CSFile)" Outputs="$(OutputPath) (CSFile.Filename).dll" >
    <CSC Sources="%(CSFile.Identity)" TargetType="library" OutputAssembly="$(OutputPath)%(CSFile.Filename).dll" References="@(Reference)"/>
</Target>

它在某些方面起作用,但是现在当我想要将一些Nuget包挂钩到它(它与NuGet本身无关,但它在我尝试更改一些引用路径时出现)和

<Reference Include="..\libs\customdll.dll"/>

更改为

<Reference Include="customdll"/>
  <HintPath>..\libs\customdll.dll</HintPath>
</Reference>

它根本不起作用。看起来MSBuild没有正确解析引用,只使用&#34; Include&#34;属性。它不会检查HintPaths,系统路径等。此外,当我尝试将DependsOnTargets="ResolveAssemblyReferences"添加到Target时,我会在调用CSC时看到引用中的完整路径(当{ {1}}已更改为@(Reference)),但令人惊讶的是,某些基本引用(如@(ReferencePath)System等)似乎多次被包含在内,编译器抱怨我必须删除重复项。即使我从System.Core删除它们,错误仍然是相同的。

所以一般有两种错误。首先,当我不​​使用来自Microsoft.CSharp中的公共目标的<ItemGroup><Reference>..目标时,基本上说Metadata file系统could not be found,这基本上意味着它无法解析引用,第二个错误是当我使用它并且引用被正确解析时,但是libs以某种方式包含多次并且仍然无法编译。

知道如何解决这个问题吗?或者,如果没有VisualStudio生成的完整工作CSPROJ,我的MSBuild目标应该如何实现每个标准的DLL目标。

我已经尝试过MSBuild工具4.0,12.0。以及.NET4.0 / .NET4.5目标框架的各种组合。

1 个答案:

答案 0 :(得分:0)

我想到了三个想法:

1)尝试使用Csc taks中的“AdditionalLibPaths”和“BaseAddress”参数。

2)如果你说@(ReferencePath)包含重复项 - 请删除它们。但是,在运行目标ResolveAssemblyReferences之后,不是来自Reference项,而是来自ReferencePath。 尝试RemoveDuplicates任务

3)(这将是我的方法)忘记自己运行csc。创建两个单独的文件(Main.proj和FileBuild.proj)并使用标准的着名MSBuld任务。 (我是从头上写的,所以可以在这里找到一些类型:P这只是一个概念)

Main.proj:

<ItemGroup>
  <CSFile Include="file\*.cs" />
</ItemGroup>

<Target Name="CompileFiles">
  <MSBuild Projects="FileBuild.proj" Properties="CsFile=%(CSFile.Identity)" />
</Target>

FileBuild.proj

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <OutputPath>bin\</OutputPath>
    <AssemblyName>$(CsFile)</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="System.dll"/>
    <Reference Include="..\libs\customdll.dll"/>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="$(CsFile)" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

当然,您必须在FileBuild中设置其他信息(比如将AssemblyName更改为仅包含没有扩展名的文件名),或者如果您确实需要输入/输出,则必须从Main.proj中的MSBuild获取输出。