如何在使用其他规则的属性时设置自定义构建规则的输出属性?
我设法用VS2008构建自定义构建规则并在VS2010中升级它。
但我有一个问题在VS2010中使用规则的输出属性。
基本上,我添加了一个自定义属性名称OutputSubDir(String),我想在Outputs属性中使用它,就像这样:$(Target)%(OutputSubDir)%(Filename).txt
当我为OutputSubDir设置默认值(在props文件中)时,我的自定义构建规则即使我为项目中的选定项目设置了一个新值,也使用了这个值。
唯一的方法,我让MSBuild使用新的一个是覆盖Outputs属性(使用相同的值)作为默认值!)
看起来像:
- 项目项有输出属性,然后使用项目项的OutputSubDir属性
- Project Item没有Outputs属性,使用Project的Outputs属性然后在同一位置使用OutputSubDir属性输出属性(即:在项目级别=默认值)
看起来MSBuild不允许对其项目进行多态性。
您是否知道我如何配置属性,规则和/或目标以使用良好的值来生成输出?
你知道VS2013问题是否仍然存在吗?
我可以提供样本文件(.props,.xml& .targets)但是很长时间才将它们直接放在问题中。 (我不知道是否可以在这里上传它们)
以下是文件:
TestRule.xml
Hi,
I manage to build a custom build rule with VS2008 and upgrade it in VS2010.
But I have a problem with the Outputs Property of the Rule in VS2010.
Basically, I add a custom property name OutputSubDir (String) and I want to use it in the Outputs property like this : $(Target)%(OutputSubDir)%(Filename).txt
When I put a default value (in the props file) for OutputSubDir, my Custom Build Rule used this value even if I set a new one for the selected item in the project.
The only way, I made MSBuild use the new one is to override the Outputs property as well (using the same value as the default one !)
It looks like :
- Project Item has Outputs property, then use the OutputSubDir Property of the Project Item
- Project Item does not have Outputs property, use the Outputs property of the Project then use the OutputSubDir property at the same location of the Outputs property (i.e.: at the Project level = default value)
It looks like MSBuild does not allow Polymorphism on its Items.
Do you have any idea how can I configure the properties, the rule, and/or the target to make the Outputs using the good value ?
Do you know if the problem still exists with VS2013 ?
I can provide sample files (.props, .xml & .targets) but there are quite long to put them directly in the question. (and I don't know if it is possible to upload them here)
Here are the files :
TestRule.xml
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback">
<Rule
Name="TestRule"
PageTemplate="tool"
DisplayName="Test Rule"
Order="200">
<Rule.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType="TestRule" />
</Rule.DataSource>
<Rule.Categories>
<Category
Name="General">
<Category.DisplayName>
<sys:String>General</sys:String>
</Category.DisplayName>
</Category>
<Category
Name="Command Line"
Subtype="CommandLine">
<Category.DisplayName>
<sys:String>Command Line</sys:String>
</Category.DisplayName>
</Category>
</Rule.Categories>
<StringListProperty
Name="Inputs"
Category="Command Line"
IsRequired="true"
Switch=" ">
<StringListProperty.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType="TestRule"
SourceType="Item" />
</StringListProperty.DataSource>
</StringListProperty>
<StringProperty
Name="OutputSubDir"
Category="General"
HelpContext="0"
DisplayName="Output SubDir"
Description="Sub Folder of $(Target) where output file should be"
Switch="[value]" />
<StringProperty
Name="CommandLineTemplate"
DisplayName="Command Line"
Visible="False"
IncludeInCommandLine="False" />
<DynamicEnumProperty
Name="TestRuleBeforeTargets"
Category="General"
EnumProvider="Targets"
IncludeInCommandLine="False">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute Before</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run before.</sys:String>
</DynamicEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name="Exclude"
Value="^TestRuleBeforeTargets|^Compute" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence="ProjectFile"
HasConfigurationCondition="true" />
</DynamicEnumProperty.DataSource>
</DynamicEnumProperty>
<DynamicEnumProperty
Name="TestRuleAfterTargets"
Category="General"
EnumProvider="Targets"
IncludeInCommandLine="False">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute After</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run after.</sys:String>
</DynamicEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name="Exclude"
Value="^TestRuleAfterTargets|^Compute" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType=""
HasConfigurationCondition="true" />
</DynamicEnumProperty.DataSource>
</DynamicEnumProperty>
<StringListProperty
Name="Outputs"
DisplayName="Outputs"
Visible="True"
IncludeInCommandLine="False"/>
<StringProperty
Name="ExecutionDescription"
DisplayName="Execution Description"
IncludeInCommandLine="False" />
<StringListProperty
Name="AdditionalDependencies"
DisplayName="Additional Dependencies"
Visible="False"
IncludeInCommandLine="False" />
<StringProperty
Subtype="AdditionalOptions"
Name="AdditionalOptions"
Category="Command Line"
Visible="False">
<StringProperty.DisplayName>
<sys:String>Additional Options</sys:String>
</StringProperty.DisplayName>
<StringProperty.Description>
<sys:String>Additional Options</sys:String>
</StringProperty.Description>
</StringProperty>
</Rule>
<ItemType
Name="TestRule"
DisplayName="Test Rule" />
<FileExtension
Name="*.ext"
ContentType="TestRule" />
<ContentType
Name="TestRule"
DisplayName="Test Rule"
ItemType="TestRule" />
</ProjectSchemaDefinitions>
TestRule.props
TestRule.props
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup
Condition="'$(TestRuleBeforeTargets)' == '' and '$(TestRuleAfterTargets)' == '' and '$(ConfigurationType)' != 'Makefile'">
<TestRuleBeforeTargets>Midl</TestRuleBeforeTargets>
<TestRuleAfterTargets>CustomBuild</TestRuleAfterTargets>
</PropertyGroup>
<PropertyGroup>
<TestRuleDependsOn
Condition="'$(ConfigurationType)' != 'Makefile'">_SelectedFiles;$(TestRuleDependsOn)</TestRuleDependsOn>
</PropertyGroup>
<ItemDefinitionGroup>
<TestRule>
<CommandLineTemplate>
ECHO OutputDir should be $(TargetDir)[OutputSubDir]%(Filename).txt
</CommandLineTemplate>
<Outputs>$(TargetDir)%(OutputSubDir)%(Filename).txt</Outputs>
<ExecutionDescription>Test Rule</ExecutionDescription>
</TestRule>
</ItemDefinitionGroup>
</Project>
TestRule.targets
TestRule.targets
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PropertyPageSchema
Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
<AvailableItemName
Include="TestRule">
<Targets>_TestRule</Targets>
</AvailableItemName>
</ItemGroup>
<UsingTask
TaskName="TestRule"
TaskFactory="XamlTaskFactory"
AssemblyName="Microsoft.Build.Tasks.v4.0">
<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>
</UsingTask>
<Target
Name="_TestRule"
BeforeTargets="$(TestRuleBeforeTargets)"
AfterTargets="$(TestRuleAfterTargets)"
Condition="'@(TestRule)' != ''"
DependsOnTargets="$(TestRuleDependsOn);ComputeTestRuleOutput"
Outputs="%(TestRule.Outputs)"
Inputs="%(TestRule.Identity);%(TestRule.AdditionalDependencies);$(MSBuildProjectFile)">
<ItemGroup
Condition="'@(SelectedFiles)' != ''">
<TestRule
Remove="@(TestRule)"
Condition="'%(Identity)' != '@(SelectedFiles)'" />
</ItemGroup>
<ItemGroup>
<TestRule_tlog
Include="%(TestRule.Outputs)"
Condition="'%(TestRule.Outputs)' != '' and '%(TestRule.ExcludedFromBuild)' != 'true'">
<Source>@(TestRule, '|')</Source>
</TestRule_tlog>
</ItemGroup>
<Message
Importance="High"
Text="%(TestRule.ExecutionDescription)" />
<Message
Importance="High"
Text="OutputSubDir = %(TestRule.OutputSubDir)" />
<Message
Importance="High"
Text="Outputs = %(TestRule.Outputs)" />
<WriteLinesToFile
Condition="'@(TestRule_tlog)' != '' and '%(TestRule_tlog.ExcludedFromBuild)' != 'true'"
File="$(IntDir)$(ProjectName).write.1.tlog"
Lines="^%(TestRule_tlog.Source);@(TestRule_tlog->'%(Fullpath)')" />
<TestRule
答
(Target)%(OutputSubDir)%(Filename).txt
When I put a default value (in the props file) for OutputSubDir, my Custom Build Rule used this value even if I set a new one for the selected item in the project.
The only way, I made MSBuild use the new one is to override the Outputs property as well (using the same value as the default one !)
It looks like :
- Project Item has Outputs property, then use the OutputSubDir Property of the Project Item
- Project Item does not have Outputs property, use the Outputs property of the Project then use the OutputSubDir property at the same location of the Outputs property (i.e.: at the Project level = default value)
It looks like MSBuild does not allow Polymorphism on its Items.
Do you have any idea how can I configure the properties, the rule, and/or the target to make the Outputs using the good value ?
$b $b
Do you know if the problem still exists with VS2013 ?
I can provide sample files (.props, .xml & .targets) but there are quite long to put them directly in the question. (and I don’t know if it is possible to upload them here)
Here are the files :
TestRule.xml
(Target)%(OutputSubDir)%(Filename).txt
When I put a default value (in the props file) for OutputSubDir, my Custom Build Rule used this value even if I set a new one for the selected item in the project.
The only way, I made MSBuild use the new one is to override the Outputs property as well (using the same value as the default one !)
It looks like :
- Project Item has Outputs property, then use the OutputSubDir Property of the Project Item
- Project Item does not have Outputs property, use the Outputs property of the Project then use the OutputSubDir property at the same location of the Outputs property (i.e.: at the Project level = default value)
It looks like MSBuild does not allow Polymorphism on its Items.
Do you have any idea how can I configure the properties, the rule, and/or the target to make the Outputs using the good value ?
Do you know if the problem still exists with VS2013 ?
I can provide sample files (.props, .xml & .targets) but there are quite long to put them directly in the question. (and I don't know if it is possible to upload them here)
Here are the files :
TestRule.xml
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback">
<Rule
Name="TestRule"
PageTemplate="tool"
DisplayName="Test Rule"
Order="200">
<Rule.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType="TestRule" />
</Rule.DataSource>
<Rule.Categories>
<Category
Name="General">
<Category.DisplayName>
<sys:String>General</sys:String>
</Category.DisplayName>
</Category>
<Category
Name="Command Line"
Subtype="CommandLine">
<Category.DisplayName>
<sys:String>Command Line</sys:String>
</Category.DisplayName>
</Category>
</Rule.Categories>
<StringListProperty
Name="Inputs"
Category="Command Line"
IsRequired="true"
Switch=" ">
<StringListProperty.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType="TestRule"
SourceType="Item" />
</StringListProperty.DataSource>
</StringListProperty>
<StringProperty
Name="OutputSubDir"
Category="General"
HelpContext="0"
DisplayName="Output SubDir"
Description="Sub Folder of
(Target) where output file should be\"
Switch=\"[value]\" />
<StringProperty
Name=\"CommandLineTemplate\"
DisplayName=\"Command Line\"
Visible=\"False\"
IncludeInCommandLine=\"False\" />
<DynamicEnumProperty
Name=\"TestRuleBeforeTargets\"
Category=\"General\"
EnumProvider=\"Targets\"
IncludeIn CommandLine=\"False\">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute Before</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run before.</sys:String>
</DynamicEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name=\"Exclude\"
Value=\"^TestRuleBeforeTargets|^Compute\" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence=\"ProjectFile\"
HasConfigurationCondition=\"true\" />
</DynamicEnumProperty.DataSource>
</DynamicEnumProperty>
<DynamicEnumProperty
Name=\"TestRuleAfterTargets\"
Category=\"General\"
EnumProvider=\"Targets\"
IncludeInCommandLine=\"False\">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute After</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run after.</sys:String>
</Dynam icEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name=\"Exclude\"
Value=\"^TestRuleAfterTargets|^Compute\" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence=\"ProjectFile\"
ItemType=\"\"
HasConfigurationCondition=\"true\" />
</DynamicEnumProperty.D ataSource>
</DynamicEnumProperty>
<StringListProperty
Name=\"Outputs\"
DisplayName=\"Outputs\"
\t Visible=\"True\"
IncludeInCommandLine=\"False\"/>
<StringProperty
Name=\"ExecutionDescription\"
DisplayName=\"Execution Description\"
IncludeInCommandLine=\"False\" />
<StringListProperty
an>Name=\"AdditionalDependencies\"
DisplayName=\"Additional Dependencies\"
Visible=\"False \"
IncludeInCommandLine=\"False\" />
<StringProperty
Subtype =\"AdditionalOptions\"
Name=\"AdditionalOptions\"
Category=\"Command Line\"
pan>
Visible=\"False\">
<StringProperty.DisplayName>
<sys:String>Additional Options</sys:String>
</StringProperty.DisplayName>
<StringProperty.Description>
<sys:String>Additional Options</sys:String>
</StringProperty.Description>
</StringProperty>
</Rule>
<ItemType
Name=\"TestRule\"
DisplayName=\"Test Rule\" />
<FileExtension
Name=\"*.ext\"
ContentType=\"TestRule\" />
<ContentType
pan> Name=\"TestRule\"
DisplayName=\"Test Rule\"
ItemType=\"TestRule\" />
</ProjectSchemaDefinitions>
(Target) where output file should be"
Switch="[value]" />
<StringProperty
Name="CommandLineTemplate"
DisplayName="Command Line"
Visible="False"
IncludeInCommandLine="False" />
<DynamicEnumProperty
Name="TestRuleBeforeTargets"
Category="General"
EnumProvider="Targets"
IncludeInCommandLine="False">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute Before</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run before.</sys:String>
</DynamicEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name="Exclude"
Value="^TestRuleBeforeTargets|^Compute" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence="ProjectFile"
HasConfigurationCondition="true" />
</DynamicEnumProperty.DataSource>
</DynamicEnumProperty>
<DynamicEnumProperty
Name="TestRuleAfterTargets"
Category="General"
EnumProvider="Targets"
IncludeInCommandLine="False">
<DynamicEnumProperty.DisplayName>
<sys:String>Execute After</sys:String>
</DynamicEnumProperty.DisplayName>
<DynamicEnumProperty.Description>
<sys:String>Specifies the targets for the build customization to run after.</sys:String>
</DynamicEnumProperty.Description>
<DynamicEnumProperty.ProviderSettings>
<NameValuePair
Name="Exclude"
Value="^TestRuleAfterTargets|^Compute" />
</DynamicEnumProperty.ProviderSettings>
<DynamicEnumProperty.DataSource>
<DataSource
Persistence="ProjectFile"
ItemType=""
HasConfigurationCondition="true" />
</DynamicEnumProperty.DataSource>
</DynamicEnumProperty>
<StringListProperty
Name="Outputs"
DisplayName="Outputs"
Visible="True"
IncludeInCommandLine="False"/>
<StringProperty
Name="ExecutionDescription"
DisplayName="Execution Description"
IncludeInCommandLine="False" />
<StringListProperty
Name="AdditionalDependencies"
DisplayName="Additional Dependencies"
Visible="False"
IncludeInCommandLine="False" />
<StringProperty
Subtype="AdditionalOptions"
Name="AdditionalOptions"
Category="Command Line"
Visible="False">
<StringProperty.DisplayName>
<sys:String>Additional Options</sys:String>
</StringProperty.DisplayName>
<StringProperty.Description>
<sys:String>Additional Options</sys:String>
</StringProperty.Description>
</StringProperty>
</Rule>
<ItemType
Name="TestRule"
DisplayName="Test Rule" />
<FileExtension
Name="*.ext"
ContentType="TestRule" />
<ContentType
Name="TestRule"
DisplayName="Test Rule"
ItemType="TestRule" />
</ProjectSchemaDefinitions>
TestRule.props
TestRule.props
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup
Condition="'
(TestRuleBeforeTargets)' == '' and '
(TestRuleBeforeTargets)' == '' and '