MSBuild Task

MSBuild Task

Rate This
  • Comments 13

Hello again! My name is Li Shao. I am a Software Design Engineer in Test in the Visual C++ group.

As one of my colleagues, Marian Luparu, has blogged in detail about, and Soma has mentioned in his recent blog as well, one of the important features we have in VS2010 is to enable C++ customers to build C++ applications using MSBuild. MSBuild (Microsoft Build Engine) is an extensible, XML-based build engine first shipped with Visual Studio 2005 and the .NET Framework 2.0. It is a core part of .NET Framework 2.0/3.0/3.5. It gives developers full control of their build process and provides a new XML based project file format. .NET languages such as Visual Basic (VB) and Visual C# (VC#) have migrated to MSBuild as their project and build systems in Visual Studio 2005.

Currently, C++ uses its own build system: VCBuild. VCBuild and MSBuild have many differences. Here are a couple of key differences:

1.     The Build logic in MSBuild is expressed in MSBuild target files which are accessible by the end uses. The build logic for VCBuild is encapsulated inside the binaries.

2.     VCBuild is made specific for building C++ application. MSBuild on the other hand, is more flexible and extensible. It can be extended to accomplish many different tasks without changes to MSBuild engine.

Over the last year, I’ve spent most of my time working in a team tasked to migrate the C++ build system from VCBuild to MSBuild. A large chuck of the work we need to do for this migration is to create “tasks” for all the native tools we support in VCBuild. Tasks are reusable units of executable code used by MSBuild projects to perform build operations. There’s a library of common tasks provided with MSBuild. You can take a look at this link to know what the available tasks are. You can also create your own task by authoring a managed type that implements the ITask Interface. Here is an MSDN example on how to create your own tasks.

In VCBuild, we support these set of native tools:

o   cl.exe

o   link.exe

o   lib.exe:

o   rc.exe

o   midl.exe

o   mt.exe

o   xsd.exe

o   xdcmake.exe

o   bscmake.exe

 

To have MSBuild support for building native applications, new tasks need to be made for each of the tools. These tasks map the commonly used switches or the switches currently exposed through project system property page to the properties on the tasks.

There are situations that you know what switches you would like to pass to the tools but you need to figure out what MSBuild properties to use. To find the complete mapping of the properties and their representative switches, you can take a look of the XAML files under %programfiles%\MSBuild\Microsoft.Cpp\v4.0. These XAML files express the mapping between properties and switches and their usage. Each of the XAML files represents one tool.

o   CL.XML

o   Link.XML

o   Lib.XML

o   RC.XML

o   MIDL.XML

o   MT.XML

o   XSD.XML

o   XDCMake.xml

o   BSCmake.xml

This is a snippet in CL.XML:

<StringListProperty Name="AdditionalIncludeDirectories" Category="General" Switch="I">

- <StringListProperty.DisplayName>

  <sys:String>Additional Include Directories</sys:String>

</StringListProperty.DisplayName>

- <StringListProperty.Description>

  <sys:String>Specifies one or more directories to add to the include path; separate with semi-colons if more than one. (/I[path])</sys:String>

</StringListProperty.Description>

</StringListProperty>

From here, you can see that “AdditionalDirectories” maps to switch “I”. In the project file (.vcxproj is the new MSBuild based C++ project file), you can specify:

<ClCompile>

   <AdditionalIncludeDirectories>include1;include2;include3</AdditionalIncludeDirectories>

</ClCompile>

 

It will be translated to this command line for CL:

/I:”include1” /I:”include2” /I:”include3”

We have also exposed some new switches, for example /MP. This is the XAML definition of the /MP switch

- <BoolProperty Name="MultiProcessorCompilation" Category="General" Switch="MP">

- <BoolProperty.DisplayName>

  <sys:String>Multi-processor Compilation</sys:String>

  </BoolProperty.DisplayName>

- <BoolProperty.Description>

  <sys:String>Multi-processor Compilation</sys:String>

  </BoolProperty.Description>

  <Argument Property="ProcessorNumber" IsRequired="false" />

  </BoolProperty>

