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.