自定义PiPL文件构建中ExcludeFromBuild属性不生效的MSBuild问题
我为PiPL格式的*.r文件创建了自定义构建规则,但遇到了一个问题:在Visual Studio中打开这类文件的属性页,选择特定配置并将“从构建中排除”设为“是”后,该配置下Visual Studio仍然会编译这个文件。查看vcxproj文件,该文件的ExcludedFromBuild属性已经针对目标配置正确设置:
<ItemGroup> <PIPLFile Include="..\MyFile.r"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">true</ExcludedFromBuild> </PIPLFile> </ItemGroup>
将MSBuild日志级别设为“诊断”后,得到以下输出:
1>Target "PIPLCompile" in file "[my path]\r.targets":
1> Building target "PIPLCompile" completely.
1> Input file "[my source path]\MyFile.r" is newer than output file "[my IntDir path]\Resources.pipl".
我原本以为MSBuild会自动识别自定义文件类型的ExcludedFromBuild属性?还是说自定义构建规则需要自行检查这个属性?
目前我通过在执行编译的Exec任务中添加%(PIPLFile.ExcludedFromBuild)的检查条件,临时解决了编译问题,但从日志来看,只要输入文件比输出文件新,MSBuild就会每次尝试运行这个目标任务,这个情况无法通过任务级别的条件解决。我更希望MSBuild直接跳过整个PIPLCompile目标,但在目标级别使用元数据作为条件时会报错:
error MSB4116: The condition "'%(PIPLFile.ExcludedFromBuild)'!='true'" on the "PIPLCompile" target has a reference to item metadata.
我使用的是Visual Studio 2019版本16.11.21,MSBuild版本为16.11.2.50704。以下是我当前的构建自定义代码,欢迎指出问题或给出改进建议:
r.xml
<?xml version="1.0" encoding="utf-8"?> <ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties"> <Rule Name="PIPLConfig" PageTemplate="generic" DisplayName="PiPL configuration"> <Rule.Categories> <Category Name="PIPLGeneral" DisplayName="General" /> </Rule.Categories> <Rule.DataSource> <DataSource Persistence="ProjectFile" ItemType="PIPLFile" /> </Rule.DataSource> <StringProperty Subtype="folder" Name="PIPLSDKPath" Category="PIPLGeneral" DisplayName="SDK path" Description="The path to the installed SDK." /> </Rule> <ItemType Name="PIPLFile" DisplayName="PIPL File" /> <ContentType Name="PIPLFile" ItemType="PIPLFile" DisplayName="PIPL File" /> <FileExtension Name=".r" ContentType="PIPLFile" /> </ProjectSchemaDefinitions>
r.targets(已简化)
<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <PropertyPageSchema Include="$(MSBuildThisFileDirectory)r.xml" /> <AvailableItemName Include="PIPLFile"> <Targets>PIPLCompile</Targets> </AvailableItemName> </ItemGroup> <PropertyGroup> <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> </PropertyGroup> <Target Name="PIPLCompile" Inputs="@(PIPLFile);%(PIPLFile.RootDir)%(PIPLFile.Directory)%(PIPLFile.FileName).config" Outputs="@(PIPLFile -> '$(IntDir)pipl.rr');@(PIPLFile -> '$(IntDir)Resources.pipl')" BeforeTargets="ClCompile" > <Exec Condition="'%(PIPLFile.ExcludedFromBuild)'!='true'" Command=""$(VC_ExecutablePath_x64_x64)\cl.exe" /nologo /D "PRWIN_ENV" -I "%(PIPLFile.PIPLSDKPath)\Headers" /EP "$(ProjectDir)..\%(PIPLFile.Filename).r" > "$(IntDir)pipl.rr" "%(PIPLFile.PIPLSDKPath)\Resources\PiPLtool.exe" "$(IntDir)pipl.rr" "$(IntDir)Resources.pipl"" Outputs="$(IntDir)pipl.rr;$(IntDir)Resources.pipl" /> </Target> </Project>
内容的提问来源于stack exchange,提问作者Carl Colijn

