Практическое руководство. расширение процесса сборки visual studio

Implementing the Task

From my own experience, I’d recommend to keep the task assembly small and move complex logic into their own projects. This is also the approach most of the projects mentioned above have taken. Some of the most important types for custom MSBuild tasks are , , and . In order to gain access, we need to add references for them:

Note that the MSBuild references are part of every MSBuild installation and therefore should not be deployed with our final NuGet package. In order to achieve that, we set the and attribute for each reference to . We will also need to remove those references from the item group:

As already hinted, our task assembly will likely have dependencies to other projects or NuGet packages. A while back, this would have taken a huge effort:

task assemblies that have dependencies on other assemblies is really messy in MSBuild 15. Working around it could be its own blog post

Meanwhile we’re at MSBuild 16, and some of the problems that Nate described in his blog have already been addressed. I am by no means an expert in properly resolving dependencies, but Andrew Arnott came up with the – originally used in Nerdbank.GitVersion – which is working out great for many folks:

As for the actual implementation, we won’t go into too much detail but focus on the most important bits. MSBuild calls the method which will later delegate to and its return value signals whether the task succeeded or failed. The inherited property allows us to log information, warning, and error messages. Users of the task can opt-in to treat warnings of the task as errors by setting the property. The property is a required input value. The item group is optional and can contain a list of files. In many situations, a can also be a ordinary string value, like for .

Переопределение предопределенных целевых объектов

Список стандартных целевых объектов содержит набор предопределенных пустых целевых объектов, которые вызываются до и после некоторых основных целевых объектов в процессе сборки. Например, MSBuild вызывает целевой объект перед основным целевым объектом , а целевой объект  — после целевого объекта . По умолчанию пустые целевые объекты в списке стандартных целевых объектов не выполняют никаких действий, но их поведение по умолчанию можно переопределить, определив нужные целевые объекты в файле проекта, куда импортируются стандартные целевые объекты. Переопределяя предварительно заданные целевые объекты, вы можете использовать задачи MSBuild, чтобы получить больший контроль над процессом сборки.

Observação

В проектах в стиле SDK имеется неявная директива импорта целевых объектов после последней строки в файле проекта. Это означает, что переопределить целевые объекты по умолчанию можно только в том случае, если директивы импорта указаны вручную, как описано в статье Информация об использовании пакетов SDK проекта MSBuild.

Переопределение предопределенного целевого объекта

  1. Выберите в списке стандартных целевых объектов предварительно заданный целевой объект, который требуется переопределить. Приведенная ниже таблица содержит полный список целевых объектов, которые можно безопасно переопределить.

  2. Определите один или несколько целевых объектов в конце файла проекта, прямо перед тегом . Пример:

  3. Выполните сборку файла проекта.

В приведенной ниже таблице представлены все стандартные целевые объекты, которые можно безопасно переопределить.

Имя целевого объекта Описание
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после основной компиляции. Основная часть настроек выполняется в одном из этих двух целевых объектов.
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после остальной части сборки. Примечание. Целевые объекты и уже определены в комментариях в конце большинства файлов проекта, поэтому вы можете легко добавлять события до и после сборки в файл проекта.
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после вызова основной функции перестроения. В Microsoft.Common.targets действует следующий порядок выполнения целевых объектов: , , , а затем .
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после вызова основной функции очистки.
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после вызова основной функции публикация.
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после разрешения ссылок на сборки.
, Задачи, добавленные в один из этих целевых объектов, выполняются до или после создания ресурсов.

Структура встроенной задачи

Элемент UsingTask содержит встроенную задачу. Встроенная задача и содержащий ее элемент обычно включены в TARGETS-файл и при необходимости импортируются в другие файлы проекта. Ниже представлен пример обычной встроенной задачи

Обратите внимание, что в нем не предусмотрено выполнение каких-либо действий

Элемент в примере включает три атрибута, описывающих задачу и фабрику встроенной задачи, компилирующую ее.

  • Атрибут содержит имя задачи. В примере используется имя — .

  • Атрибут содержит класс, реализующий фабрику встроенной задачи.

  • Атрибут включает расположение фабрики встроенной задачи. Вы также можете использовать атрибут для указания полного имени класса фабрики встроенной задачи, который обычно расположен в .

