MSBuild: Custom.After.Microsoft.Common.targets для собственных проектов C ++ в VS2010 - PullRequest
6 голосов
/ 13 октября 2010

Я читал об использовании «Custom.Before.Microsoft.Common.targets» и «Custom.After.Microsoft.Common.targets» для выполнения пользовательской цели до / после каждой сборки проекта, и я бы хотелнравится использовать эту технику для изменения информации о версии при сборке на нашем сервере сборки TeamCity.

Проблема в том, что, хотя он работает для проектов C #, он, похоже, не работает для нативных проектов C ++.

После некоторого поиска в файле Microsoft.Cpp.targets я обнаружил, что для нативных проектов C ++ это, по-видимому, реализуется путем установки $ (ForceImportBeforeCppTargets) и $ (ForceImportAfterCppTargets).

Iне могу найти ни одной информации в Интернете об этой технике для родных приложений C ++, поэтому я спрашиваю, смотрю ли я в правильном направлении или нет.

Любая помощь приветствуется.

Ответы [ 2 ]

11 голосов
/ 14 октября 2010

Для проектов VC ++ это немного отличается. Вы определяете файл для импорта либо в начале, либо в конце проекта. Чтобы использовать этот подход, вам нужно определить значения для свойств ForceImportBeforeCppTargets или ForceImportAfterCppTargets. Например, если вы хотите, чтобы файл был включен в начале проекта, вы можете передать значение в командной строке. Например, я только что создал фиктивный проект VC ++ с именем CppTets01. Затем я создал два примера файлов ниже.

Before.proj

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


  <Target Name="CustomTargetInBefore" AfterTargets="Build">
    <Message Text="From CustomTargetInBefore" Importance="high"/>
  </Target>

</Project>

After.proj

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

  <Target Name="CustomTargetInAfter" AfterTargets="Build">
    <Message Text="From CustomTargetInAfter" Importance="high"/>
  </Target>

</Project>

Затем я выполнил следующую команду:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\Before.proj";
    ForceImportAfterCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\After.proj"

Результат был C: \ Temp_NET \ ThrowAway \ CppTest01 \ CppTest01> msbuild CppTest01.vcxproj / p: ForceImportBeforeCppTargets = "C: \ Temp_NET \ ThrowAway \ CppTest01 \ C ppTest01 \ Before.proj "; ForceImportAfterCppTargets =" C: \ Temp_NET \ холостые \ CppTest01 \ CppTest01 \ After.proj "

Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.1]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 10/18/2010 8:32:55 AM.
Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" on node 1 (default targets).
InitializeBuildStatus:
  Creating "Debug\CppTest01.unsuccessfulbuild" because "AlwaysCreate" was specified.
ClCompile:
  All outputs are up-to-date.
  All outputs are up-to-date.
ManifestResourceCompile:
  All outputs are up-to-date.
Link:
  All outputs are up-to-date.
Manifest:
  All outputs are up-to-date.
FinalizeBuildStatus:
  Deleting file "Debug\CppTest01.unsuccessfulbuild".
  Touching "Debug\CppTest01.lastbuildstate".
CustomTargetInBefore:
  From CustomTargetInBefore
CustomTargetInAfter:
  From CustomTargetInAfter
Done Building Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.21

Как видно из выходных данных, цели были успешно внедрены в процесс сборки. Если вы хотите связать это обратно с Custom.Before.Microsoft.Common.targets и Custom.Before.Microsoft.Common.targets, то вы должны знать, что используемая там техника немного отличается. В частности, если вы создаете эти файлы, они автоматически импортируются в каждый проект C # / VB.NET. В этом случае вы должны установить это свойство. У вас действительно есть два варианта здесь:

  1. Вы можете установить это свойство как переменную окружения
  2. Вы можете использовать другую технику, ImportBefore & ImportAfter, которая специфична для VC ++

Для # 1 позвольте мне объяснить немного. В MSBuild, когда вы обращаетесь к свойству с синтаксисом $ (PropName), тогда, если свойство с именем PropName не существует, MSBuild будет искать в переменных среды, чтобы увидеть, существует ли такое значение, если оно существует, то это значение возвращается , Поэтому, если у вас есть сервер сборки, в который вы хотите включить файл для каждой сборки VC ++, просто создайте эти свойства как переменные среды. Теперь о другой технике.

ImportBefore / ImportAfter В VC ++ вводится новая концепция. В Microsoft.Cpp.Win32.targets вы можете увидеть объявление в верхней части файла .targets.

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportBefore\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportBefore')" />

Тогда есть один к низу

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportAfter\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportAfter')" />

Аналогичное объявление импорта существует и для других целевых платформ. Посмотрите на файлы в %ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\ для конкретных имен.

С помощью этой техники, если вы хотите импортировать файл, просто создайте файл, заканчивающийся .targets, и поместите его в соответствующую папку. Преимущество этого заключается в том, что он будет импортирован в каждую сборку VC ++ для этой платформы, и вы сможете создавать много разных файлов. Недостатком является то, что вы должны поместить их в эти конкретные папки. Это основное различие между обоими методами. С помощью этого первого метода вы можете указать местоположение файла через свойство, и оно не включается автоматически для каждой сборки, но для второго подхода это так, но вы не можете изменить местоположение

3 голосов
/ 25 января 2011

Вы также можете добавить содержимое проекта в один из *.props файлов из каталога %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\

Это дает тот же эффект.

...