- <IntProperty Name="ProcessorNumber" Category="General">

- <IntProperty.DisplayName>

  <sys:String>Number of processors</sys:String>

  </IntProperty.DisplayName>

- <IntProperty.Description>

  <sys:String>Number of processors.</sys:String>

  </IntProperty.Description>

  </IntProperty>

In you project file, you can specify:

<CLCompile>

  <MultiProcessorCompilation>true</MultiProcessorCompilation>

  <ProcessorNumber>4</ProcessorNumber>

</ClCompile>

The command line for cl will contain /MP4.

In the old project files, we use enum values to specify the properties that can take different values. For example, in old project file, you have “TargetMachine="1"” specifying “/MACHINE:X86” while in new project file, you can do the following which is more readable.

<Linker>

  <TargetMachine>MachineX86</TargetMachine>

<Linker>

In link.xml, you can see the following is part of the definition for “TargetMachine”.

<EnumProperty Name="TargetMachine" Category="Advanced">

- <EnumValue Name="MachineIA64" Switch="MACHINE:IA64">

- <EnumValue.DisplayName>

  <sys:String>MachineIA64</sys:String>

  </EnumValue.DisplayName>

  </EnumValue>

- <EnumValue Name="MachineX64" Switch="MACHINE:X64">

- <EnumValue.DisplayName>

  <sys:String>MachineX64</sys:String>

  </EnumValue.DisplayName>

   </EnumValue>

- <EnumValue Name="MachineX86" Switch="MACHINE:X86">

- <EnumValue.DisplayName>

  <sys:String>MachineX86</sys:String>

  </EnumValue.DisplayName>

   </EnumValue>

</EnumProperty>

 It defines the properties for /MACHINE:X86, /MACHINE:x64 and /MACHINE:IA64. In addition to these, “TargetMachine” also defines the properties for /MACHINE:ARM, /MACHINE:EBC, /MACHINE:MIPS, /MACHINE:MIPS16, /MACHINE:MIPSFPU, /MACHINE:MIPSFPU16, /MACHINE:SH4, /MACHINE:THUMB.

Like the old project system, the majority of the properties in the XAML files are also exposed through the property page UI in the new project system. Take “TargetMachine” as an example again, since it is defined in linker.XML as:

<EnumProperty Name="TargetMachine" Category="Advanced">

With its “Category” attribute as “Advanced”, you can expect to find “TargetMachine” at the linker tool/Advanced page.

That’s it for this blog. Hope you will find it helpful. Please let us know if you have any feedback when using MSBuild to build C++ applications.

Happy Holidays!

