MSBuild:VS2010中本地C ++项目的Custom.After.Microsoft.Common.targets
我已经阅读了关于使用Custom.Before.Microsoft.Common.targets和Custom.After.Microsoft.Common.targets为了在每个项目构建之前/之后执行自定义目标,我会喜欢使用这种技术,以便在构建TeamCity构建服务器时更改版本信息。
I've read about the use of "Custom.Before.Microsoft.Common.targets" and "Custom.After.Microsoft.Common.targets" in order to execute a custom target before/after every project build and I would like to use this technique in order to change version info while building on our TeamCity build server.
问题是,虽然它适用于C#项目,但似乎并不适用于本地C ++项目。
The problem is that although it works for C# projects, it doesn't seem to work for native C++ projects.
在Microsoft.Cpp.targets文件中的一些挖掘之后,我发现对于本地C ++项目,这似乎是通过设置$(ForceImportBeforeCppTargets)和$(ForceImportAfterCppTargets )。
After some digging around in the Microsoft.Cpp.targets file I found out that for native C++ projects this seems to be implemented through setting $(ForceImportBeforeCppTargets) and $(ForceImportAfterCppTargets).
我似乎无法在网络上找到一个关于这种技术的本地C ++应用程序的信息,所以我问,如果我看向正确的方向或不。
I can't seem to find a single piece of information on the web about this technique for native C++ apps though, so I'm asking if I'm looking in the right direction or not.
任何帮助是值得赞赏的。
Any help is appreciated.
有点不同。您可以在项目的开始或结束时定义要导入的文件。要使用这种方法,您需要为属性 ForceImportBeforeCppTargets
或 ForceImportAfterCppTargets
定义值。例如,如果您希望文件包含在项目的开头,您可以在命令行传递值。例如我刚刚创建了一个名为CppTets01的虚拟VC ++项目。然后,我在下面创建了两个示例文件。
For VC++ projects it is a bit different. You define a file to be imported either at the beginning or at the end of the project. To use this approach you need to define values for the properties ForceImportBeforeCppTargets
or ForceImportAfterCppTargets
. For example if you want a file to be included at the beginning of the project you can pass in the value at the command line. For example I just created a dummy VC++ project named CppTets01. Then I created the two sample files below.
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\ThrowAway\CppTest01\CppTest01\After.proj
The result was 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
从输出中可以看出,目标已成功注入构建过程。如果您想将此回到 Custom.Before.Microsoft.Common.targets
和 Custom.Before.Microsoft.Common.targets
那么你应该知道使用的技术有一点不同。特别是如果你创建这些文件,他们会自动导入到每个C#/ VB.NET项目。在这种情况下,您必须设置此属性。您在这里确实有两个选项:
As you can see from the output the targets were successfully injected into the build process. If you want to relate this back to Custom.Before.Microsoft.Common.targets
and Custom.Before.Microsoft.Common.targets
then you should know that the technique used there is a bit different. Specifically if you create those files they are automatically imported into every C#/VB.NET project. In this case you have to set this property. You really have two options here:
- 您可以将此属性设置为环境变量
- 可以使用另一种技术,ImportBefore& ImportAfter是VC ++特有的
对于#1 ,让我解释一下。在MSBuild中,当您访问一个带有语法$(PropName)的属性时,如果不存在名为PropName的属性,MSBuild将在环境变量中查找是否存在这样的值,如果存在,则返回该值。因此,如果你有一个构建服务器,其中包括每个VC ++构建的文件,然后只需创建这些属性作为环境变量。现在对于其他技术。
For #1 let me explain a bit. In MSBuild when you access a property with the syntax $(PropName) then if a property with the name PropName doesn't exist MSBuild will look up in the environment variables to see if such a value exists, if it does then that value is returned. So if you have a build server in which you want to include a file for each VC++ build, then just create those properties as environment variables. Now for the other technique.
ImportBefore / ImportAfter
在VC ++中引入了一个新概念。在Microsoft.Cpp.Win32.targets中,您可以在.targets文件顶部看到声明。
ImportBefore/ImportAfter In VC++ a new concept is introduced. In Microsoft.Cpp.Win32.targets you can see the declaration at the top of the .targets file.
<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\
下的文件的具体名称。
A similar import declaration exists for the other target platforms as well. Take a look at the files at %ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\
for the specific names.
使用此技术,如果您想要导入文件,那么只需创建一个以 .targets
结尾的文件,然后将其放入适当的文件夹。这样做的优点是它将被导入到该平台的每个VC ++构建中,并且您可以创建许多不同的文件。缺点是你必须将它们放在那些特定的文件夹中。这是两种技术之间的主要区别。有了这第一种技术,你可以通过属性指定文件位置,而不是自动包括每个版本,但对于第二种方法,但是你不能改变位置
With this technique if you want a file to be imported then simply create a file that ends with .targets
and place it into the appropriate folder. The advantage of this is that it will be imported into every VC++ build for that platform, and that you can create many different files. The drawback is that you have to place them in those specific folders. That's the main difference between both techniques. With this first technique you can specify the file location via property and its not automatically included for every build, but for the second approach it is but you cannot change the location