MSBuild: введение в файл проекта — Properties, Targets

Автор: | 12/04/2015
 

msbuild_logoКраткий перевод из книги Inside the Microsoft Build Engine.

Файл MSBuild — простой XML-файл, который так же называется «файл проекта MSBuild» (MSBuild project file).

Файл описан двумя XSD-файлами (XML Schema Definition) — Microsoft.Build.Commontypes.xsd и Microsoft.Build.Core.xsd, которые расположены в каталоге c:WindowsMicrosoft.NETFramework64v4.0.30319MSBuild:

> dir c:WindowsMicrosoft.NETFramework64v4.0.30319MSBuild /b
Microsoft.Build.Commontypes.xsd
Microsoft.Build.Core.xsd

Все данные файла проекта должны располагаться внутри элемента <Project>.

При сборке проекта требуется точно знать две вещи — что именно будет собираться, и какие параметры для сборки будут использоваться. Как правило — результатом билда являются файлы, и их мы будем описывать в элементах (items). Параметры сборки, такие как Configuration или OutputPath, будут располагаться в свойствах (properties).

Properties

Свойства (properties) в файле MSBuild — это пары ключ:значение. Ключ — это имя, которое будет использоваться для ссылки к свойству.

Для объявления свойства — его необходимо поместить внутри элемента PropertyGroup, который расположен в элементе Project.

Напрмиер — создадим файл Hello.csproj:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<Property1>value1</Property1>
		<Property2>value2<Property2>
	</PropertyGroup>
</Project>

Тут мы создали два свойства — Property1 и Property2, со значениями value1 и value2 соответственно, которые заключены в элементе PropertyGroup, который, в свою очередь, расположен внутри элемента Project.

Можно создавать несколько групп PropertyGroup. Например — можно переписать пример выше так:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<Property1>value1</Property1>
	</PropertyGroup>
	<PropertyGroup>
		<Property2>value2</Property2>
	</PropertyGroup>
</Project>

Targets (цели)

MSBuild использует два типа элементов для выполнения — задача (task) и цель (target). Task — самый маленький элемент для работы в файле MSBuild, а target — это набор task.

Task всегда должны располагаться внутри элемента Target, но их мы рассмотрим позже.

Дополним наш файл новой целью HelloWorld:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<Property1>value1</Property1>
	</PropertyGroup>
	<PropertyGroup>
		<Property2>value2</Property2>
	</PropertyGroup>

	<Target Name="HelloWorld">
	</Target>
</Project>

В данном случае — этот target не содержит ни одной задачи для выполнения, но MSBuild имеет огромное количество предустановленных задач, полный список которых можно найти тут>>>.

Сейчас мы используем задачу Message. Каждая задача может принимать определённые аргументы, в данном случае для Message мы можем использовать Text:

<Target Name="HelloWorld">
		<Message Text="Hello world!" />
</Target>

Запуск MSBuild

Исполняемый файл MSBuild — MSBuild.exe, находится в каталоге C:WindowsMicrosoft.NETFramework64v4.0.30319.

Добавляем его в PATH (при работе из Visual Studio этого делать не надо, но в данном случае — задача собрать проект без VS, на билд-агенте CI сервера TeamCity):

> setPATH=%PATH%;C:WindowsMicrosoft.NETFramework64v4.0.30319

Проверяем:

> msbuild /h

Синтаксис использования MSBuild выглядит так:

msbuild [INPUT_FILE] /t:[TARGETS_TO_EXECUTE]

Что бы вызвать задачу HelloWorld из файла проекта MSBuild Hello.csproj — выполняем:

> msbuild Hello.csproj /t:HelloWorld
Microsoft (R) Build Engine version 4.0.30319.33440
[Microsoft .NET Framework, version 4.0.30319.34014]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 4/8/2015 2:01:46 PM.
Project "d:Temp3Hello.csproj" on node 1 (HelloWorld target(s)).
HelloWorld:
  Hello world!
Done Building Project "d:Temp3Hello.csproj" (HelloWorld target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.02

Что бы убрать из вывода информацию о версиях — можно добавить /nologo:

> msbuild Hello.csproj /t:HelloWorld /nologo
Build started 4/8/2015 2:02:29 PM.
Project "d:Temp3Hello.csproj" on node 1 (HelloWorld target(s)).
HelloWorld:
  Hello world!
Done Building Project "d:Temp3Hello.csproj" (HelloWorld target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.02

Targets (цели) и Properties (свойства)

Теперь — объединим использование Properties и Targets.

Отредактируем файл:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

	<PropertyGroup>
		<HelloMessage>Hello from property</HelloMessage>
	</PropertyGroup>

	<Target Name="HelloProperty">
		<Message Text="$(HelloMessage)" />
	</Target>

</Project>

Мы создали новое группу свойств, в которой добавлено свойство с именем HelloMessage и значением «Hello from property«.

Затем — мы добавили новую цель с именем HelloProperty, которая получает значение свойства HelloMessage с помощью переменной вида $(PropertyName), в данном случае — $(HelloMessage).

Выполняем:

> msbuild Hello.csproj /t:HelloProperty /nologo
Build started 4/8/2015 2:09:42 PM.
Project "d:Temp3Hello.csproj" on node 1 (HelloProperty target(s)).
HelloProperty:
  Hello from property
Done Building Project "d:Temp3Hello.csproj" (HelloProperty target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.02

В значении свойства можно использовать значение другого, уже заданного, свойства, например:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

	<PropertyGroup>
		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
		<DeployLocation>https://urlserver.com/$(Configuration)/$(Platform)</DeployLocation>
	</PropertyGroup>

	<Target Name="PrepareFilesForDeploy">
		<Message Text="DeployLocation : $(DeployLocation)" />
	</Target>

</Project>

Тут мы создаём три Property — ConfigurationPlatform и DeployLocation. Для Configuration и Platform используется атрибут Condition, который мы рассмотрим позже, и который так же описан тут>>>.

А свойство DropLocation имеет значение, состоящее из трёх частей — константа, описывающая URL, и значения свойств Configuration  и Platform:

<DeployLocation>https://urlserver.com/$(Configuration)/$(Platform)</DeployLocation>

Когда MSBuild встречает выражение вида $(PropertyName) — она заменяет его значением указанного в скобках свойства.

Запускаем:

> msbuild Hello.csproj /t:PrepareFilesForDeploy /nologo
Build started 4/8/2015 4:31:08 PM.
Project "d:Temp3Hello.csproj" on node 1 (PrepareFilesForDeploy target(s)).
PrepareFilesForDeploy:
  DeployLocation : https://urlserver.com/Debug/AnyCPU
Done Building Project "d:Temp3Hello.csproj" (PrepareFilesForDeploy target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.02

В следующей части — мы рассмотрим Task.