MsBuild Target с несколькими выходами
Есть ли способ преодолеть целевые соответствия один-к-одному, когда у вас есть несколько выходов? Кажется, это возможно, но я не могу понять, как, учитывая, что я довольно новичок в MsBuild, я, вероятно, что-то упускаю.
Следующий фрагмент скрипта msbuild взят из документации Microsoft. Что я должен изменить, если у меня есть несколько папок для резервных копий? Итак, список @(BackupFolders), и я хотел бы сохранить пошаговое поведение сборки?
<Target Name="Backup" Inputs="@(Compile)"
Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>
1 ответ
Прежде всего, атрибуты Inputs и Outputs на узле Target предназначены для инкрементных сборок. Они должны иметь одинаковое количество записей, чтобы msbuild понимал, какие элементы должны быть отфильтрованы при сборке. MSBuild проверяет, имеются ли выходные данные и являются ли они актуальными, и, если это так, соответствующий элемент ввода отфильтровывается из списка ввода. Если вас не интересует пошаговое построение, вы можете вообще пропустить этот механизм. Если входы и выходы не совпадают (или не присутствуют), msbuild всегда выполняет цель со всеми элементами, потому что не может решить, какие элементы ведут к какому выходу.
Во-вторых, эти атрибуты ожидают списка элементов. Это не должен быть один список, это может быть произвольный список. Так что совершенно справедливо расширить ваш пример так:
<Target Name="Backup" Inputs="@(Compile);@(Compile2)"
Outputs="@(Compile->'$(BackupFolder)%(Identity).bak');@(Compile2->'$(BackupFolder)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
<Copy SourceFiles="@(Compile2)" DestinationFiles=
"@(Compile2->'$(BackupFolder)%(Identity).bak')" />
</Target>
Но вы хотите скопировать одни и те же элементы в разные папки резервных копий, верно? Так что-то вроде этого должно сделать:
<Target Name="Backup">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder2)%(Identity).bak')" />
</Target>
С двумя папками резервных копий, элемент может фактически быть обновленным в одной папке, но отсутствовать в другой. Вы можете определить его в качестве "основной" резервной папки и указать MSBuild использовать его в качестве ссылки для инкрементных сборок.
Редактировать: Для инкрементных сборок в двух местах, вероятно, самое простое решение - объединить две цели, обе построены постепенно:
<Target Name="Backup" DependsOnTargets="_Backup1;_Backup2">
</Target>
<Target Name="_Backup1" Inputs="@(Compile)"
Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>
<Target Name="_Backup2" Inputs="@(Compile)"
Outputs="@(Compile->'$(BackupFolder2)%(Identity).bak')">
<Copy SourceFiles="@(Compile)" DestinationFiles=
"@(Compile->'$(BackupFolder2)%(Identity).bak')" />
</Target>