Что случилось с BeforeBuild и другими объектами в VS2012?

Я пытаюсь выполнить некоторые предварительные шаги для работы в проекте на С++ в Visual Studio 2012, но они не вызываются (хотя я уверен, что в Visual Studio 2010 одинаковые методы были в порядке). Строки командной строки ведут себя точно так же.

Это конец файла проекта; файл был сгенерирован с использованием Visual Studio, а затем я просто добавил последние пару строк:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="BeforeBuild">
  <Message Text="### BeforeBuild ###" />
</Target>
<Target Name="BeforeCompile">
  <Message Text="### BeforeCompile ###" />
</Target>
<Target Name="AfterBuild">
  <Message Text="### AfterBuild ###" />
</Target>

и здесь вывод:

Project "d:\temp\temp.vcxproj" on node 1 (default targets).
InitializeBuildStatus:
  Creating "Debug\temp.unsuccessfulbuild" because "AlwaysCreate" was specified.
AfterBuild:
  AfterBuild
FinalizeBuildStatus:
  Deleting file "Debug\temp.unsuccessfulbuild".
  Touching "Debug\temp.lastbuildstate".

Поэтому учитывается только AfterBuild, а остальные игнорируются. В этом я нашел эту PropertyGroup в Microsoft.BuildSteps.targets:

<BuildDependsOn>
  _PrepareForBuild;
  $(BuildSteps);
  AfterBuild;
  FinalizeBuildStatus;
</BuildDependsOn>

Разве это не должно иметь объекты BeforeBuild и BuildEvent? Или что-то не так с моей установкой MSBuild, заставляя ее использовать этот файл BuildSteps.targets, а не что-то еще?

Решение

Как указывает Алексей, использование Before/AfterTarget позволяет использовать обходное решение. Вам просто нужно позаботиться о том, какие цели использовать, но это легко, посмотрев файл BuildSteps. На данный момент это работает нормально:

<Target Name="BeforeBuild" BeforeTargets="PrepareForBuild">
  <Message Text="### BeforeBuild ###" />
</Target>
<Target Name="BeforeCompile" BeforeTargets="BuildCompile">
  <Message Text="### BeforeCompile ###" />
</Target>
<Target Name="AfterBuild" AfterTargets="Build">
  <Message Text="### AfterBuild ###" />
</Target>

Ответы

Ответ 1

У меня есть те же самые цели msbuild, как вы описали, поэтому я думаю, что ваша установка msbuild прекрасна. Похоже, они решили сделать некоторую очистку для целей и зависимостей (не уверен, что эта проблема связана с версией VS, VS просто использует одни и те же цели, предоставленные msbuild). BeforeBuild и другие цели все еще существуют в Microsoft.common.targets. Я предполагаю, что он просто зарезервирован для .NET-проектов (я никогда не играл с С++, поэтому я не собирал там конвейер).

В любом случае, работает ли это или нет в предыдущих версиях, ваша проблема может быть решена намного проще - просто используйте новые атрибуты BeforeTargets\AfterTargets для MSBuild 4.0 и привяжите свои цели непосредственно к тому, что вы хотите:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="BeforeBuild" BeforeTargets="Build">
     <Message Text="### BeforeBuild ###" Importance="high" />
</Target>
<Target Name="BeforeCompile" BeforeTargets="Compile">
    <Message Text="### BeforeCompile ###" Importance="high" />
</Target>
<Target Name="AfterBuild" AfterTargets="Build">
    <Message Text="### AfterBuild ###" Importance="high" />
</Target>