Остальные элементы задачи пусты и приведены, чтобы показать порядок и структуру встроенной задачи. Более сложный пример представлен в этой статье далее.

  • Элемент является необязательным. Если он все же используется, его функция заключается в указании параметров задачи. Дополнительные сведения о входных и выходных параметрах см. в разделе ниже.

  • Элемент содержит исходный код задачи и описывает его.

  • Элемент указывает ссылки на сборки .NET, используемые в коде. Это эквивалентно добавлению ссылки в проект в Visual Studio. Атрибут задает путь к сборке, на которую указывает ссылка.

  • Элемент необходим для вывода списка пространств имен, к которым нужно получить доступ. Он похож на оператор в Visual C#. Атрибут указывает пространство имен, которое нужно включить.

Элементы и подходят для любого языка. Встроенные задачи можно написать на любом из поддерживаемых языков .NET CodeDom, например Visual Basic или Visual C#.

Observação

Элементы, содержащиеся в элементе , характерны для фабрики задачи, в этом случае для фабрики кода задачи.

Code, элемент

Последний дочерний элемент в элементе  — . Элемент содержит код, который нужно скомпилировать в задачу, или определяет его местонахождение. Содержимое в элементе зависит от того, каким образом вы хотите написать задачу.

Атрибут указывает язык, на котором написан код. Допустимые значения: для C# и для Visual Basic.

Атрибут указывает тип кода, находящийся в элементе .

  • Если значением атрибута является , элемент содержит код для класса, производного от интерфейса ITask.

  • Если значением атрибута является , код определяет переопределение метода интерфейса ITask.

  • Если значением атрибута является , тогда код определяет содержимое метода , а не сигнатуру или оператор .

Сам код отображается, как правило, между метками и . Так как код размещается в разделе CDATA, вам не нужно беспокоиться об экранировании зарезервированных знаков, например <» or «>.

Вы также можете использовать атрибут элемента , чтобы указать расположение файла, содержащего код для задачи. Код в исходном файле должен иметь тип, заданный атрибутом . Если есть атрибут , тогда по умолчанию значением атрибута является . Если атрибут отсутствует, значением по умолчанию будет .

Observação

При определении класса задачи в исходном файле имя класса должно быть согласовано с атрибутом соответствующего элемента UsingTask.

Target framework and profile

A target framework is the particular version of the .NET Framework that your project is built to run on. Specification of a target framework is required because it enables compiler features and assembly references that are exclusive to that version of the framework.

Currently, the following versions of the .NET Framework are available for use:

  • The .NET Framework 2.0 (included in Visual Studio 2005)

  • The .NET Framework 3.0 (included in Windows Vista)

  • The .NET Framework 3.5 (included in Visual Studio 2008)

  • The .NET Framework 4.5.2

  • The .NET Framework 4.6 (included in Visual Studio 2015)

  • The .NET Framework 4.6.1

  • The .NET Framework 4.6.2

  • The .NET Framework 4.7

  • The .NET Framework 4.7.1

  • The .NET Framework 4.7.2

  • The .NET Framework 4.8

The versions of the .NET Framework differ from one another in the list of assemblies that each makes available to reference. For example, you cannot build Windows Presentation Foundation (WPF) applications unless your project targets the .NET Framework version 3.0 or above.

The target framework is specified in the property in the project file. You can change the target framework for a project by using the project property pages in the Visual Studio integrated development environment (IDE). For more information, see How to: Target a version of the .NET Framework. The available values for are , , , , , , , , , , and .

A target profile is a subset of a target framework. For example, the .NET Framework 4 Client profile does not include references to the MSBuild assemblies.

Note

Target profiles apply only to portable class libraries.

The target profile is specified in the property in a project file. You can change the target profile by using the target-framework control in the project property pages in the IDE.

MSBuild GetPathOfFileAbove

Функция свойства MSBuild выполняет поиск каталога, содержащего указанный файл, начиная с указанного каталога включительно. Она возвращает полный путь к ближайшему совпадающему файлу, если он найден. В противном случае — пустую строку.

Эта функция свойства использует следующий синтаксис.

 — имя искомого файла, а  — необязательный каталог для начала поиска. По умолчанию поиск начнется в собственном каталоге текущего файла.

