Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
598 views
in Technique[技术] by (71.8m points)

visual studio 2010 - MSBuild: Custom.After.Microsoft.Common.targets for native C++ projects in VS2010

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.

The problem is that although it works for C# projects, it doesn't seem to work for native C++ projects.

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).

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

Then I executed the following command:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:Temp\_NETThrowAwayCppTest01CppTest01Before.proj";
    ForceImportAfterCppTargets="C:Temp\_NETThrowAwayCppTest01CppTest01After.proj"

The result was C:Temp_NETThrowAwayCppTest01CppTest01>msbuild CppTest01.vcxproj /p:ForceImportBeforeCppTargets="C:Temp_NETThrowAwayCppTest01C ppTest01Before.proj";ForceImportAfterCppTargets="C:Temp_NETThrowAwayCppTest01CppTest01After.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\_NETThrowAwayCppTest01CppTest01CppTest01.vcxproj" on node 1 (default targets).
InitializeBuildStatus:
  Creating "DebugCppTest01.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 "DebugCppTest01.unsuccessfulbuild".
  Touching "DebugCppTest01.lastbuildstate".
CustomTargetInBefore:
  From CustomTargetInBefore
CustomTargetInAfter:
  From CustomTargetInAfter
Done Building Project "C:Temp\_NETThrowAwayCppTest01CppTest01CppTest01.vcxproj" (default targets).


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

Time Elapsed 00:00:00.21

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:

  1. You can set this property as an environment variable
  2. You can use another technique, ImportBefore & ImportAfter which is specific to 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 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)PlatformsWin32ImportBefore*.targets" 
Condition="Exists('$(VCTargetsPath)PlatformsWin32ImportBefore')" />

Then there is one towards the bottom

<Import Project="$(VCTargetsPath)PlatformsWin32ImportAfter*.targets" 
Condition="Exists('$(VCTargetsPath)PlatformsWin32ImportAfter')" />

A similar import declaration exists for the other target platforms as well. Take a look at the files at %ProgramFiles32%MSBuildMicrosoft.Cppv4.0Platforms for the specific names.

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...