Объем и порядок оценки предметов в MsBuild
Интересно, почему в следующем коде MsBuild отказывается устанавливать метаданные суффикса. Он работает с задачей CreateItem вместо объявления ItemGroup (потому что CreateItem вычисляется во время сборки), но я не могу сделать это здесь, потому что этот код находится в "файле свойств": у проекта нет цели, это просто куча свойств / предметов я включаю в реальные проекты.
<ItemGroup>
<Layout Include="Bla">
<PartnerCode>bla</PartnerCode>
</Layout>
<Layout Include="Bli">
<PartnerCode>bli</PartnerCode>
</Layout>
</ItemGroup>
<ItemGroup Condition="'$(LayoutENV)'=='Preprod'">
<LayoutFolder Include="Preprod">
<Destination>..\Compil\layout\pre\</Destination>
</LayoutFolder>
</ItemGroup>
<ItemGroup>
<Destinations Include="@(LayoutFolder)" >
<Suffix>%(Layout.PartnerCode)</Suffix>
</Destinations>
</ItemGroup>
Направления хорошо построены, но метаданные суффикса не установлены.
На данный момент я продублировал Определение направлений в каждом проекте, в котором он мне был нужен, но он не очень чистый. Если у кого-то есть лучшее решение, мне интересно!
3 ответа
Похоже, что я пытаюсь динамически устанавливать метаданные вне цели, что невозможно. Я пытаюсь установить метаданные суффикса путем пакетирования по элементам макета, но элементы макета не устанавливаются должным образом, когда пакетирование выполнено. Пакетирование выполняется, когда msbuild анализирует мои файлы свойств, он не ожидает объявления Layout.
Тем не менее, как указывал MadGnome, я могу выполнить пакетную обработку над LayoutFolder (который является исходными элементами для моих включений), поскольку MSBuild действительно ждет его объявления.
С MSBuild 4
вы можете использовать метаданные из предыдущих элементов в объявлении элемента следующим образом:
<ItemGroup>
<Layout Include="Bla">
<PartnerCode>bla</PartnerCode>
</Layout>
<Layout Include="Bli">
<PartnerCode>bli</PartnerCode>
</Layout>
</ItemGroup>
<ItemGroup>
<Destinations Include="@(Layout)" >
<Suffix>%(PartnerCode)</Suffix>
</Destinations>
</ItemGroup>
(Странно, что вы пакетируете на LayoutFolder
и попытаться получить Layout
метаданные. Какое значение вы хотите, как суффикс бла или бли?)
Проблема, с которой вы сталкиваетесь, заключается в том, что вы ссылаетесь на метаданные в списке. %(Layout.PartnerCode)
перебирает ItemGroup "Layout", которая в этом случае возвращает 2 элемента. Даже с 1 это приводит к нежелательным, неожиданным результатам, так как вы указываете на список. MSBuild возвращает два мета-тега и не знает, какой из них вы хотели бы иметь. В результате он выбирает ни один вместо... или... ну, MSBuild заканчивает тем, что устанавливает его в ничто.
Я бы предложил установить ItemDefinition по умолчанию, например, (MSBuild 3.5)
<ItemDefinitionGroup>
<Layout>
<PartnerCode>%(Identity)</PartnerCode>
<Suffix>%(PartnerCode)</Suffix>
<Destination Condition="'$(LayoutENV)'=='Preprod'">..\Compile\layout\pre\</Destination>
</Layout>
</ItemDefinitionGroup>
А затем определите их, как вы бы.
<ItemGroup>
<Layout Include="Bla" />
<Layout Include="Bli" />
<Layout Include="Bloop">
<PartnerCode>B2</PartnerCode>
<Suffix>%(PartnerCode)</Suffix>
</Layout>
</ItemGroup>
Sidenotes
Примечание Кажется, что метаданные анализируются только один раз для каждой группы определений / группы элементов, поэтому, если вы устанавливаете PartnerCode, вам также придется сбросить суффикс, как показано во втором примере. Я не знаком с поведением в MSBuild 3.5, но это имеет место в MSBuild 4.0.
Примечание Я предполагаю, что вы хотите ваше имя файла в качестве суффикса,
Identity
делает трюк, см. здесь "Метаданные общеизвестных элементов MSBuild": ( https://msdn.microsoft.com/en-us/library/ms164313.aspx), если это не так, вы всегда можете следовать переопределить пример или написать свою собственную функцию на его основе. Подробнее о подобных вещах читайте здесь: "Функции свойств MSBuild": ( https://msdn.microsoft.com/en-us/library/dd633440.aspx)