C# MSBuild处理循环依赖项

C# MSBuild处理循环依赖项,c#,.net-4.0,msbuild,C#,.net 4.0,Msbuild,我不熟悉MSBuild。两天前刚开始尝试,现在我正在测试。我遇到了一个问题,出现了以下错误: "c:\Users\martinslot\Documents\Visual Studio 2010\Projects\MultifileAssembly\SpecializedBuild.xml" (BuildNumberUtil target) (1) -> c:\Users\martinslot\Documents\Visual Studio 2010\Projects\Multifile

我不熟悉MSBuild。两天前刚开始尝试,现在我正在测试。我遇到了一个问题,出现了以下错误:

"c:\Users\martinslot\Documents\Visual Studio 2010\Projects\MultifileAssembly\SpecializedBuild.xml" (BuildNumberUtil target) (1) ->
  c:\Users\martinslot\Documents\Visual Studio 2010\Projects\MultifileAssembly\SpecializedBuild.xml(4,34): error MSB4006: There is a circular dependency in t
he target dependency graph involving target "BuildNumberUtil".
我的MSBuild脚本如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="BuildNumberUtil" DependsOnTargets="BuildStringUtil" >
    <Message Text="=============Building modules for NumberUtil============="/>

    <Csc TargetType="Module" Sources="NumberUtil/DoubleUtil.cs; NumberUtil/IntegerUtil.cs" AddModules="/StringUtil/StringUtil"/>
    <Copy SourceFiles="@(NetModules)" DestinationFolder="../Output/Specialized"/>

  </Target>

  <Target Name="BuildStringUtil" DependsOnTargets="BuildNumberUtil" >
    <Message Text="=============Building modules for StringUtil============="/>

    <Csc TargetType="Module" Sources="StringUtil/StringUtil.cs;" AddModules="/NumberUtil/IntegerUtil;/NumberUtil/DoubleUtil"/>
    <Copy SourceFiles="@(NetModules)" DestinationFolder="/Output/Specialized"/>

  </Target>
</Project>

我理解这个问题,实际上我创建了这个小示例,以查看MSBuild是否理解并能够以某种方式纠正这个问题。我如何解决这个问题


我的问题是这两个目标编译相互依赖的模块。这里有人有没有关于如何使用MSBuild处理此类问题的解决方案?也许我用错误的方式构建了它?

您根本无法构建具有循环依赖关系的项目。你怎么能?你先造哪一个?可能有一些深奥、复杂、不正确的方法,但为什么要这样做呢?循环依赖通常表示设计缺陷。修复设计,您就不再有循环依赖关系问题。

可以在MSBuild和Visual Studio的范围内构造循环模块;然而,这样做的有效情况非常有限

如果您计划在代码中使用Xaml,一个关键的方法是删除
Csc
标记的
方面,并生成您自己的
.response
文件,该文件实际上指向您希望注入的代码。在
Csc
标记属性中,您可以在
ResponseFiles
属性中自己指定此文件

.response
文件中,然后将应用程序分解为程序集和netmodule组件,确保始终首先包含核心程序集的文件。通常,
Csc
标记的属性直接转换为Csc.exe命令行参数。参数名称并不总是匹配的。为了便于解析,在引用文件时,最好使用完整的、非相对的路径(例如,下面的部分,
.response
):

您会注意到,这最终会将您的多个目标集合并为一个,并且我自己已经包含了xaml生成的代码。这就是删除源方面的部分原因,因为MSBuild任务的Xaml页面生成器部分会自动将信息注入@(编译)集中。由于存在调试/发布配置,在定义要使用的响应文件的区域中,我创建了两个版本的响应(因为我使用的是T4模板):

如果希望在代码中包含多个平台,则可能需要C*p响应文件,其中C是配置数(Debug | Release),p是平台数(x86、x64、AnyCpu)。这种解决方案可能只会是一种使用生成器的正常方法


简短的版本是:只要您能保证在一个步骤中编译所有模块,就可以创建循环模块。为了确保维护Xaml构建步骤提供给您的构建功能,最好从一个普通的C#项目开始,从
中的
$(MSBuildToolsPath)\Microsoft.CSharp.Targets
创建您自己的
.Targets
文件,注意这是针对web应用程序的(ASP.NET标准web应用程序或ASP.NET MVC应用程序)和此问题的修复程序将从“.csproj”文件的下一行中删除


$(BuildDependsOn);
包裹

它就是不能工作。解决方案对于第三个项目来说是微不足道的,一个可以生成其他项目所需元数据的项目。在.NET framework中有一个真实的例子,mscorlib取决于系统,系统取决于mscorlib。无论Microsoft使用什么引导机制来解决它(.netmodules,可能,可能是中间al.exe链接版本)是您不想进入的内容。哦,现在我可以看到,在通过VS GUI界面添加引用时,VS实际上发出了警告(右键单击引用并添加项目引用)。谢谢你的回答,Hans Passant。你为什么直接调用
任务?@KMoraz 1)因为我想尝试MSBuild out 2)因为我不知道更好的方法。通常你会让.csproj文件来控制编译逻辑。打开任何.csproj文件,您都会注意到它实际上是MSBuild文件,带有指向常见任务和项目数据定义的指针。
"X:\Projects\Code\C#\Solution Name\InternalName\ProjectName - InternalName\SearchContexts\StringSearchType.cs"
"X:\Projects\Code\C#\Solution Name\InternalName\ProjectName - InternalName\UI\Themes\Themes.cs"
/target:module /out:bin\x86\Debug\InternalName.UI.dll
"X:\Projects\Code\C#\Solution Name\InternalName\ProjectName - InternalName\UI\EditDatabaseImageControl.xaml.cs"
"X:\Projects\Code\C#\Solution Name\InternalName\ProjectName - InternalName\obj\x86\Debug\UI\EditDatabaseImageControl.g.cs"
ResponseFiles="$(CompilerResponseFile);InternalName.$(Configuration).response"
<PropertyGroup>
  <BuildDependsOn>
    $(BuildDependsOn);
    Package
  </BuildDependsOn>
</PropertyGroup>