В этом примере показано, как импортировать файл с именем dir.props в текущий каталог или выше, только если найдено совпадение:

функционально эквивалентно

Однако иногда необходимо начать поиск в родительском каталоге, чтобы избежать совпадения с текущим файлом. В этом примере показано, как файл Directory.Build.props может импортировать ближайший файл Directory.Build.props на более высоком уровне дерева без рекурсивного импорта самого себя:

функционально эквивалентно

Элементы и атрибуты

В следующих разделах описаны атрибуты, дочерние и родительские элементы.

Атрибуты

Атрибут Описание
Необязательный атрибут. Целевой объект или объекты по умолчанию служат точкой входа сборки, если целевой объект не указан. Несколько целевых объектов разделяются точкой с запятой (;). Если целевой объект по умолчанию не указан в атрибуте или командной строке MSBuild, обработчик выполняет первый целевой объект в файл проекта после вычисления элементов Импорт.
Необязательный атрибут. Исходный целевой объект или объекты, выполняемые до целевых объектов, заданных в атрибуте или в командной строке. Несколько целевых объектов разделяются точкой с запятой (). Если несколько импортированных файлов определяют , все упомянутые целевые объекты будут выполняться в том порядке, в котором встречаются операции импорта.
Необязательный атрибут. Имя и (необязательно) версия пакета SDK для создания неявных операторов import, которые добавляются в PROJ-файл. Если версия не указана, MSBuild будет пытаться использовать версию по умолчанию. Например, или .
Необязательный атрибут. Версия набора инструментов MSBuild используется для определения значений $(MSBuildBinPath) и $(MSBuildToolsPath).
Необязательный атрибут. Имена свойств, которые не будут относиться к глобальным. Этот атрибут запрещает определенным свойствам командной строки переопределять значения свойств, заданные в файле проекта или целевых объектов и всех последующих операциях импорта. Несколько свойств разделяются точкой с запятой (;). Как правило, глобальные свойства переопределяют значения свойств, заданных в файле проекта или целевых объектов. Если свойство указано в значении , значение глобального свойства не переопределяет значения свойств, заданные в этом файле и всех последующих операциях импорта. Дополнительные сведения см. в практическом руководстве по сборке одинаковых исходных файлов с различными параметрами. Примечание. Чтобы задать глобальные свойства из командной строки, используйте параметр -property (или -p). Кроме того, вы можете задать или изменить глобальные свойства для дочерних проектов в сборках нескольких проектов, используя атрибут задачи MSBuild. Дополнительные сведения см. в разделе Задача MSBuild.
Необязательный атрибут. Если он указан, атрибут должен иметь значение .

Дочерние элементы

Элемент Описание
Choose Необязательный элемент. Вычисляет дочерние элементы для выбора одного набора элементов и/или элементов для вычисления.
Импорт Необязательный элемент. Позволяет файлу проекта импортировать другой файл проекта. Проект может содержать любое число элементов , включая ноль.
ImportGroup Необязательный элемент. Содержит коллекцию элементов , сгруппированных по необязательному условию.
ItemGroup Необязательный элемент. Группирующий элемент для отдельных элементов. Элементы указываются с помощью элемента Item. Проект может содержать любое число элементов , включая ноль.
ItemDefinitionGroup Необязательный элемент. Позволяет определить набор определений элементов, которые представляют собой значения метаданных, по умолчанию применяемых ко всем элементам проекта. Элемент ItemDefinitionGroup используется вместо задач и .
ProjectExtensions Необязательный элемент. Предоставляет способ сохранения данных, не относящихся к MSBuild, в файле проекта MSBuild. Проект может содержать один элемент или ни одного такого элемента.
PropertyGroup Необязательный элемент. Группирующий элемент для отдельных свойств. Свойства задаются с помощью элемента Property. Проект может содержать любое число элементов , включая ноль.
Sdk Необязательный элемент. Ссылки на пакет SDK проекта MSBuild. Этот элемент может использоваться в качестве альтернативы атрибуту Sdk.
Цель Необязательный элемент. Содержит набор задач для MSBuild для последовательного выполнения. Задачи указываются с помощью элемента Task. Проект может содержать любое число элементов , включая ноль.
UsingTask Необязательный элемент. Предоставляет способ регистрации задач в MSBuild. Проект может содержать любое число элементов , включая ноль.

