首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSBuild处理循环依赖关系

MSBuild处理循环依赖关系
EN

Stack Overflow用户
提问于 2012-03-18 04:58:04
回答 3查看 6.1K关注 0票数 2

我是MSBuild的新手。两天前才开始尝试,现在我只是在测试它。我遇到了一个问题,我得到了这个错误:

代码语言:javascript
复制
"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脚本如下所示:

代码语言:javascript
复制
<?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处理这类问题的解决方案吗?也许我构建的方式是错误的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-18 07:37:10

您根本不能构建具有循环依赖关系的项目。你怎么能这样呢?你首先构建哪一个?可能有一些深奥的,令人费解的,不正确的方式来做,但是为什么要这样做呢?循环依赖通常表示设计缺陷。修复设计,您将不再有循环依赖问题。

票数 5
EN

Stack Overflow用户

发布于 2014-03-09 15:18:45

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

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

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

代码语言:javascript
复制
"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"

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

代码语言:javascript
复制
ResponseFiles="$(CompilerResponseFile);InternalName.$(Configuration).response"

如果您打算在代码中包含多个平台,则可能需要C*P响应文件,其中C是配置的数量(调试|发布),P是平台的数量(x86、x64、AnyCpu)。这种解决方案很可能只是一个使用生成器的明智的方法。

简而言之:创建循环模块是可能的,只要你能保证你能在一个步骤中编译所有的模块。为了确保保持Xaml构建步骤提供的构建功能,最好的方法是从一个普通的C#项目开始,然后从底部附近的$(MSBuildToolsPath)\Microsoft.CSharp.targets标记中的<Import ...创建您自己的<Import ...文件。出于设计目的,您可能还需要一个辅助csproj,因为使用此变通方法会丢失很大一部分智能感知(或者使用csproj Condition属性,其中目标是通过您设置的某个标志来选择的)。您还会注意到,某些Xaml编辑器似乎不喜欢绑定到netmodule名称空间,所以如果您绑定到netmodule中的类型,则很可能必须在代码背后完成它们(我还没有测试过解决方法,因为通常有一些方法可以绕过静态名称空间绑定)

由于某些原因,.baml编译的.xaml文件被Csc编译器隐式地理解,我还不能弄清楚它是从命令参数哪里得到的,或者它只是被设计成隐式的。如果我不得不猜测它们是由与所包含文件列表中包含的内容相关联的g.cs文件推断出来的。

票数 1
EN

Stack Overflow用户

发布于 2016-04-05 18:32:17

注意到web应用程序(无论是ASP.NET标准web应用程序还是ASP.NET MVC应用程序)都会发生这种情况,解决此问题的方法是删除".csproj“文件中的以下行。

代码语言:javascript
复制
<PropertyGroup>
  <BuildDependsOn>
    $(BuildDependsOn);
    Package
  </BuildDependsOn>
</PropertyGroup>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9753653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档