MSBuild:VS. 2010中的本机C ++项目的Custom.After.Microsoft.Common.targets

时间:2010-10-13 13:52:07

标签: c++ visual-studio-2010 msbuild native

我已经阅读了“Custom.Before.Microsoft.Common.targets”和“Custom.After.Microsoft.Common.targets”的使用,以便在每个项目构建之前/之后执行自定义目标,我会喜欢使用这种技术,以便在我们的TeamCity构建服务器上构建时更改版本信息。

问题是虽然它适用于C#项目,但它似乎不适用于本机C ++项目。

在Microsoft.Cpp.targets文件中进行了一些挖掘之后,我发现对于本机C ++项目,这似乎是通过设置$(ForceImportBeforeCppTargets)和$(ForceImportAfterCppTargets)来实现的。

我似乎无法在网上找到关于本地C ++应用程序的这种技术的单一信息,所以我问我是否正在寻找正确的方向。

感谢任何帮助。

2 个答案:

答案 0 :(得分:11)

对于VC ++项目,它有点不同。您可以在项目的开头或结尾定义要导入的文件。要使用此方法,您需要为属性ForceImportBeforeCppTargetsForceImportAfterCppTargets定义值。例如,如果您希望在项目开头包含文件,则可以在命令行传递值。例如,我刚刚创建了一个名为CppTets​​01的虚拟VC ++项目。然后我在下面创建了两个示例文件。

<强> 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&gt; 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.targetsCustom.Before.Microsoft.Common.targets联系起来,那么你应该知道那里使用的技术有点不同。特别是如果您创建这些文件,它们会自动导入到每个C#/ VB.NET项目中。在这种情况下,您必须设置此属性。你真的有两个选择:

  1. 您可以将此属性设置为环境变量
  2. 你可以使用另一种技术,ImportBefore&amp; ImportAfter特定于VC ++
  3. 对于#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 ++构建中,并且您可以创建许多不同的文件。缺点是您必须将它们放在这些特定的文件夹中。这是两种技术之间的主要区别。使用第一种技术,您可以通过属性指定文件位置,并且不会为每次构建自动包含文件位置,但对于第二种方法,它是可以但您无法更改位置

答案 1 :(得分:3)

您还可以将项目内容添加到目录*.props

中的%LOCALAPPDATA%\Microsoft\MSBuild\v4.0\个文件之一

它也有同样的效果。