Wiring the Task

In this next step we’ll wire up the task implementation in a file, which will be included in our NuGet package and automatically loaded from a referencing project. In this file – here we’ll load the task assembly, create a new XML task element, define a couple default values, and create a new target that calls the task:

Defining the (Line 5) does not only help us to not repeat ourselves when we reference multiple tasks from the same assembly (Line 8), but is also great for debugging, as we’ll see later. Also note that we’re using a couple of well-known MSBuild properties like and to avoid magic strings being scattered around our file. Following best practices makes renaming or relocating the task more effortless! The task invocation also uses the property (Line 18) – one of the common properties available to all task elements.

Настройка сборки решения

Importante

Подобная настройка сборки решения применяется только к сборкам из командной строки с MSBuild.exe. Она не применяется к сборкам внутри Visual Studio. По этой причине не рекомендуется размещать настройки на уровне решения. Лучшим вариантом для настройки всех проектов в решении является использование файлов Directory.Build.props и Directory.Build.targets в папке решения, как описано в других разделах этой статьи.

Когда система MSBuild выполняет сборку файла решения, она сначала внутренне преобразует его в файл проекта и затем выполняет его сборку. Созданный файл проекта импортирует до определения каких-либо целевых объектов и после их импорта, включая целевые объекты, установленные в каталоги и .

Например, можно определить новый целевой объект для записи настраиваемого сообщения журнала после сборки MyCustomizedSolution.sln, создав в том же каталоге файл after.MyCustomizedSolution.sln.targets, содержащий следующее:

Сборка решения выполняется отдельно, поэтому заданные здесь параметры не влияют на сборку проекта.

Настройка сборок C++

В проектах C++ рассматриваемые выше файлы с расширениями .targets и .props нельзя использовать для переопределения параметров по умолчанию тем же способом. Файл Directory.Build.props импортируется файлом Microsoft.Common.props, который импортируется в . При этом большинство параметров по умолчанию определяется в файле Microsoft.Cpp.props и для некоторых свойств нельзя использовать условие «если еще не определено», поскольку такие свойства уже определены, а для конкретных свойств проекта, определенных в с , значения по умолчанию должны отличаться (см. описание структуры файлов с расширением .vcxproj и .props).

Тем не менее вы можете использовать следующие свойства, чтобы задать автоматический импорт файлов с расширением .props до или после файлов Microsoft.Cpp.* .

  • ForceImportAfterCppDefaultProps
  • ForceImportBeforeCppProps
  • ForceImportAfterCppProps
  • ForceImportBeforeCppTargets
  • ForceImportAfterCppTargets

Чтобы настроить значения свойств по умолчанию для всех сборок C++, необходимо создать еще один файл .props (например, MyProps.props) и определить свойство в файле , указывающем на него.

Файл MyProps.props будет автоматически импортироваться после файла Microsoft.Cpp.props.

Item metadata

Items may contain metadata in addition to the information gathered from the Include and Exclude attributes. This metadata can be used by tasks that require more information about items than just the item value.

Item metadata is declared in the project file by creating an element with the name of the metadata as a child element of the item. An item can have zero or more metadata values. For example, the following CSFile item has Culture metadata with a value of «Fr»:

To get the metadata value of an item type, use the following syntax, where ItemType is the name of the item type and MetaDataName is the name of the metadata:

To examine item metadata:

  1. From the code editor, replace the Message task with this line:

  2. Save the project file.

  3. From the Command Window, enter and execute this line:

  4. Examine the output. You should see these lines:

Notice how the phrase «Compile.DependentUpon» appears several times. The use of metadata with this syntax within a target causes «batching». Batching means that the tasks within the target are executed once for each unique metadata value. This is the MSBuild script equivalent of the common «for loop» programming construct. For more information, see Batching.

Well-known metadata

Whenever an item is added to an item list, that item is assigned some well-known metadata. For example, %(Filename) returns the file name of any item. For a complete list of well-known metadata, see Well-known item metadata.

To examine well-known metadata:

  1. From the code editor, replace the Message task with this line:

  2. Save the project file.

  3. From the Command Window, enter and execute this line:

  4. Examine the output. You should see these lines:

