【问题标题】:Visual Studio 2017 is building project over and over againVisual Studio 2017 一遍又一遍地构建项目
【发布时间】:2019-06-08 15:43:06
【问题描述】:

我有一个大解决方案(约 450 个项目),其中一些项目正在一遍又一遍地构建,尽管我没有改变任何东西。

当我将构建输出详细程度更改为 diagnostic 时,它会说:

项目“ProjectA”不是最新的。缺少输入文件 'C:\Src\Project.Core\Bin\Release\ProjectB.dll'

ProjectA 依赖于ProjectB,我正在构建配置Debug,那么为什么Visual Studio 会检查Release 文件夹中的文件ProjectB.dllProjectB.dll 被构建并复制到正确的文件夹中(调试)!

每个项目(c#和c++)的输出路径都是一样的:

<OutputPath>$(SolutionDir)Bin\$(Configuration)\</OutputPath>

这只是一个例子。我的解决方案中的多个项目都有这种奇怪的行为。似乎是 c++ 项目导致了这种情况,但我没有明确的证据。

这是我对文件访问的进程监视器分析:

更新 1:

ProjectA(C# 项目)使用 ProjectReference 引用 ProjectB(C++ 项目):

<ProjectReference Include="..\..\ProjectB.vcxproj">
   <Project>{F2F4C146-8A98-432B-BB9F-A06C4B4162CF}</Project> 
   <Name>ProjectB</Name>
</ProjectReference>

更新 2:

.NET Core 项目有这个设置:

针对 .NET Framework 的项目是否有类似的东西?

更新 3:

似乎 C# 项目的 FastUpToDateCheck 的代码在 csproj.dll 程序集中。由于它是本机程序集,因此我无法查看代码。真可惜。

【问题讨论】:

  • 你是如何设置依赖的?
  • 这可能是您在ProjectA 中从ProjectBRelease 文件夹中添加对ProjectB 的引用,因为您的所有项目都在同一个解决方案中,请确保您从解决方案。
  • ProjectA 通过 ProjectReference 引用 ProjectB
  • 这很奇怪。通常项目输出将位于路径bin\$(Configuration) 中的文件夹内,但从屏幕截图看来,您将所有项目的输出更改为位于单个解决方案文件夹中。您能否仔细检查Build 选项卡中的项目ProjectB 属性,以确保Configuration 发布和调试输出都配置到正确的目录。
  • 您的 solution's 调试配置是否设置为构建 ProjectB 的 project 调试配置?这让我多次遇到更复杂的解决方案。检查Build -&gt; Configuration Manager...

标签: c# c++ visual-studio msbuild


【解决方案1】:

问题不在于您的所有项目都在解决方案文件 (.sln) 中。 鉴于您正在使用项目引用。即&lt;ProjectReference
当某些项目位于解决方案文件 (
.sln) 中,并且它们引用解决方案文件之外的另一个项目时,MSBuild 将构建另一个项目,但不会使用您正在构建的配置。它总是或通常(一个错误)将使用您正在使用的相反配置构建。

顺便说一句,超级骗子烦人的错误。

作为一种解决方法,您可以为所有项目声明一个 ItemGroup,然后直接将其传递给 MSBuild,而根本不使用解决方案。

<ItemGroup>
   <Files Include="**\*.csproj" />
   <Files Include="**\*.vcxproj" />
</ItemGroup>

<Target Name="Build">
   <MSBuild Projects="@(Files)" Properties="Configuration=Debug" />
</Target>

如果它们都使用&lt;ProjectReference,那么 MSBuild 将自动确定它们的内置顺序。

或者您可以创建一个包含所有内容的解决方案。

【讨论】:

  • 对大量解决方案文件的警告:它们需要很长时间才能加载到 Visual Studio。但是当传递给 msbuild.exe 时,它​​们在命令行上工作正常
  • 事实并非如此。我引用的每个项目都在解决方案中。也许我解释得不够好,但是每个项目都建立在正确的配置中并被复制到正确的目录中。问题是,当 Visual Studio 为 projectA 执行 FastUpToDateCheck 时,它正在错误的目录(例如发布文件夹)中查找 projectB.dll。而且由于明显的原因,该文件在那里不可用,它一遍又一遍地构建 projectA,尽管它们没有任何变化..
  • 你应该输出一个详细的日志并将其保存到文件中,以便其他人可以看到发生了什么。
  • Visual Studios FastUpToDateCheck 没有记录任何内容。我只能提供我在问题中发布的 ProcessMonitor 的捕获。
  • msbuild -t:Build -p:Configuration=Debug -v:m -fl -flp:Verbosity=Normal,Logfile=build.log
【解决方案2】:

我遇到了和你一样的问题。我没有修复 - 只是一个适用于 msbuild 15 及更高版本的解决方法。和你一样,我发现无法将正确的目标输出路径从 clr 项目传递到 csproj ProjectReference 元素或其任何目标。

Directory.Build.targets (link) 中的某处添加以下代码,以便您的解决方案进行更新检查。

所发生的只是 dll 将从 OutputPath 复制到 IntermediateOutputPath,这允许 FastUpToDateCheck 找到它。

我发现这样做没有问题,即使我认为它“hacky”。如果您有非常“非标准”的构建路径/配置,可能会导致问题

  <Target Name="CopyClrToProjectOutputForFastUpToDateCheck" AfterTargets="AfterBuild" Condition="'$(CLRSupport)' == 'true' And '$(Language)' == 'C++'">
    <Message Text="Copying CLR Project output to intermeidate output path so that csprojs have the change to do fastuptodatecheck  $(OutputPath)$(TargetFileName) to $(IntermediateOutputPath)$(TargetFileName)"/>
    <Copy SourceFiles=" $(OutputPath)$(TargetFileName)"               DestinationFiles="$(IntermediateOutputPath)$(TargetFileName)" />
  </Target>

【讨论】:

    猜你喜欢
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多