Li Shao

 

 

  • I am really happy to see a real build tool for VC++. GNU Make and others have been kicking VC++'s ass for quite some time now. Better later than never I guess.

  • Yes this seems like a sane idea - I seriously hope it turns out good.

    On a strongly related note: VS6 was the last great IDE for MFC/C++.  After operation Round-Peg-In-Square-Hole (VS 2003 .NET), C++ developers opting to develop with Microsoft's  latest and greatest C++ IDE were served a big ol' bowl of poo-noodles (aka poop-ghetti).  VS 2005 added a delicate, yet hearty, layer of pee sprinkles on top plus a colorful side of bear scat to round out the meal. (Kudos to the lead chef)

    I hope the VCBuild migration to MSBuild turns out positive, and not another major problem for C++ developers.

  • Looks nice!

    But when will MSBuild support vdproj (deployment projects, msi installers)?

    Without this support, I cannot use MSBuild most of the time. :(

  • 2nd comment - you cracked me up. :)

    A very amusing description of Microsoft's past work in C++!

  • What's this:

    <AdditionalIncludeDirectories>include1;include2;include3</AdditionalIncludeDirectories>

    If you are going to use XML, then use it, not some half hearted mixture.

    <AdditionalIncludeDirectories>

    <AdditionalIncludeDirectory>include1</AdditionalIncludeDirectory>

    <AdditionalIncludeDirectory>include2</AdditionalIncludeDirectory>

    <AdditionalIncludeDirectory>include3</AdditionalIncludeDirectory>

    </AdditionalIncludeDirectories>

    I agree with #3, MSBuild MUST support everything that vsbuild can, out of the box.  Otherwise we'll end up with some Frankenstein builds using makefiles/Nant and more !!

  • Is there a UI for creating your own MSBuild tasks? We use custom build rules for compiling Direct3D shaders, and there's a UI in VC++ for defining such rules. They're stored in an XML .rules file anyway, not sure what the real difference will be moving to MSBuild...

  • On the question regarding <AdditionalDirectories>: MSBuild uses XML synatx, but it is not free form XML. Instead, it defines concepts like "items" and "properties". In this case, you could define either a delimited property, or a set of items (similar to what you did). Both are possible and it's up to the author of the task that consumes the information.

    In this particular case, I believe the choice was driven by the fact that most people are familiar with entering a semi-colon delimited list in the UI. Mapping that directly to the project file was the easiest way - but either could have been done.

  • Thanks all for your comments!

    Yes, we are working hard to make sure that this migration will be a positive experience for C++ developers. We also appreciate your feedback when you try with CTP and future beta releases.

    For question about building deployment project (.vdproj), yes, that will be our supported scenario. In fact, building .vdproj is handled by solution build so it is not C++ specific. Solution build needs to make sure the output from C++ msbuild will be packaged into .msi file. We will make sure this scenario works.

    In terms of XML based project file format, we tried to make it simple yet understandable. we introduced some datatype that our XML parser can understand. For exmaple, in the "AdditionalIncludeDirectories" case,  

    <StringListProperty Name="AdditionalIncludeDirectories" Category="General" Switch="I">

    "StringList" means that you can pass multiple semicolon separated strings and each string will be passed to the switch. In addition to "AdditionalDirectories" (/I), many other properties are of this type, for example, "PreprocessorDefinitions" (/D), "ForceIncludes" (/FI), "ForceUsing" (/FU), etc.

    The Dev10 project system will be based on MSBuild. Property pages are the UI for the tasks. We will also have support for custom build rule (not supported in CTP2 build). We will provide support so that you can migrate your old custom build rule to the new custom build rule format.

    I will be going on a trip tomorrow without email access. My colleagues will try to answer the additional questions you have.

    Again, thanks for all your comments and Happy Holidays!

  • Just a side note: Did you try to get in touch with people like the CMake guys and ask them what documentation they need, what hooks they might need etc.? Would be great if VS2010 has better interop with 3rd party build tools.

    Same for the Intel guys, the Intel C++ could be also integrated better into the IDE. Just wondering whether the VS Team is pro-actively seeking contact with such developers, or whether it does its own thing just to find out later what problems arise?

  • Sorry for the delay. I just got back from vacation.

    Yes, we will have support in place for third party to create their own tasks. we are working on the implementation now.

  • In the VS 2010 CTP it appears that the IDE is using VCBuild by default for VC++, and it's necessary to patch VS to use MSBuild instead.

    When VS 2010 is released, will it use MSBuild out of the box? Also, will building with VCBuild be available as an option, or will it be completely replaced by MSBuild?

  • @Duncan

    Yes, VS2010 will use MSBuild out of the box. VCBuild.exe will be dead; all its functions will be superseded. ".vcproj" will be converted to msbuild format ".vcxproj" and ".vsprops" will be converted to msbuild format ".props". Nobody likes conversion, but obviously, the format is quite different - in my opinion, for more readable. Unfortunately we did not have time to convert the horrible .sln format, but if you are willing to write your own traversal MSBuild projects, you can treat .sln as just a VS visualization. It is very likely that .sln will be dumped next version.

    @Anonymous

    We are in contact with the Intel C++ team to help them interop smoothly

  • Hello, my name is Felix Huang and I am a developer on the Visual C++ team. Over the last year, I worked

Page 1 of 1 (13 items)