By comparing the two examples above, you can see that while not every item in the Compile item type has DependentUpon metadata, all items have the well-known Filename metadata.

Metadata transformations

Item lists can be transformed into new item lists. To transform an item list, use the following syntax, where <ItemType> is the name of the item type and <MetadataName> is the name of the metadata:

For example, an item list of source files can be transformed into a collection of object files using an expression like . For more information, see Transforms.

To transform items using metadata:

  1. From the code editor, replace the Message task with this line:

  2. Save the project file.

  3. From the Command Window, enter and execute this line:

  4. Examine the output. You should see this line:

Notice that metadata expressed in this syntax does not cause batching.

Запуск

MSBuild можно вызывать из Visual Studio с помощью объектной модели MSBuild в Microsoft.Build.dll или путем вызова исполняемого файла непосредственно в командной строке или в сценарии, например в системах CI. В любом случае входные данные, влияющие на процесс сборки, включают файл проекта (или объект проекта, внутренний для Visual Studio), возможно, файл решения, переменные среды и параметры командной строки или их эквиваленты объектной модели. На этапе запуска параметры командной строки или эквиваленты объектной модели используются для настройки параметров MSBuild, таких как параметры средств ведения журнала. Свойства, заданные в командной строке с помощью параметра или , задаются как глобальные свойства, которые переопределяют все значения, которые будут установлены в файлах проекта, даже если файлы проекта считываются позже.

В следующих разделах содержатся сведения о входных файлах, таких как файлы решений или файлы проектов.

Проекты и решения

Экземпляры MSBuild могут состоять из одного проекта или нескольких проектов в составе решения. Файл решения не является XML-файлом MSBuild, но MSBuild интерпретирует его для получения сведений о проектах, которые должны быть созданы для заданной конфигурации и параметров платформы. Когда MSBuild обрабатывает эти входные данные XML, это называется сборкой решения. Он имеет несколько расширяемых точек, которые позволяют выполнять какие-либо действия во всех сборках решения, но поскольку эта сборка является отдельным запуском из сборок отдельных проектов, никакие настройки свойств или целевых определений из сборки решения не важны для каждой отдельной сборки проекта.

Дополнительные сведения о том, как расширить сборку решения, можно найти в разделе .

Сборки Visual Studio и сборки MSBuild.exe

Имеется ряд существенных различий между сборкой проектов в Visual Studio и при вызове MSBuild напрямую либо с помощью исполняемого файла MSBuild, либо при использовании объектной модели MSBuild для запуска сборки. Visual Studio управляет порядком сборки проекта для сборок Visual Studio. Он вызывает только MSBuild на уровне отдельного проекта. Когда это происходит, задаются несколько логических свойств ( и ), которые значительно влияют на то, что делает MSBuild. Внутри каждого проекта выполнение происходит так же, как при вызове с помощью MSBuild, но отличается для проектов, на которые имеются ссылки. В MSBuild, когда требуются проекты, на которые имеются ссылки, возникает фактическая сборка (то есть она запускает задачи и средства и создает выходные данные). Когда сборка Visual Studio находит проект, на который указывает ссылка, MSBuild возвращает ожидаемые выходные данные из упоминаемого проекта. Это позволяет Visual Studio управлять сборкой этих проектов. Visual Studio определяет порядок сборки и вызывает MSBuild отдельно (по мере необходимости), все это полностью находится под контролем Visual Studio.

Другое различие возникает при вызове MSBuild файлом решения, MSBuild анализирует файл решения, создает стандартный входной XML-файл, оценивает его и выполняет в качестве проекта. Сборка решения выполняется перед любым проектом. При сборке из Visual Studio ничего этого не происходит; MSBuild не видит файл решения. Как следствие, настройка сборки решения (с использованием before.SolutionName.sln.targets и after.SolutionName.sln.targets) применяется только к MSBuild.exe или к управляемой объектной модели, а не к сборкам Visual Studio.

Пакеты SDK для проектов

Функция пакета SDK для файлов проекта MSBuild относительно нова. До этого изменения файлы проекта явным образом импортировали файлы TARGETS и PROPS, в которых определен процесс сборки для конкретного типа проекта.

