MSBuild ExampleΒΆ

The _build element that comes with Sake is written to use MSBuild 4.0. If your source code uses features of C# 5 or 6, this may not work. For example, when building an application that uses string interpolation, which was added in C# 6, the build fails indicating that $ is an unexpected character.

This example shows a custom element, based on _build, which uses MSBuild 14.0 (VS 2015, C# 6) or MSBuild 12.0 (VS 2012/13, C# 5).

The solution that this example builds can be found along with the other files on github. Note in the example makefile.shade, the output directory is relative the .csproj files.

build.cmd:

@echo off
cd %~dp0

SETLOCAL
SET NUGET_VERSION=latest
SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe

IF EXIST "%CACHED_NUGET%" goto copynuget
echo Downloading latest version of NuGet.exe...

IF NOT EXIST "%LocalAppData%\NuGet" md "%LocalAppData%\NuGet"
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'"

:copynuget
IF EXIST .nuget\nuget.exe goto restore
md .nuget
copy "%CACHED_NUGET%" .nuget\nuget.exe > nul

:restore
IF EXIST packages\Sake goto run
.nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages

:run
packages\Sake\tools\Sake.exe -I imports -f makefile.shade %*

_msbuild.shade saved to the imports directory:

@{/*

build 
    Executes msbuild to compile your project or solution

projectFile='' 
    Required. Path to the project or solution file to build.

configuration='Release'
    Determines which configuration to use when building.

outputDir=''
    Directs all compiler outputs into the target path. Note:  this will be relative to the project files (not the solution file if building a solution).

extra=''
    Additional commandline parameters for msbuild

*/}

default configuration='Release'
default outputDir=''
default extra=''

use namespace="System"
use namespace="System.IO"
use namespace="System.Reflection"

var buildProgram=''

@{
   Assembly buildUtilities = null;
   string toolsVersion = null;

   try
   {
      buildUtilities = Assembly.Load("Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
      toolsVersion = "14.0";
   }
   catch
   {
      buildUtilities = Assembly.Load("Microsoft.Build.Utilities.v12.0, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
      toolsVersion = "12.0";
   }

   var helper = buildUtilities.GetType("Microsoft.Build.Utilities.ToolLocationHelper");
   var method = helper.GetMethod("GetPathToBuildTools", new Type[] { typeof(string) } );
   var path = method.Invoke(helper, new object[] { toolsVersion }).ToString();

   buildProgram = Path.Combine(path, "msbuild.exe");
}

var OutDirProperty=''
set OutDirProperty='OutDir=${outputDir}${Path.DirectorySeparatorChar};' if='!string.IsNullOrWhiteSpace(outputDir)'

exec program="${buildProgram}" commandline='${projectFile} "/p:${OutDirProperty}Configuration=${configuration}" ${extra}'

makefile.shade:

#default .build

#clean
   msbuild projectFile="src/SakeMsBuild.sln" outputDir="../../output" extra="/t:Clean"

#build .clean
   msbuild projectFile="src/SakeMsBuild.sln" outputDir="../../output" extra="/t:Rebuild /m"

Output:

../_images/msbuild.jpg