Как дважды ссылаться на одну и ту же миссию msbuild с разными параметрами из самого файла проекта msbuild
У меня есть следующий код msbuild:
<PropertyGroup>
<DirA>C:\DirA\</DirA>
<DirB>C:\DirB\</DirB>
</PropertyGroup>
<Target Name="CopyToDirA"
Condition="Exists('$(DirA)') AND '@(FilesToCopy)' != ''"
Inputs="@(FilesToCopy)"
Outputs="@(FilesToCopy -> '$(DirA)%(Filename)%(Extension)')">
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirA)" />
</Target>
<Target Name="CopyToDirB"
Condition="Exists('$(DirB)') AND '@(FilesToCopy)' != ''"
Inputs="@(FilesToCopy)"
Outputs="@(FilesToCopy -> '$(DirB)%(Filename)%(Extension)')">
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirB)" />
</Target>
<Target Name="CopyFiles" DependsOnTargets="CopyToDirA;CopyToDirB"/>
Таким образом, вызов target CopyFiles
копирует соответствующие файлы в $(DirA)
и $(DirB)
, если они еще не установлены и не обновлены.
Но цели CopyToDirA
и CopyToDirB
выглядят идентичными, кроме одной копии, на $(DirA)
, а остальные - на $(DirB)
. Можно ли объединить их в одну цель, сначала вызванную с помощью $(DirA)
, а затем с помощью $(DirB)
?
Спасибо.
Ответы
Ответ 1
Вы должны иметь возможность генерировать ItemGroup, содержащую Dirs, а затем% на этом.
<ItemGroup>
<Dirs Include="C:\DirA\;C:\DirB\">
</ItemGroup>
<Target Name="CopyFiles"
Condition="Exists('%(Dirs)') AND '@(FilesToCopy)' != ''"
Inputs="@(FilesToCopy)"
Outputs="@(FilesToCopy -> '%(Dirs)%(Filename)%(Extension)')">
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="%(Dirs)" />
</Target>
Или вы можете сделать 2 явных вызова:
<Target Name="CopyFiles">
<MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="[email protected](FilesToCopy);DestDir=$(DirA)" />
<MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="[email protected](FilesToCopy);DestDir=$(DirB)" />
</Target>
<Target Name="CopyASetOfFiles"
Condition="Exists('$(DestDir)') AND '@(FilesToCopy)' != ''"
Inputs="@(FilesToCopy)"
Outputs="@(FilesToCopy -> '$(DestDir)%(Filename)%(Extension)')">
<Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DestDir)" />
</Target>
Я не тестировал ни синтаксис, но относительно увереннее второго.
(Ответ, если таковой имеется, есть в моей книге "Sayed Hashimi" на моем столе - вам придется подождать до первого:
- Получить книгу
- Мне скучно
- Sayed находит это сообщение и придумывает блестящий проверенный ответ)
Ответ 2
Как кто-то уже упоминает, что ответ завершен.
Вот несколько ссылок:
Ответ 3
Да, то, что вы хотите, называется пакетной в MSBuild.
;%(Dirs.Identity)
Определенный в Outputs вызовет выполнение этой задачи для каждого элемента в Dirs ItemGroup.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="CopyFiles"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="3.5">
<ItemGroup>
<Dirs Include="C:\DirA" />
<Dirs Include="C:\DirB" />
</ItemGroup>
<Target Name="CopyFiles"
Inputs="@(FilesToCopy);@(Dirs)"
Outputs="@(FilesToCopy -> '%(Dirs.Identity)%(Filename)%(Extension)');%(Dirs.Identity)" >
<Message Text="%(Dirs.Identity)" />
</Target>
</Project>
Выходы:
Build started 8/19/2009 10:11:57 PM.
Project "D:\temp\test.proj" on node 0 (default targets).
C:\DirA
CopyFiles:
C:\DirB
Done Building Project "D:\temp\test.proj" (default targets).
Измените задачу "Сообщение", чтобы скопировать задачу со следующим условием, и вы закончили:
Condition="Exists('%(Dirs.Identity)') AND '@(FilesToCopy)' != ''"