Когда вы импортируете другой файл msbuild, каков порядок оценки?
У меня есть файл общих свойств shared.properties.proj
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SharedAssemblySearch>$(MSBuildProjectDirectory)\..\Shared Assemblies</SharedAssemblySearch>
<ParentDir>..</ParentDir>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblyPath Condition="Exists('$(SharedAssemblySearch)')">$(SharedAssemblySearch)</SharedAssemblyPath>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">..\SharedAssemblies</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
<SharedAssemblyPath Condition="Exists('$(SharedAssemblySearch)')">$(SharedAssemblySearch)</SharedAssemblyPath>
</PropertyGroup>
</project>
Я ищу любой родительский каталог уровня, содержащий каталог с именем Shared Assemblies
. или, альтернативно, SharedAssemblies
Я хотел бы поставить этот код в центральное место для sln, так что все проекты могут просто импортировать его. проекты в sln не все находятся на одном уровне иерархии.
Пример .csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Shared.Properties.proj))\Shared.Properties.proj"
Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Shared.Properties.proj))' != '' "/>
<ItemGroup>
<Reference Include="EntityFramework">
<HintPath>$(SharedAssemblyPath)\NuGet\EntityFramework.4.3.0\lib\net40\EntityFramework.dll</HintPath>
</Reference>
</ItemGroup>
<Target Name="CheckReferencePaths" BeforeTargets="ResolveAssemblyReferences">
<Message Importance="high" Text="Doing CheckReferencePaths" />
<ItemGroup>
<SharedAssemblyPathItem Include="$(SharedAssemblyPath)" />
</ItemGroup>
<Warning Condition="!Exists('@(SharedAssemblyPathItem)')" Text="SharedAssemblyPath not found at '@(SharedAssemblyPathItem)'" />
<Warning Condition="!Exists('@(SharedAssemblyPathItem)')" Text="SharedAssemblyPath not found at '@(SharedAssemblyPathItem->'%(FullPath)')'" />
<Message Condition="!Exists('%(Reference.HintPath)')" Text="FullPath=%(Reference.HintPath)" Importance="high" />
У меня это работает в основном проекте, не вытесняя группу свойств в файл со спутника, который я импортирую, но теперь хочу сделать его повторно используемым между другими проектами, которые могут иметь общие ссылки.
Цель BeforeTargets
показывает это при новой попытке, которая не работает:
CheckReferencePaths: Выполнение CheckReferencePaths D:\Projects\Team\Project\Переходники\DbAdapter\dbadapter.csproj(103,5): предупреждение: SharedAssemblyPath не найден в '' D:\Projects\Team\Project\Переходники\DbAdapter\dbadapter.csproj(104,5): предупреждение: SharedAssemblyPath не найден в ''
FullPath =\NuGet\EntityFramework.4.3.0\Lib\net40\EntityFramework.dll
FullPath =
Как я могу получить файл проекта, который импортирует shared, чтобы оценить импортированные свойства проекта, прежде чем он оценит hintpaths групп элементов. Или собственно порядок оценки, но что-то еще в моей конструкции неверно?
Ответы
Ответ 1
Ваш вопрос заставил меня найти эту ценную информацию о MSDN. Я размещаю его здесь для сохранения ответа автономного.
Порядок оценки
Когда MSBuild достигает элемента Импорт, импортированный проект эффективно вставляется в проект импорта в месте расположения элемента Импорт. Поэтому расположение элемента Импорт может влиять на значения свойств и элементов. Важно понимать свойства и элементы, заданные импортированным проектом, а также свойства и элементы, которые использует импортированный проект.
Когда проект строится, сначала сначала оцениваются все свойства, а затем элементы. Например, следующий XML определяет импортированный файл проекта MyCommon.targets:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Name>MyCommon</Name>
</PropertyGroup>
<Target Name="Go">
<Message Text="Name='$(Name)'"/>
</Target>
</Project>
В следующем XML определяется MyApp.proj, который импортирует MyCommon.targets:
<Project
DefaultTargets="Go"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Name>MyApp</Name>
</PropertyGroup>
<Import Project="MyCommon.targets"/>
</Project>
При создании проекта отображается следующее сообщение:
Name= "MyCommon"
Поскольку проект импортируется после определения свойства Name в MyApp.proj, определение Name в MyCommon.targets переопределяет определение в MyApp.proj. Если проект импортируется до определения имени свойства, в сборке будет отображаться следующее сообщение:
Name= "MyApp"
При импорте проектов
используйте следующий подход:
-
Определите в файле проекта все свойства и элементы, которые используются
как параметры свойств и элементов в импортированном проекте.
-
Импортируйте проект.
-
Определите в файле проекта все свойства и элементы, которые должны
переопределять определения свойств и элементов по умолчанию в импортированных
проект.
Пример
В следующем примере кода показан файл MyCommon.targets, который импортирует второй пример кода. Файл .targets оценивает свойства проекта импорта для настройки сборки.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Flavor Condition="'$(Flavor)'==''">DEBUG</Flavor>
<Optimize Condition="'$(Flavor)'=='RETAIL'">yes</Optimize>
<appname>$(MSBuildProjectName)</appname>
<PropertyGroup>
<Target Name="Build">
<Csc Sources="hello.cs"
Optimize="$(Optimize)"
OutputAssembly="$(appname).exe"/>
</Target>
</Project>
Следующий пример кода импортирует файл MyCommon.targets.
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Flavor>RETAIL</Flavor>
</PropertyGroup>
<Import Project="MyCommon.targets"/>
</Project>
Ответ 2
Попробуйте использовать встроенную задачу вместо файла shared.properties.proj. Проверьте мой ответ на этот вопрос.
Речь идет о поиске какого-либо файла в родительских каталогах. Вы можете адаптировать его для поиска родительского каталога.