Quick Help on VS2010 Custom Build Rule

Hi my name is Li Shao. I am a Software Design Engineer in Test for the C++ team. In my earlier blog “Visual Studio 2010 C++ Project Upgrade Guide”, I have mentioned about the change of Custom build Rules in VS2010. In this post, I would like to explain in more detail of the new format of the Custom Build Rules and some of its limitations in VS2010.

Custom build rule is a build feature introduced in VS2005. It provides the ability for the users to easily Plug-In third party tools to use in their build process. The custom build rule is defined by “.rules” files. Rules for MASM (Microsoft Micro Assembler) and LIC (License Compiler) are shipped in the box for VS2005 and VS2008.  

In VS2010, due to the migration to MSBuild, the information in the rules file is represented by three files: .XML, .props and .targets files. The XML file defines the property and switch mapping. The props file initializes the property values and the targets file generates the task based on the XML file and has the build logic. MASM and LIC custom build rules are also shipped in VS2010 with this new format. In the next couple of paragraphs, I will use MASM rule as an example to explain some important parts of the new custom build rule format and hope to give you some ideas on how to read custom build rule files if you need to.

 MASM custom build rule is available at %ProgramFiles%MSBuildMicrosoft.Cppv4.0BuildCustomizations or %ProgramFiles(x86)%MSBuildMicrosoft.Cppv4.0BuildCustomizations on x64 machine. You have the following in the MASM.XML file. 

<BoolProperty

      Name=GenerateDebugInformation

      HelpUrl=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vclrfml.asp

      DisplayName=Generate Debug Information

      Description=Generates Debug Information.     (/Zi)

      Switch=/Zi />

 

With this XML file definition, “GenerateDebugInformation” is mapped to /Zi

In the file MASM.Props, “GenerateDebugInformation” is initialized to “True” (see highlighted line below)

<ItemDefinitionGroup>

  <MASM>

    <NoLogo>true</NoLogo>

    <GenerateDebugInformation>true</GenerateDebugInformation>

    <ObjectFileName>$(IntDir)%(FileName).obj</ObjectFileName>

    <PreserveIdentifierCase>0</PreserveIdentifierCase>

    <WarningLevel>3</WarningLevel>

    <PackAlignmentBoundary>0</PackAlignmentBoundary>

    <CallingConvention>0</CallingConvention>

    <ErrorReporting>0</ErrorReporting>

    <CommandLineTemplate Condition=‘$(Platform)’ == ‘Win32’>ml.exe /c [AllOptions] [AdditionalOptions] /Ta[Inputs]</CommandLineTemplate>

    <CommandLineTemplate Condition=‘$(Platform)’ == ‘X64’>ml64.exe /c [AllOptions] [AdditionalOptions] /Ta[Inputs]</CommandLineTemplate>

    <CommandLineTemplate Condition=‘$(Platform)’ != ‘Win32’ and ‘$(Platform)’ != ‘X64’>echo MASM not supported on this platform</CommandLineTemplate>

    <ExecutionDescription>Assembling [Inputs]…</ExecutionDescription>

  </MASM>

</ItemDefinitionGroup>

 

The MASM.XML file is imported by the MASM.targets file. MSBuild relies on the Task Generator to generate the task for the custom build rule.

<UsingTask

    TaskName=MASM

    TaskFactory=XamlTaskFactory

    AssemblyName=Microsoft.Build.Tasks.v4.0>

  <Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>

</UsingTask>

 

The values initialized in MASM.props file is also passed to the targets:

<MASM

      GenerateDebugInformation=%(MASM.GenerateDebugInformation)

      Inputs=%(MASM.Identity) />

 

The build logic is in the .targets file as well. For example, these lines define the inputs and outputs for MASM:

Outputs=%(MASM.ObjectFileName)

Inputs=%(MASM.Identity);%(MASM.AdditionalDependencies);$(MSBuildProjectFile)

This defines what outputs from MASM need to be passed to Linker/Lib:

<Target

    Name=ComputeMASMOutput

    Condition=‘@(MASM)’ != ”>

  <ItemGroup>

    <Link Include=@(MASM->Metadata(‘ObjectFileName’)->Distinct()->ClearMetadata()) Condition=‘%(MASM.ExcludedFromBuild)’ != ‘true’/>

    <Lib Include=@(MASM->Metadata(‘ObjectFileName’)->Distinct()->ClearMetadata()) Condition=‘%(MASM.ExcludedFromBuild)’ != ‘true’/>

  </ItemGroup>

</Target >

 

MASM.props and MASM.targets file are imported by project files (.vcxproj) if the custom build rule for MASM is enabled.

<ImportGroup Label=ExtensionSettings>

    <