我正在尝试按照How to invoke the same msbuild target twice?
中概述的基本模型在msbuild中创建可重用的目标我试图传递一个我想要解释为列表的属性。我还没有在网上找到一个处理这种情况的例子。据我了解,问题是属性已被视为列表项,因此它不喜欢传入列表项。有没有办法让msbuild在这里正确打包和解包列表?
Msbuild抱怨:
error MSB4012: The expression "FilesToZip=@(Scripts)" cannot be used in this context. Item lists cannot be concatenated with other strings where an item list is expected. Use a semicolon to separate multiple item lists.
以下是一个示例来电者:
<Target Name="BuildMigrationZip">
<MSBuild Projects="BuildZip.msbuild"
Targets="BuildZip"
Properties="FilesToZip=@(Scripts);OutputZipFile=$(MigrationPackageFilePath);OutputFolder=$(MigrationPackagePath);Flatten=true"/>
<Message Text="Created database migration zip: $(MigrationPackageFilePath)" Importance="high"/>
</Target>
基础目标:
<Target Name="BuildZip">
<MakeDir Directories="$(OutputFolder)"/>
<Zip Files="@(FilesToZip)"
ZipFileName="$(OutputZipFile)"
Flatten="$(Flatten)"
ParallelCompression="false" />
</Target>
我基本上只是回去剪切和粘贴这些,虽然我想在这里打包一些拉链。
更新:同样的问题适用于在可重用目标上设置输入。到目前为止,我的问题解决了原始功能,但保持依赖项工作会很好。例如:
<Target Name="BuildZip"
Inputs="@(FilesToZip)"
Outputs="$(OutputZipFile)">
<MakeDir Directories="$(OutputFolder)"/>
<Zip Files="@(FilesToZip)"
ZipFileName="$(OutputZipFile)"
Flatten="$(Flatten)"
ParallelCompression="false" />
</Target>
答案 0 :(得分:4)
他们的关键是将列表作为属性传递。因此,当您的Scripts
列表定义为
<ItemGroup>
<Scripts Include="A"/>
<Scripts Include="B"/>
<Scripts Include="C"/>
</ItemGroup>
然后你首先将它转换为一个属性(它只生成分号分隔的项目,但msbuild知道如何通过Properties
目标的MSBuild
传递它,然后将其传递给目标:< / p>
<Target Name="BuildMigrationZip">
<PropertyGroup>
<ScriptsProperty>@(Scripts)</ScriptsProperty>
</PropertyGroup>
<MSBuild Projects="$(MSBuildThisFile)" Targets="BuildZip"
Properties="FilesToZip=$(ScriptsProperty)" />
</Target>
(请注意我在这里使用$(MSBuildThisFile)
:您不一定需要为每个目标创建单独的构建文件,事实上对于像您这样的小目标而言,它还需要更多方便把它放在同一个文件中)
然后在您的目标目标中,您再次将该属性转换为列表:
<Target Name="BuildZip">
<ItemGroup>
<FilesToZipList Include="$(FilesToZip)"/>
</ItemGroup>
<Message Text="BuildZip: @(FilesToZipList)" />
</Target>
输出:
BuildZip: A;B;C
<强>更新强>
使用Inputs
时,您无法传递@(FilesToZip)
,因为它不会扩展为空,因为它不是列表:它是一个属性 - 恰好是一些以分号分隔的字符串。因此,它可用于Inputs
您只需将其展开为属性即$(FilesToZip)
:
<Target Name="BuildZip"
Inputs="$(FilesToZip)"
Outputs="$(OutputZipFile)">
...
</Target>
第二轮的输出:
BuildZip:
Skipping target "BuildZip" because all output files are up-to-date with respect to the input files.