【问题标题】:MSBuild, OutputPath to a lib directory is not honouredMSBuild,不支持 lib 目录的 OutputPath
【发布时间】:2017-10-07 17:02:47
【问题描述】:

我现在花了几个小时,但我根本不明白:

为什么 lib 子目录不被 VS“快速更新检查”所认可? 如果设置了库的 lib 输出目录,则始终重建解决方案 - 是否进行了更改无关紧要。如果 \lib 子目录被删除,它可以工作。为什么?

这是我目前测试的:

参考下一个代码sn-p。那一个完美地工作。如果要求多个依赖项目构建多次,如果没有进行任何更改,它们实际上只构建一次。 Visual Studio FastUpToDateCheck 启动。

但是如果换行

<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutputPath>

<OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\lib\</OutputPath>

它不断地重建。任何想法为什么?

ComponentBuild.props 位于 .sln 文件旁边

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

  <PropertyGroup>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\$(MSBuildProjectName)\</IntermediateOutputPath>
    <UseCommonOutputDirectory>False</UseCommonOutputDirectory>
    <DisableFastUpToDateCheck>false</DisableFastUpToDateCheck>
  </PropertyGroup>

  <PropertyGroup Condition=" '$(OutputType)' == 'Library' ">
    <!-- To distinguish by \lib\ does not work, a rebuild is triggered since the up-to-date check fails -->
    <!-- <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\lib\</OutputPath> -->
    <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutputPath>   
    <OutDir>$(OutputPath)</OutDir>
  </PropertyGroup>

  <PropertyGroup Condition=" '$(OutputType)' == 'Exe' ">
    <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutputPath>
    <OutDir>$(OutputPath)</OutDir>
  </PropertyGroup>
</Project>

该文件包含在 Import Microsoft.CSharp.targets 之前的 csproj 文件中:

.csproj 文件:

    <!-- position of include is important, OutputType of project must be defined already -->
    <Import Project="$(SolutionDir)ComponentBuild.props" Condition="Exists('$(SolutionDir)ComponentBuild.props')" /> 
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <PropertyGroup>
      <PostBuildEvent>
      </PostBuildEvent>
    </PropertyGroup>

我测试的越多,行为变得越奇怪。 我创建了两个简单的库项目 A 和 B。B 依赖于 A。我添加了上面提到的导入和 FastUpToDateCheck 工作。 将 lib 路径添加到库输出类型后,它在没有其他任何更改的情况下工作。但是当 lib B 项目被清理后,每个后续构建都会重新构建项目 B。

将 lib 路径添加到 exe 输出类型时也是如此。 FastUpToDateCheck 再次起作用。

然后我再次从输出类型 exe 中删除了 lib 路径,但 FastUpToDateCheck 令人惊讶地仍然有效 - 总是。即使在清理构建、更改类或删除所有 obj 和 bin 文件夹时。

但是,一旦我从 lib 输出类型中删除了 lib 路径,即我将所有内容恢复为原始状态,它就会失败。它每次都重建。诊断输出的第一行是

项目“ClassLibrary1”不是最新的。缺少输出文件 'c:\Users\hg348\Documents\Visual Studio 2015\Projects\BuildTest\bin\Debug\AnyCPU\lib\ClassLibrary1.dll'

即使不再设置它,它仍然会查看 lib 路径。 我认为这涉及到一些令人讨厌的缓存。

有人可以验证一下吗?

【问题讨论】:

  • 无法复制。据我所知,主要区别在于您为库附加了 \lib only,而 exe 的输出路径保持不变。如果您也将 \lib 附加到那个会发生什么?与此相关的是,您的项目中未在此处显示的其他一些配置可能是罪魁祸首。
  • 是的,我只将它附加到库中。我发布的是完整配置。那个是在 csproj 文件中导入的。它似乎适用于单个项目。您是否对 2 个项目进行了尝试,其中一个项目引用了另一个项目?
  • 添加lib路径后,不要忘记在依赖类中进行更改或执行清理。否则无法观察到重建。

标签: msbuild


【解决方案1】:

好吧,我上面描述的测试得出了答案: 它缓存在 Visual Studio (VS) 中,它在更改输出路径后触发构建。在对输出路径和可能的 outdir 进行更改后,Visual Studio 仍会在旧目录中查找其 FastUpToDateCheck。

关闭并重新打开解决方案已经有助于清除 VS 缓存。在某些情况下需要删除隐藏文件夹.vs 中的隐藏文件.suo 这解决了上述问题中给出的示例文件中所述的所有问题。

我的最终导入文件如下所示:

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

      <!--  Note that VS caches settings, to be sure the FastUpToDateCheck works
                * reopen the solution after 
                    - changing properties
                    - after adding a platform config
                    - after adding references to projects
                * close VS and remove the hidden file 
                  <solution folder>\.vs\<solution name>\v14\.suo   after changing IntermediateOutputPath,
                  (You have to enable "how hidden files" in windows file explorer)
                * After updating App.config do a random change in any .cs source file too, 
                  otherwise FastUpToDateCheck fails
      -->

      <PropertyGroup>
        <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>

        <IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(MSBuildProjectName)\</IntermediateOutputPath>

        <!-- if true, don't copy output files of referenced assemblies, since everything builds to the same folder. -->
        <UseCommonOutputDirectory>true</UseCommonOutputDirectory>
        <DisableFastUpToDateCheck>false</DisableFastUpToDateCheck>
      </PropertyGroup>

      <PropertyGroup Condition=" '$(OutputType)' == 'Library' ">

        <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\lib\</OutputPath>
        <OutDir>$(OutputPath)</OutDir>
      </PropertyGroup>

      <PropertyGroup Condition=" '$(OutputType)' == 'Exe' ">
        <OutputPath>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutputPath>
        <OutDir>$(OutputPath)</OutDir>
      </PropertyGroup>


      <!-- sets "Copy Local" property of references to false on reopen of solution
           don't copy output files of referenced assemblies, since everything builds to the same folder -->
      <ItemDefinitionGroup>
        <Reference>
            <Private>False</Private>
        </Reference>
        <ProjectReference>
            <Private>False</Private>
        </ProjectReference>
      </ItemDefinitionGroup>

  </Project>

【讨论】:

  • 最后我也找到了 $(Platform) 问题的解决方案。您的解决方案文件夹中有一个 .vs 文件夹。那个似乎缓存了像 IntermediateOutputPath 这样的属性设置。我关闭了VS,删除了文件夹.vs\&lt;solution&gt;\v14\.suo中的文件.suo,它工作了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 2015-10-18
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
相关资源
最近更新 更多