Visual Studio 2012-добавочная сборка MSBuild не обнаруживает изменений

Я настроил проект MSBuild так, что целью по умолчанию является новая цель с именем, аналогичным "BuildWithExternalReference". Эта новая цель вызывает две другие цели; первая-пользовательская цель, называемая чем-то вроде "BuildExternalReference", которая создает DLL с помощью внешнего инструмента. Построенная DLL является ссылкой для основного проекта, который построен с использованием обычной цели "сборка". Я настроил атрибуты входов и выходов для цели "BuildExternalReference" так входы ссылки на исходные файлы, а ссылка выводит результат в DLL.

в Visual Studio 2012 и Visual Studio 2010 сборка работает правильно при первом вызове. Однако при последующих сборках, если я изменяю внешние исходные файлы (на которые ссылается атрибут целевых входных данных BuildExternalReference), Visual Studio 2012 просто сообщает "сборка: 0 успешно, 0 не удалось, 1 обновлено, 0 пропущено". Visual Studio 2010 продолжает работать отлично. В кроме того, построение из командной строки с помощью MSBuild.ехе работает отлично.

Я знаю, что система сборки в Visual Studio 2012 изменилась, но я не могу найти информацию об изменениях в том, как выполняются инкрементные сборки.

что-нибудь изменилось в Visual Studio 2012, чтобы вызвать инкрементные сборки для изменения?

вот сокращенная версия файла csproj, который я использую:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="BuildWithExternalTool" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <ExternalSourceFiles Include="..ExternalSourceFiles**.cs" />
    <ExternalDll Include="..ExternalSourceExternal.dll" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)Microsoft.CSharp.targets" />
  <Target Name="BuildExternalTool" Inputs="@(ExternalSourceFiles);" Outputs="@(ExternalDll)">
    <Exec Command="C:ExternalPathToTool.exe" />
  </Target>
  <Target Name="BuildWithExternalTool">
    <CallTarget Targets="BuildExternalTool" />
    <CallTarget Targets="Build" />
  </Target>
</Project>

обновление 1 ноября 2012

вот полный автономный пример, который воспроизводит проблему:

https://skydrive.live.com/redir?resid=EA1DD6ACA92F9EFF!155&authkey=!ANhuqF_rrCgxpLE

Это решение с одним проектом. MSBuildIssueExampleMSBuildIssueExample.файл csproj был настроен так, что есть пользовательская цель по умолчанию. Эта цель по умолчанию вызывает пользовательскую цель (называемую 'ExternalTool') , а затем сборку по умолчанию цель.

пользовательская цель ExternalTool записывает некоторые сообщения, чтобы убедиться, что она работает, а также копирует содержимое MSBuildIssueExampleExternalToolInput.txt-файл над выходом MSBuildIssueExampleExternalTool.txt-файл.

Вход.txt-файл-это вход цели ExternalTool и выход.txt-это выход.

чтобы воссоздать проблему, выполните следующие действия:

1) Откройте решение в указанной версии Visual Студия

2) Создайте решение один раз, чтобы убедиться, что выходы обновлены по отношению к входам

3) Измените MSBuildIssueExampleExternalToolInput.txt, поэтому его содержимое не соответствует выходу.txt

4) построить снова

при выполнении этого процесса в Visual Studio 2010 целевой объект ExternalTool будет вызываться снова, а входные данные.txt файл будет скопирован на выходные.формат txt.

когда вы проходите этот процесс в Visual Studio 2012 цель ExternalTool не будет вызываться, даже если входные данные являются более новыми, чем выходные данные, и в результате содержимое входных данных.txt не будет записываться на вывод.формат txt.

однако, если вы перестраиваете (а не просто строите), то обе версии Visual Studio работают так, как ожидалось.

3 ответов


Это обратная связь от Microsoft отвечает на вопрос:

