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

Hal*_*alt 5 c++ msbuild native visual-studio-2010

我已经读过使用"Custom.Before.Microsoft.Common.targets"和"Custom.After.Microsoft.Common.targets"以便在每个项目构建之前/之后执行自定义目标并且我想使用这种技术是为了在我们的TeamCity构建服务器上构建时更改版本信息.

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

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

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

任何帮助表示赞赏.

Say*_*imi 10

对于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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

然后我执行了以下命令:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\Before.proj";
    ForceImportAfterCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\After.proj"
Run Code Online (Sandbox Code Playgroud)

结果是 C:\ Temp_NET\ThrowAway\CppTest01\CppTest01> msbuild CppTest01.vcxproj/p:ForceImportBeforeCppTargets ="C:\ Temp_NET\ThrowAway\CppTest01\C ppTest01\Before.proj"; ForceImportAfterCppTargets ="C:\ Temp_NET\ThrowAway\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
Run Code Online (Sandbox Code Playgroud)

从输出中可以看出,目标已成功注入构建过程.如果你想将它与之相关联Custom.Before.Microsoft.Common.targets,Custom.Before.Microsoft.Common.targets那么你应该知道那里使用的技术有点不同.特别是如果您创建这些文件,它们会自动导入到每个C#/ VB.NET项目中.在这种情况下,您必须设置此属性.你真的有两个选择:

  1. 您可以将此属性设置为环境变量
  2. 您可以使用另一种特定于VC++的ImportBefore&ImportAfter技术

对于#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')" />
Run Code Online (Sandbox Code Playgroud)

然后有一个朝向底部

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

其他目标平台也存在类似的导入声明.查看%ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\特定名称的文件.

使用此技术,如果要导入文件,则只需创建一个.targets以其结尾的文件并将其放入相应的文件夹中.这样做的好处是它将被导入到该平台的每个VC++构建中,并且您可以创建许多不同的文件.缺点是您必须将它们放在这些特定的文件夹中.这是两种技术之间的主要区别.使用第一种技术,您可以通过属性指定文件位置,并且它不会自动包含在每个构建中,但对于第二种方法,它是但您无法更改位置