Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Как на самом деле работает MSBuild? В этой статье вы узнаете, как MSBuild обрабатывает файлы проекта, независимо от того, вызывается ли из Visual Studio или из командной строки или скрипта. Зная, как работает MSBuild, вы можете лучше диагностировать проблемы и лучше настроить процесс сборки. В этой статье описывается процесс сборки и он в значительной степени применим ко всем типам проектов.
Полный процесс сборки состоит из начального запуска, оценки и выполнения целевых объектов и задач, которые создают проект. Помимо этих входных данных внешние импорты определяют сведения о процессе сборки, включая стандартные импорты , такие как Microsoft.Common.targets и настраиваемые пользователем импорты на уровне решения или проекта.
Запуск
MSBuild можно вызвать из Visual Studio через объектную модель MSBuild в Microsoft.Build.dllили вызвать исполняемый файлMSBuild.exe
(или dotnet build
) непосредственно в командной строке или в скрипте, например в системах CI. В любом случае входные данные, влияющие на процесс сборки, включают файл проекта (или объект проекта внутри Visual Studio), возможно, файл решения, переменные среды и коммутаторы командной строки или эквиваленты их объектной модели. На этапе запуска параметры командной строки или эквиваленты объектной модели используются для настройки параметров MSBuild, таких как настройка средств ведения журнала. Свойства, заданные в командной строке с помощью -property
или -p
переключателя, задаются как глобальные свойства, которые переопределяют все значения, которые будут заданы в файлах проекта, даже если файлы проекта считываются позже.
В следующих разделах рассматриваются входные файлы, такие как файлы решения или файлы проекта.
Решения и проекты
Экземпляры MSBuild могут состоять из одного проекта или многих проектов в рамках решения. Файлы решений в .slnx
формате или .sln
формате поддерживаются (в MSBuild 17.12 и более поздних версиях). Файл решения (.sln
) не ЯВЛЯЕТСЯ XML-файлом MSBuild, но MSBuild интерпретирует его, чтобы знать все проекты, необходимые для создания для заданной конфигурации и параметров платформы. Когда MSBuild обрабатывает эти входные данные, это называется сборкой проекта решения. Он имеет некоторые расширяемые точки, которые позволяют выполнять операции при каждой сборке решения, но поскольку эта сборка — отдельный запуск от отдельных сборок проекта, никакие параметры или определения целей из сборки решения не применяются к каждой сборке проекта.
Вы можете узнать, как расширить сборку решения при настройке сборки решения.
Сборки Visual Studio против сборок MSBuild.exe
При создании проектов в Visual Studio и при вызове MSBuild напрямую через исполняемый файл MSBuild или при использовании объектной модели MSBuild для запуска сборки существуют некоторые существенные различия. Visual Studio управляет порядком сборки проектов в своих сборках; он вызывает MSBuild только на уровне отдельного проекта, и, когда делает это, устанавливаются некоторые логические свойства (BuildingInsideVisualStudio
, BuildProjectReferences
), которые существенно влияют на действия 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, dotnet build
, или управляемым объектной моделью сборкам, а не к сборкам Visual Studio.
Пакеты SDK для проектов
Функция SDK для файлов проекта MSBuild является относительно новой. Перед этим изменением файлы проекта явно импортировали файлы .targets и PROPS-файлы , которые определили процесс сборки для определенного типа проекта.
Проекты .NET Core импортируют версию пакета SDK для .NET, соответствующую им. Ознакомьтесь с общими сведениями, пакетами SDK для проекта .NET Core и ссылкой на свойства.
Этап оценки
В этом разделе описывается обработка и анализ этих входных файлов для создания объектов в памяти, определяющих, что будет создано.
Целью этапа оценки является создание структур объектов в памяти на основе входных XML-файлов и локальной среды. Этап оценки состоит из шести проходов, которые обрабатывают входные файлы, такие как XML-файлы проекта или импортированные XML-файлы, обычно называемые .props или .targets файлами, в зависимости от того, задают ли они главным образом свойства или определяют цели сборки. Каждая итерация создает часть объектов в памяти, которые позже используются на этапе выполнения для сборки проектов, но фактические действия сборки не выполняются на фазе оценки. В каждом проходе элементы обрабатываются в том порядке, в котором они появляются.
Этапы прохождения оценки приведены следующие:
- Оценка переменных среды
- Оценка импорта и свойств
- Оценка определений элементов
- Оценка элементов
- Оценка элементов UsingTask
- Оценка целевых объектов
Импорт и свойства вычисляются в той же последовательности внешнего вида, как если бы импорт был развернут на месте. Таким образом, параметры свойств в ранее импортированных файлах доступны в последующих импортированных файлах.
Порядок этих проходов оказывает значительное влияние и важно учитывать его при настройке файла проекта. См. порядок оценки свойств и элементов.
Оценка переменных среды
На этом этапе переменные среды используются для задания эквивалентных свойств. Например, переменная среды PATH становится доступной как свойство $(PATH)
. При выполнении из командной строки или скрипта командная среда используется как обычно, а при запуске из Visual Studio применяется среда, активная на момент запуска Visual Studio.
Оценка импорта и свойств
На этом этапе весь входной XML считывается, включая файлы проекта и всю цепочку импорта. MSBuild создает xml-структуру в памяти, представляющую XML проекта и все импортированные файлы. В настоящее время свойства, которые не находятся в целевых объектах, оцениваются и задаются.
Как следствие MSBuild считывает все входные XML-файлы на ранних этапах процесса, любые изменения этих входных данных во время процесса сборки не влияют на текущую сборку.
Свойства за пределами любого целевого объекта обрабатываются по-разному от свойств в целевых объектах. На этом этапе вычисляются только свойства, определенные за пределами любого целевого объекта.
Так как свойства обрабатываются в порядке передачи свойств, свойство в любой момент ввода может получить доступ к значениям свойств, отображаемым ранее в входных данных, но не к свойствам, которые отображаются позже.
Так как свойства обрабатываются перед вычислением элементов, вы не можете получить доступ к значению любого элемента во время передачи свойств.
Оценка определений элементов
На этом этапе определения элементов интерпретируются и создается представление этих определений в памяти.
Оценка элементов
Элементы, определенные внутри целевого объекта, обрабатываются по-разному от элементов за пределами любого целевого объекта. На этом этапе обрабатываются элементы вне любого целевого объекта и их связанных метаданных. Метаданные, заданные определениями элементов, переопределяются метаданными, заданными для элементов. Так как элементы обрабатываются в порядке их отображения, можно ссылаться на элементы, определенные ранее, но не те, которые отображаются позже. Так как элементы передаются после передачи свойств, элементы могут получить доступ к любому свойству, если оно определено вне целевых объектов, независимо от того, отображается ли определение свойства позже.
Оценка UsingTask
элементов
На этом этапе элементы UsingTask считываются, а задачи объявляются для последующего использования на этапе выполнения.
Оценка целевых объектов
На этом этапе все целевые структуры объектов создаются в памяти при подготовке к выполнению. Фактическое выполнение не происходит.
Этап выполнения
На этапе выполнения цели упорядочиваются и запускаются, и все задачи выполняются. Но сначала свойства и элементы, определенные в целевых объектах, оцениваются вместе на одном этапе в порядке их отображения. Порядок обработки значительно отличается от способа обработки свойств и элементов, которые не находятся в целевом объекте: все свойства сначала, а затем все элементы в отдельных проходах. Изменения свойств и элементов в целевом объекте можно наблюдать после изменения целевого объекта.
Целевой порядок сборки
В одном проекте целевые задачи выполняются последовательно. Основная проблема заключается в том, как определить, в каком порядке собирать всё так, чтобы зависимости использовались для создания целевых элементов в правильном порядке.
Порядок целевых сборок определяется использованием атрибутов BeforeTargets
, DependsOnTargets
, и AfterTargets
для каждого целевого объекта. Порядок последующих целевых объектов может изменяться во время выполнения более ранней целевой задачи, если более ранний целевой объект изменяет свойство, на которое ссылаются эти атрибуты.
Правила упорядочивания описаны в разделе "Определение целевого порядка сборки". Процесс определяется структурой стека, содержащей целевые объекты для сборки. Целевой объект в верхней части этой задачи запускает выполнение, и если он зависит от чего-либо другого, эти целевые объекты отправляются в верхнюю часть стека, и они начинают выполняться. Когда цель не имеет зависимостей, она выполняется до завершения, после чего возобновляется ее родительская цель.
Ссылки на проект
Существует два пути кода, которые MSBuild может принимать, обычный, описанный здесь, и параметр графа, описанный в следующем разделе.
Отдельные проекты указывают свою зависимость от других проектов с помощью ProjectReference
элементов. Когда проект на вершине стека начинает сборку, он достигает точки, в которой выполняется ResolveProjectReferences
цель — стандартная цель, определённая в общих файлах целей.
ResolveProjectReferences
вызывает задачу MSBuild с входами ProjectReference
элементов для получения выходных данных. Элементы ProjectReference
преобразуются в локальные элементы, такие как Reference
. Этап выполнения MSBuild для текущего проекта приостанавливается во время того, как этап выполнения начинает обрабатывать ссылочный проект (сначала при необходимости выполняется этап оценки). Указанный проект компилируется только после начала сборки зависимого проекта, и это создает иерархию компиляции проектов.
Visual Studio позволяет создавать зависимости проекта в файлах решения (.sln). Зависимости указываются в файле решения и учитываются только при создании решения или при сборке внутри Visual Studio. При создании одного проекта этот тип зависимостей игнорируется. Ссылки на решения преобразуются MSBuild в ProjectReference
элементы и после этого обрабатываются таким же образом.
Опция графика
Если вы укажете переключатель сборки графа (-graphBuild
или -graph
), то ProjectReference
становится основным понятием, используемым MSBuild. MSBuild анализирует все проекты и создает граф порядка сборки, фактический граф зависимостей проектов, который затем проходит по определению порядка сборки. Как и в случае с целями в отдельных проектах, MSBuild гарантирует, что связанные проекты собираются после проектов, от которых они зависят.
Параллельное выполнение
При использовании поддержки нескольких процессоров (-maxCpuCount
или -m
коммутатора) MSBuild создает узлы, которые являются процессами MSBuild, использующими доступные ядра ЦП. Каждый проект отправляется на доступный узел. В узле отдельные сборки проектов выполняются последовательно.
Задачи могут быть включены для параллельного $(BuildInParallel)
выполнения, задав логическую переменнуюBuildInParallel, которая устанавливается в соответствии со значением свойства в MSBuild. Для задач, которые включены для параллельного выполнения, планировщик работы управляет узлами и назначает работу узлам.
См. статью "Создание нескольких проектов параллельно с MSBuild"
Стандартные импорты
Microsoft.Common.props и Microsoft.Common.targets импортируются файлами проектов .NET (явно или неявно в проектах в стиле SDK) и находятся в папке MSBuild\Current\bin в установке Visual Studio. Проекты C++ имеют собственную иерархию импорта; см. раздел "Внутренние компоненты MSBuild" для проектов C++.
Файл Microsoft.Common.props задает значения по умолчанию, которые можно переопределить. Он импортируется (явно или неявно) в начале файла проекта. Таким образом, параметры проекта отображаются после значений по умолчанию, чтобы они переопределяли последние.
Файл Microsoft.Common.target и целевые файлы, которые он импортирует, определяют стандартный процесс сборки для проектов .NET. Он также предоставляет точки расширения, которые можно использовать для настройки сборки.
В реализации Microsoft.Common.targets — это тонкая оболочка, которая импортирует Microsoft.Common.CurrentVersion.targets. Этот файл содержит параметры стандартных свойств и определяет фактические целевые объекты, определяющие процесс сборки. Целевой Build
объект определен здесь, но на самом деле сам по себе пуст. Однако целевой Build
объект содержит DependsOnTargets
атрибут, указывающий отдельные целевые объекты, составляющие фактические шаги сборки, которые являются BeforeBuild
и CoreBuild
AfterBuild
. Целевой Build
объект определяется следующим образом:
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="@(TargetPathWithTargetPlatformMoniker)" />
BeforeBuild
и AfterBuild
являются точками расширения. Они пусты в файле Microsoft.Common.CurrentVersion.targets , но проекты могут предоставлять свои собственные BeforeBuild
и AfterBuild
целевые объекты с задачами, которые необходимо выполнить до или после основного процесса сборки.
AfterBuild
выполняется до no-op, Build
, так как AfterBuild
появляется в атрибуте DependsOnTargets
целевого объекта Build
, но происходит после CoreBuild
.
Целевой CoreBuild
объект содержит вызовы средств сборки следующим образом:
<PropertyGroup>
<CoreBuildDependsOn>
BuildOnlySettings;
PrepareForBuild;
PreBuildEvent;
ResolveReferences;
PrepareResources;
ResolveKeySource;
Compile;
ExportWindowsMDFile;
UnmanagedUnregistration;
GenerateSerializationAssemblies;
CreateSatelliteAssemblies;
GenerateManifests;
GetTargetPath;
PrepareForRun;
UnmanagedRegistration;
IncrementalClean;
PostBuildEvent
</CoreBuildDependsOn>
</PropertyGroup>
<Target
Name="CoreBuild"
DependsOnTargets="$(CoreBuildDependsOn)">
<OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent" Condition="'$(RunPostBuildEvent)'=='Always' or '$(RunPostBuildEvent)'=='OnOutputUpdated'"/>
<OnError ExecuteTargets="_CleanRecordFileWrites"/>
</Target>
В следующей таблице описаны эти целевые объекты; некоторые целевые объекты применимы только к определенным типам проектов.
Цель | Описание |
---|---|
BuildOnlySettings | Параметры только для реальных сборок, а не при вызове MSBuild при загрузке проекта Visual Studio. |
PrepareForBuild | Подготовка необходимых компонентов для сборки |
PreBuildEvent | Точка расширения для проектов, позволяющая определять задачи, которые выполняются перед сборкой |
ResolveProjectReferences | Анализ зависимостей проекта и создание ссылочных проектов |
ResolveAssemblyReferences | Найдите ссылки на сборки. |
ResolveReferences | Состоит из ResolveProjectReferences и ResolveAssemblyReferences для поиска всех зависимостей |
ПодготовьтеРесурсы | Обработка файлов ресурсов |
ResolveKeySource | Устраните ключ строгого имени, используемый для подписи сборки, и сертификат, используемый для подписи манифестов ClickOnce. |
Компиляция | Вызывает компилятор |
ЭкспортироватьWindowsMDФайл | Создайте файл WinMD из файлов WinMDModule, созданных компилятором. |
НеконтролируемаяОтменаРегистрации | Удалите и очистите записи реестра COM Interop из предыдущей сборки. |
Создать сборки сериализации | Создайте сборку сериализации XML с помощью sgen.exe. |
СоздатьСпутниковыеСборки | Создайте одну спутниковую сборку для каждой уникальной культуры в ресурсах. |
Создание манифестов | Создает манифесты приложения ClickOnce и развертывания или нативный манифест. |
GetTargetPath | Возвращает элемент, содержащий продукт сборки (исполняемый файл или сборку) для этого проекта с метаданными. |
PrepareForRun | Скопируйте выходные данные сборки в окончательный каталог, если они изменились. |
НеуправляемаяРегистрация | Установить записи реестра для COM Interop |
Инкрементальная очистка | Удалите файлы, созданные в предыдущей сборке, но не были созданы в текущей сборке. Это необходимо, чтобы Clean работал в инкрементальных сборках. |
PostBuildEvent | Точка подключения, позволяющая проектам задавать задачи, которые выполняются после сборки. |
Многие целевые объекты в предыдущей таблице находятся в импортах, относящихся к языку, таких как Microsoft.CSharp.targets. Этот файл определяет шаги, описанные в стандартном процессе сборки для проектов C# .NET. Например, он содержит целевой Compile
объект, который фактически вызывает компилятор C#.
Настраиваемые пользователем импорты
Помимо стандартных импортов существует несколько импортов, которые можно добавить для настройки процесса сборки.
- Directory.Build.props
- Directory.Build.targets
Эти файлы считываются стандартными механизмами импорта для всех проектов в любых вложенных папках. Обычно это на уровне настроек решения для управления всеми проектами в решении, но также может быть на более высоком уровне в файловой системе, вплоть до корня диска.
Файл Directory.Build.props импортируется Microsoft.Common.props, поэтому свойства, определенные в нем, доступны в файле проекта. Они можно переопределять в файле проекта, чтобы настроить значения на основе каждого проекта. Файл Directory.Build.targets считывается после файла проекта. Обычно он содержит целевые объекты, но здесь можно также определить свойства, которые не нужно переопределить отдельными проектами.
Настройки в файле проекта
Visual Studio обновляет файлы проекта при внесении изменений в обозревателе решений, окне свойств или в свойствах проекта, но вы также можете внести собственные изменения, непосредственно изменив файл проекта.
Многие поведения сборки можно настроить, задав свойства MSBuild в файле проекта для параметров локального проекта или как упоминалось в предыдущем разделе, создав файл Directory.Build.props для глобального задания свойств для всех папок проектов и решений. Для нерегламентированных сборок в командной строке или скриптах можно также использовать /p
параметр в командной строке, чтобы задать свойства для определенного вызова MSBuild. См. Общие свойства проекта MSBuild для получения информации о свойствах, которые можно задать.