" Это связано с изменением в VS 2012, где проекты C#/VB теперь делают "быструю последнюю проверку", которая позволяет им пропускать сборку, а не заставлять сборку все время. Одним из недостатков, однако, является то, что быстрая обновленная проверка не учитывает пользовательские цели, поэтому ваше инкрементное изменение не было обнаружено. Если вы хотите отключить "быстрый до-до-даты Регистрация" необходимо указать "DISABLEFASTUPTODATECHECK" в true либо как свойство MSBuild в файле проекта, либо как переменная среды в среде, из которой вы запускаете VS."

http://connect.microsoft.com/VisualStudio/feedback/details/770784/visual-studio-2012-msbuild-incremental-build-not-detecting-changes#details

таким образом, в основном это разрушительное изменение в Visual Studio 2012, которое, к сожалению, не очень хорошо документировано.


это старая проблема, но все еще актуальна. Большое спасибо, что подняли его здесь.

Я хотел бы представить результаты моих исследований.

в общем примере показано аномальное поведение как при построении в графическом интерфейсе Visual Studio, так и в командной строке devenv (devenv .\MSBuildIssueExample.sln /build)

однако, если вы замените файл csproj на следующий:

MSBuildIssueExample.csproj файл

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{4EA8847D-262C-4937-8536-E526E9BAB1C7}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MSBuildIssueExample</RootNamespace>
    <AssemblyName>MSBuildIssueExample</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="Custom.Targets" />
</Project>

таможни.Цели

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <CompileDependsOn>ExternalTool;$(CompileDependsOn)</CompileDependsOn>
    <CleanDependsOn>CleanOutput;$(CleanDependsOn)</CleanDependsOn>
  </PropertyGroup>
  <ItemGroup>
    <ExternalToolInputs Include="ExternalTool\Input.txt">
      <InProject>false</InProject>
    </ExternalToolInputs>
    <ExternalToolOutputs Include="ExternalTool\Output.txt">
      <InProject>false</InProject>
    </ExternalToolOutputs>
  </ItemGroup>
  <Target Name="ExternalTool" Inputs="@(ExternalToolInputs)" Outputs="@(ExternalToolOutputs)">
    <Message Text="ExternalTool target start, copying input file over output..." />
    <Copy SourceFiles="@(ExternalToolInputs)" DestinationFiles="@(ExternalToolOutputs)" />
    <Message Text="ExternalTool target end, copy successful" />
  </Target>
  <Target Name="CleanOutput">
    <Delete Files="@(ExternalToolOutputs)" ContinueOnError="true" />
  </Target>
</Project>

тогда поведение отличается !

Visual Studio GUI продолжает плохо себя вести,однако сборка командной строки с помощью devenv распознает изменение ввода!

также обратите внимание, что работает msbuild в командной строке вместо devenv работает правильно в обоих вариантах. Хотя msbuild имеет остальные проблемы. ..

редактировать

существует решение для сборки GUI, которое применимо только тогда, когда количество внешних файлов мало. Вы добавляете их в проект как ссылки и убедитесь, что Build Action is None. Тогда он отлично работает в GUI.

хотя, я только проверил с Custom.Targets, но я уверен, что он будет работать и с оригинальной версией.


чтобы расширить редактирование Марка, и так как None-элементы не работали для меня, вот пример пользовательского целевого файла, который я могу импортировать в другие проекты, который считывает текстовый файл в свойство (которое я могу использовать в DefineConstants свойство), и это пометит текстовый файл как входной для CoreCompile цель:

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

  <PropertyGroup>
    <CommonDefines>$([System.IO.File]::ReadAllText('$(SolutionDir)\_meta\definesFlags.txt'));$(CommonDefines)</CommonDefines>
  </PropertyGroup>

  <ItemGroup>
    <CustomAdditionalCompileInputs Include="$(SolutionDir)\_meta\definesFlags.txt" />
  </ItemGroup>

</Project>

CustomAdditionalCompileInputs-товаров в качестве вклада в Microsoft.Csharp.Core.targets.