Проекты .NET Core импортируют соответствующую версию пакета SDK для .NET. См. статью Пакеты SDK для проектов .NET Core и ссылку на сведения о свойствах.

Разделение файлов проекта для поддержки нескольких сред

Предположим, что требуется возможность развертывания решения в нескольких средах, таких как тестовые серверы, промежуточные платформы и рабочие среды. Конфигурация может сильно различаться между этими средами—, а не только с именами серверов, строк подключения и т. д., но также с точки зрения учетных данных, параметров безопасности и многих других факторов. Если вам необходимо регулярно делать это, не укороченного изменять несколько свойств в файле проекта каждый раз при переключении целевой среды. И не является идеальным решением для создания бесконечного списка значений свойств, которые должны быть предоставлены процессу сборки.

К счастью, существует альтернативный вариант. MSBuild позволяет разбивать конфигурацию сборки по нескольким файлам проекта

Чтобы увидеть, как это работает, в примере решения обратите внимание на два файла пользовательского проекта:

  • Publish. proj, которая содержит свойства, элементы и целевые объекты, общие для всех сред.
  • Env-dev. proj, которая содержит свойства, характерные для среды разработки.

Теперь обратите внимание, что файл Publish. proj включает элемент Import сразу под открывающим тегом проекта

Элемент Import используется для импорта содержимого другого файла проекта MSBuild в текущий файл проекта MSBuild. В этом случае параметр таржетенвпропсфиле предоставляет имя файла проекта, который необходимо импортировать. Значение этого параметра можно указать при запуске MSBuild.

В результате содержимое этих двух файлов будет объединено в один файл проекта. С помощью этого подхода можно создать один файл проекта, содержащий универсальную конфигурацию сборки и несколько вспомогательных файлов проекта, содержащих свойства конкретной среды. В результате, простое выполнение команды с другим значением параметра позволяет развернуть решение в другой среде.

Разделение файлов проекта таким способом является хорошей практикой. Она позволяет разработчикам развертывать в нескольких средах, выполняя одну команду, одновременно избегая дублирования универсальных свойств сборки в нескольких файлах проекта.

Note

Рекомендации по настройке файлов проекта для конкретной среды сервера см. в разделе Настройка свойств развертывания для целевой среды.

MSBuildProjectExtensionsPath

По умолчанию Microsoft.Common.props импортирует , а Microsoft.Common.targets импортирует . По умолчанию имеет значение , . NuGet использует этот механизм для ссылки на логику сборки, предоставляемую вместе с пакетами. Например, во время восстановления он создает файлы , ссылающиеся на содержимое пакета.

Этот механизм расширяемости можно отключить, установив для свойства значение в Directory.Build.props или до импорта Microsoft.Common.props.

Observação

Отключение импортов MSBuildProjectExtensionsPath препятствует применению логики сборки, предоставляемой в пакетах NuGet, к проекту. Некоторым пакетам NuGet нужна работающая логика сборки, и если эта возможность отключена, они будут бесполезны.

Как MSBuild вызывает задачу

При вызове задачи MSBuild сначала создает экземпляр класса задачи, а затем вызывает методы задания свойств этого объекта для параметров задачи, указанных в элементе задачи в файле проекта. Если в элементе задачи не указан параметр или если результатом вычисления выражения, указанного в элементе, является пустая строка, метод задания свойства не вызывается.

Например, в проекте

вызывается только метод задания для .

Задача не должна зависеть от относительного порядка, в котором вызываются методы задания свойств.

Типы параметров задачи

MSBuild изначально обрабатывает свойства типов , , и . Если задача принимает параметр другого типа, MSBuild вызывает ChangeType для преобразования (со всеми развернутыми свойствами и ссылками на элементы) в целевой тип. Если преобразование для любого входного параметра завершается неудачно, MSBuild выдает ошибку и не вызывает метод задачи.

Troubleshooting MSBuild

Sooner or later we will run into issues with our MSBuild integration, especially regarding the and files. We might reference a wrong property, forget about escaping, or just have a typo in our identifiers. The Project Properties dialog is a good place to start investigations and to see evaluated properties and imports for a project file:

