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:
-
PropertyGroup with attribute 'TreatAsLocalProperty'
-
MSBuild parameters
-
Environment variables
-
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:
Full list at: https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2019
-
$(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:
-
→Count()
-
→IndexOf()
-
→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"/>
-
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" />