Как работает ResolveProjectReferences?
Я хочу профилировать и настраивать нашу сборку в надежде сэкономить несколько секунд здесь и там. Мне удалось создать задачу, основанную на ResolveAssemblyReferences, и использовать ее вместо этого, но у меня возникли проблемы с пониманием следующего (из Microsoft.Common.targets):
<!--
============================================================
ResolveProjectReferences
Build referenced projects:
[IN]
@(NonVCProjectReference) - The list of non-VC project references.
[OUT]
@(_ResolvedProjectReferencePaths) - Paths to referenced projects.
============================================================
-->
<Target
Name="ResolveProjectReferences"
DependsOnTargets="SplitProjectReferencesByType;_SplitProjectReferencesByFileExistence">
<!--
When building this project from the IDE or when building a .SLN from the command-line,
just gather the referenced build outputs. The code that builds the .SLN will already have
built the project, so there's no need to do it again here.
The ContinueOnError setting is here so that, during project load, as
much information as possible will be passed to the compilers.
-->
<MSBuild
Projects="@(_MSBuildProjectReferenceExistent)"
Targets="GetTargetPath"
BuildInParallel="$(BuildInParallel)"
UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)"
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform)"
Condition="'@(NonVCProjectReference)'!='' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true' or '$(BuildProjectReferences)' != 'true') and '@(_MSBuildProjectReferenceExistent)' != ''"
ContinueOnError="!$(BuildingProject)">
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedProjectReferencePaths"/>
</MSBuild>
<!--
Build referenced projects when building from the command line.
The $(ProjectReferenceBuildTargets) will normally be blank so that the project's default
target is used during a P2P reference. However if a custom build process requires that
the referenced project has a different target to build it can be specified.
-->
<MSBuild
Projects="@(_MSBuildProjectReferenceExistent)"
Targets="$(ProjectReferenceBuildTargets)"
BuildInParallel="$(BuildInParallel)"
UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)"
Condition="'@(NonVCProjectReference)'!='' and '$(BuildingInsideVisualStudio)' != 'true' and '$(BuildingSolutionFile)' != 'true' and '$(BuildProjectReferences)' == 'true' and '@(_MSBuildProjectReferenceExistent)' != ''">
<Output TaskParameter="TargetOutputs" ItemName="_ResolvedProjectReferencePaths"/>
</MSBuild>
<!--
Get manifest items from the (non-exe) built project references (to feed them into ResolveNativeReference).
-->
<MSBuild
Projects="@(_MSBuildProjectReferenceExistent)"
Targets="GetNativeManifest"
BuildInParallel="$(BuildInParallel)"
UnloadProjectsOnCompletion="$(UnloadProjectsOnCompletion)"
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform)"
Condition="'@(NonVCProjectReference)'!='' and '$(BuildingProject)'=='true' and '@(_MSBuildProjectReferenceExistent)'!=''">
<Output TaskParameter="TargetOutputs" ItemName="NativeReference"/>
</MSBuild>
<!-- Issue a warning for each non-existent project. -->
<Warning
Text="The referenced project '%(_MSBuildProjectReferenceNonexistent.Identity)' does not exist."
Condition="'@(NonVCProjectReference)'!='' and '@(_MSBuildProjectReferenceNonexistent)'!=''"/>
</Target>
Некоторые параметры передаются, а некоторые возвращаются, но где происходит настоящая работа? На MSDN не так много - я нашел Microsoft.Build.Tasks.ResolveProjectBase, но он не очень полезен.
1 ответ
ResolveProjectReferences (по крайней мере та, на которую вы указываете) - это цель, которая используется для разрешения межпроектных ссылок путем их построения с помощью задачи
Рассмотрим следующую цель:
<Target
Name="Build"
Returns="@(BuildOutput)">
<ItemGroup>
<BuildOutput Include="bin\Debug\Foo.exe" />
</ItemGroup>
</Target>
Если вы ссылаетесь на проект, содержащий эту цель, и хотите разрешить выходные данные цели Foo, в вашем проекте будет элемент
<ItemGroup>
<ProjectReference Include="..\SomeProject\SomeProject.proj">
<Targets>Build</Targets>
</ProjectReference>
</ItemGroup>
Обратите внимание, что если "Build" является целью по умолчанию для указанного проекта, вы можете полностью исключить метаданные "Targets". Вы также можете указать несколько целей в метаданных целей (список, разделенный точкой с запятой).
Таким образом, ваша цель ResolveProjectReferences придет и вызовет задачу
- MSBuildSourceProjectFile - ссылочный проект, сборка которого сгенерировала вывод
- MSBuildSourceTargetName - имя цели, чья сборка сгенерировала вывод
Если вы работаете в проекте C#, есть множество других этапов разрешения ссылок (включая разрешение сборки). Напишите мне, если вы хотите знать об этом.