Using the common keyboard shortcut, we can also easily copy values from grid cells. If we need even more insight, then the MSBuild Structured Log Viewer created by Kirill Osenkov can be of great help:

2 years ago I rewrote our entire build pipeline in mostly msbuild. Once I learned about structured log viewer my estimations were cut in half. MSBuild has become a lot more of a regular programming task since then.

The Structured Log Viewer operates on , which can be created by passing to the MSBuild invocation. Binary log files provide the highest level of completeness and verbosity, even compared to most-diagnostic level for text logs. Imports of files and execution of targets are hierarchically visualized using a tree view. Particularly when trying to find a proper target build order for our integration, we can easily check on the flattened temporal order view:

The latest MSBuild Log Viewer adds a new option to display targets in one flat list chronologically, it may be easier to see in which order the targets actually ran:

Another benefit is that when testing our task on large projects that imply a time-consuming compilation, we can replay a single task without executing all its dependencies:

Soon in MSBuild Structured Log Viewer: run or debug MSBuild tasks by using the exact parameter values from the binlog! «Replay» tasks in isolation outside of the build.

For developers on Windows there is a special surprise in JetBrains Rider! We can right-click the test project, choose Advanced Build Actions and execute Rebuild Selected Projects with Diagnostics:

Given that Structured Log Viewer can already run on Avalonia UI, maybe we can see the same feature also for macOS and Linux soon.

Принцип действия атрибута ToolsVersion

При создании проекта в Visual Studio или обновлении существующего проекта атрибут с именем автоматически включается в файл проекта, а его значение соответствует версии MSBuild, включенной в выпуск Visual Studio. Дополнительные сведения см. в статье Общие сведения о настройке для платформы.

Если значение определено в файле проекта, MSBuild использует это значение для определения значений свойств набора инструментов, доступных для проекта. Одно из свойств набора инструментов — это . Оно определяет путь к инструментам .NET Framework. Обязательным является только это свойство набора инструментов (или ).

Начиная с Visual Studio 2013, версия набора инструментов MSBuild совпадает с номером версии Visual Studio. MSBuild по умолчанию соответствует этому набору инструментов в Visual Studio и в командной строке, независимо от версии набора инструментов, указанной в файле проекта. Это поведение можно изменить с помощью флага -ToolsVersion. Дополнительные сведения см. в статье Переопределение параметров ToolsVersion.

В следующем примере MSBuild находит файл Microsoft.CSharp.targets с помощью зарезервированного свойства .

Значение можно изменить, определив пользовательский набор инструментов. Дополнительные сведения см. в статье Стандартные и настраиваемые конфигурации наборов инструментов.

Если вы компилируете решение из командной строки и указываете значение атрибута для msbuild.exe, все проекты и зависимости между проектами компилируются в соответствии с этим значением , даже если в каждом проекте в решении указано собственное значение . Сведения об определении значения для каждого проекта см. в статье Переопределение параметров ToolsVersion.

Атрибут также используется для миграции проектов. Например, если открыть проект Visual Studio 2008 в Visual Studio 2010, то файл проекта обновится и получит значение ToolsVersion = «4.0». Если после этого вы попытаетесь открыть этот проект в Visual Studio 2008, он не распознает обновленное значение атрибута и построит проект таким образом, как если бы этот атрибут по-прежнему имел значение 3.5.

В Visual Studio 2010 и Visual Studio 2012 используется ToolsVersion 4.0. В Visual Studio 2013 используется ToolsVersion 12.0. Visual Studio 2015 использует ToolsVersion 14.0, а Visual Studio 2017 — ToolsVersion 15.0. Во многих случаях проект можно открыть в нескольких версиях Visual Studio без внесения изменений. В Visual Studio всегда используется правильный набор инструментов, но если версия не совпадает с версией в файле проекта, вы получите уведомление. Почти всегда это предупреждение носит информационный характер, так как наборы инструментов в большинстве случаев совместимы.

Поднаборы инструментов, описываемые ниже в этом разделе, позволяют MSBuild автоматически переключаться на набор инструментов в зависимости от контекста, в котором запущено построение. Например, при запуске в Visual Studio 2012 MSBuild использует более новый набор инструментов, чем при запуске в Visual Studio 2010, но при этом не требует изменений в файле проекта.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: