我在我的msbuild项目中有以下定义......
<MSBuild
Projects="$(MSBuildProjectFile)"
Condition="'@(FilesToCompile)' != ''"
Targets="buildcpp"
Properties="CPPFILE=%(FilesToCompile.FullPath);OBJFILE=$(ObjectFolder)\%(FilesToCompile.Filename).doj;IncludeDirs=$(IncludeDirs)"
/>
......然后是目标的定义。
注意目标的定义如何包含对另一个目标compilecpp
...
<Target Name="buildcpp">
<PropertyGroup>
<CompileDefines Condition="'$(PreprocessorDefinitions)' != ''">-D$(PreprocessorDefinitions.Replace(";"," -D"))</CompileDefines>
</PropertyGroup>
<Exec
EchoOff="true"
StandardOutputImportance="low"
StandardErrorImportance="low"
IgnoreExitCode="true"
ConsoleToMSBuild="true"
Command='
"$(CompilerExe)" ^
$(HWProcessor) ^
$(IncludeDirs) ^
$(CompilerOptions) ^
$(CompileDefines) ^
"$(CPPFILE)" ^
-MM
'>
<Output TaskParameter="ConsoleOutput" PropertyName="output_cppdeps"/>
<Output TaskParameter="ExitCode" PropertyName="exitcode_cppdeps"/>
</Exec>
<MSBuild
Projects="$(MSBuildProjectFile)"
Condition="'$(exitcode_cppdeps)' == '0'"
Targets="compilecpp"
Properties="INPUTFILES=$(BuildCppDeps)"
/>
</Target>
...使用属性$(OBJFILE)
,即使它从未被调用者传入
<Target Name="compilecpp" Inputs="$(INPUTFILES)" Outputs="$(OBJFILE)">
<Message Importance="high" Text="$(CPPFILE): Compiling..."/>
...
问题
由于这个msbuild有效,我可以推断$(OBJFILE)
是可访问的;为什么可以访问?属性的范围规则是什么?
答案 0 :(得分:1)
使用Data not found
任务时,执行新的msbuild运行,类似于使用参数运行<MSBuild>
。特别是,传递属性类似于传递msbuild.exe
参数 - 它定义了新的&#34;全局属性&#34;为了这次运行。
在此内部构建期间,该属性仍然存在,并且可以通过其他内部构建(buildcpp - &gt; compilecpp)访问,除非被覆盖。因此/p:PropName=Value
只能在OBJFILE
中访问,因为它被定义为父msbuild运行的全局属性。如果以某种方式直接调用compilecpp
,则不会定义该属性(假设它未在其他位置设置)。如果要停止转发全局属性,则需要使用MSBuild任务的compilecpp
参数。因此,如果您设置RemoveProperties
,那么它就不会被用作。
Fyi,在.NET核心项目中,RemoveProperties="OBJFILE"
用于不将RemoveProperties
从自包含的应用转发到引用的项目,这些项目可能无法使用此属性集构建(到期)缺少恢复信息)。
有关详细信息,请阅读properties documentation - 尤其是有关全局属性的部分 - 以及MSBuild Task documentation(重要部分是RuntimeIdentifier
参数的说明)。但是,传递全局属性这一事实并未明确记录(尽管Properties
暗示)。
更新: documentation for global properties已更新,以描述此行为:
全局属性也会转发给子项目,除非 MSBuild任务的RemoveProperties属性用于指定 不转发的职业清单。