我已经阅读了“Custom.Before.Microsoft.Common.targets”和“Custom.After.Microsoft.Common.targets”的使用,以便在每个项目构建之前/之后执行自定义目标,我会喜欢使用这种技术,以便在我们的TeamCity构建服务器上构建时更改版本信息。
问题是虽然它适用于C#项目,但它似乎不适用于本机C ++项目。
在Microsoft.Cpp.targets文件中进行了一些挖掘之后,我发现对于本机C ++项目,这似乎是通过设置$(ForceImportBeforeCppTargets)和$(ForceImportAfterCppTargets)来实现的。
我似乎无法在网上找到关于本地C ++应用程序的这种技术的单一信息,所以我问我是否正在寻找正确的方向。
感谢任何帮助。
答案 0 :(得分:11)
对于VC ++项目,它有点不同。您可以在项目的开头或结尾定义要导入的文件。要使用此方法,您需要为属性ForceImportBeforeCppTargets
或ForceImportAfterCppTargets
定义值。例如,如果您希望在项目开头包含文件,则可以在命令行传递值。例如,我刚刚创建了一个名为CppTets01的虚拟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.targets
和Custom.Before.Microsoft.Common.targets
联系起来,那么你应该知道那里使用的技术有点不同。特别是如果您创建这些文件,它们会自动导入到每个C#/ VB.NET项目中。在这种情况下,您必须设置此属性。你真的有两个选择:
对于#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\
个文件之一
它也有同样的效果。