MS Build

  • Standard Path:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin

Typical Structure

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup></PropertyGroup>
 <ItemGroup></ItemGroup>
 <Target Name="MyTarget">
   <Message Text="Hello" Importance="high" />
 </Target>
</Project>

Message is a task similar to an 'Echo'.

Special Characters

  • %: Metadata

  • $: Properties

  • @: Elements (Items)

  • ': Conditions

  • ;: List separators

Escaping:

<Compile Include="MyFile.cs;MyClass.cs"/>  --> <Compile Include="MyFile.cs%3BMyClass.cs"/>
<Compile Include="$([MSBuild]::Escape('MyFile.cs;MyClass.cs'))" />

Typical Properties

  • Properties are not case-sensitive

Setting Properties

  • Setting via Property Group:

    <PropertyGroup>
       <BuildDir>Build</BuildDir>
    </PropertyGroup>
  • Setting via msbuild.exe

    msbuild.exe MyProj.proj -p:BuildDir=Build
    msbuild file.proj -p:Flavor=Debug;Platform=x86
  • Property Groups can also be defined within the targets.

  • A property can also be an XML node.

  • Priority:

    1. PropertyGroup with attribute 'TreatAsLocalProperty'

    2. MSBuild parameters

    3. Environment variables

    4. PropertyGroup

Reading Properties

  • Reading via '$(Property)'

  • Registry: $(registry:Hive\MyKey\MySubKey@Value))

  • Property functions: $([System.DateTime]::Now.ToString("yyyy.MM.dd")) - Link

Relevant Property Functions:
  • Path combination: $([System.IO.Path]::Combine($(MSBuildProjectDirectory), `BuildInfo.txt`))

  • Ensuring trailing slash: $([MSBuild]::EnsureTrailingSlash($(path)))

Transforming

Based on meta-information:

@(RESXFile->'%(filename).resources') -> a.resx --> a.resources

Conditional Evaluation

  • Setting default values:

    <BuildDir Condition="'$(BuildDir)' == ''">c:\tools</BuildDir>

Predefined Properties:

  • $(MSBuildProjectDirectory): Path of the project file without the file itself

  • $(MSBuildProjectFullPath): Path of the project file including the file

  • $(MSBuildProjectName): Name of the MSBuild file without extension.

  • $(OutputPath): Output path of Visual Studio

Typical Elements (Items)

Setting

Setting elements:

<ItemGroup>
   <Compile Include = "file1.cs"/>
   <Compile Include = "file2.cs"/>
</ItemGroup>

Alternative:

<ItemGroup><Compile Include = "file1.cs;file2.cs"/></ItemGroup>

Wildcards:

<VBFile Include="D:/**/*.vb"/>
<VBFile Include="D:/**/*.vb" Exclude="Settings.vb"/>

With metadata:

<ItemGroup>
   <CSFile Include="one.cs;two.cs">
       <Culture>Fr</Culture>
   </CSFile>
</ItemGroup>

Reading

Reading elements:

@(Compile) ==> file1.cs;file2.cs

Evaluating metadata: Standard Metadata

<Target Name="Batching">
      <Message Text="@(CSFile)" Condition=" '%(Culture)' == 'Fr' "/>
</Target>

Transformation using metadata:

@(CppFiles -> '%(Filename).obj')

Removing elements (only allowed within a target):

<Target Name="RemoveConfig">
   <ItemGroup><Compile Remove="*.config"/></ItemGroup>
</Target>

Item Functions:

@(Compile->IndexOf('.')) ==> 3;5 (depending on position)

Relevant functions:

  1. →Count()

  2. →IndexOf()

  3. →Replace('a', 'b')

Targets

<Target Name="Construct">
   <Csc Sources="@(Compile)" />
</Target>
  • A target is executed at most once

Definition and Order of Targets

  • First target: If nothing is specified, the first target is executed.

  • InitialTargets: As an attribute in Project. Always executed.

    <Project InitialTargets="Warm;Eject" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  • DefaultTargets: If nothing is specified via msbuild.exe, this is executed.

    <Project DefaultTargets="Warm;Eject" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  • BeforeTargets, AfterTargets: Can be used to define an order.

  • DependsOnTargets: Specifies the targets that must be executed before.

Standard Targets

  • BeforeBuild: Before building

  • Build: The standard build target

  • AfterBuild: After building

Tasks

  • Interface ITask in Microsoft.Build.Framework

  • Pre-implementation Task in Microsoft.Build.Utilities.dll

  • Importing new tasks:

    <UsingTask TaskName="Microsoft.Build.Tasks.ResolveNativeReference" AssemblyName="Microsoft.Build.Tasks.Core" />
    <UsingTask TaskName="SimpleTask3.SimpleTask3" AssemblyFile="SimpleTask3\bin\debug\simpletask3.dll"/>
  • Inline Task Definition

  • Ignoring errors:

    <Delete Files="@(Files)" ContinueOnError="WarnAndContinue"/>

Typical Tasks

Message to the console:

<Target Name="LogBuildDir"><Message Text="$(BuildDir)" Importance="high"/></Target>

Creating a directory:

<MakeDir Directories = "$(BuildDir)" Condition = "!Exists('$(BuildDir)')" />

Removing a directory:

<RemoveDir Directories="$(BuildDir)" />

Miscellaneous

  • Importing elements

    <Import Project="Other.targets" />