MSBuild 属性范围 [英] MSBuild Property Scope
问题描述
我又一次与 MSBuild 作斗争.我想要一个用根路径定义的属性值.作为构建的一部分,路径将使用版本信息进行更新.但是,MSBuild 似乎有自己的范围规则,这些规则似乎完全倒退了.举第一个例子:
Once again I'm battling MSBuild. I want to have a property value defined with a root path. As part of the build, the path will get updated with version information. However, MSBuild seems to have its own scoping rules that seem completely backwards. Take this first example:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<MyPath>\serverfolder</MyPath>
</PropertyGroup>
<Target Name="Main">
<Message Text="In Main Before - MyPath = $(MyPath)"/>
<CallTarget Targets="Task1" />
<CallTarget Targets="Task2" />
<CallTarget Targets="Task3" />
<Message Text="In Main After - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task1">
<PropertyGroup>
<MyPath>$(MyPath)version5</MyPath>
</PropertyGroup>
<Message Text="In Task1 - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task2">
<Message Text="In Task2 - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task3">
<Message Text="In Task3 - MyPath = $(MyPath)"/>
</Target>
</Project>
以下是此命令行的输出:msbuild PropertyScopeTest1.proj/target:Main
Here's the output with this command line: msbuild PropertyScopeTest1.proj /target:Main
Project "C:TempPropertyScopeTest1.proj" on node 1 (Main target(s)).
Main:
In Main Before - MyPath = \serverfolder
Task1:
In Task1 - MyPath = \serverfolderversion5
Task2:
In Task2 - MyPath = \serverfolderversion5
Task3:
In Task3 - MyPath = \serverfolderversion5
Main:
In Main After - MyPath = \serverfolder
Done Building Project "C:TempPropertyScopeTest1.proj" (Main target(s)).
现在,在 Main 目标中设置 MyPath 变量的版本略有不同:
Now, here's a slightly different version setting the MyPath variable in the Main target:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<MyPath>\serverpath</MyPath>
</PropertyGroup>
<Target Name="Main">
<Message Text="In Main Before - MyPath = $(MyPath)"/>
<PropertyGroup>
<MyPath>$(MyPath)version5</MyPath>
</PropertyGroup>
<Message Text="In Main After PropertyGroup - MyPath = $(MyPath)"/>
<CallTarget Targets="Task1" />
<CallTarget Targets="Task2" />
<CallTarget Targets="Task3" />
<Message Text="In Main After - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task1">
<Message Text="In Task1 - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task2">
<Message Text="In Task2 - MyPath = $(MyPath)"/>
</Target>
<Target Name="Task3">
<Message Text="In Task3 - MyPath = $(MyPath)"/>
</Target>
</Project>
以下是此命令行的输出:msbuild PropertyScopeTest2.proj/target:Main
Here's the output with this command line: msbuild PropertyScopeTest2.proj /target:Main
Project "C:TempPropertyScopeTest2.proj" on node 1 (Main target(s)).
Main:
In Main Before - MyPath = \serverpath
In Main After PropertyGroup - MyPath = \serverpathversion5
Task1:
In Task1 - MyPath = \serverpath
Task2:
In Task2 - MyPath = \serverpath
Task3:
In Task3 - MyPath = \serverpath
Main:
In Main After - MyPath = \serverpathversion5
Done Building Project "C:TempPropertyScopeTest2.proj" (Main target(s)).
我查看了此站点上的其他类似链接,但似乎都在从 MSBuild 项目文件中调用 MSBuild 任务.我想要做的就是更新路径并让它在项目中的任何地方都可用.有什么想法吗?
I've looked at other links on this site that are similar, but all seem to be calling the MSBuild task from within the MSBuild project file. All I want to do is update the path and have it available everywhere in the project. Any ideas?
推荐答案
基于 sll 的回答,使设置新路径的目标成为依赖项而不是使用 CallTarget
将产生预期的行为:
Building on sll's answer, making the target that sets the new path a dependency instead of using CallTarget
will yield the expected behaviour:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<MyPath>\serverfolder</MyPath>
</PropertyGroup>
<Target Name="Main" DependsOnTargets="SetMyPathProperty">
<Message Text="In Main Before - MyPath = $(MyPath)"/>
<CallTarget Targets="Task1" />
<Message Text="In Main After - MyPath = $(MyPath)"/>
</Target>
<Target Name="SetMyPathProperty">
<PropertyGroup>
<MyPath>$(MyPath)version5</MyPath>
</PropertyGroup>
</Target>
<Target Name="Task1">
<Message Text="In Task1 - MyPath = $(MyPath)"/>
</Target>
</Project>
构建输出:
Main:
In Main Before - MyPath = \serverfolderversion5
Task1:
In Task1 - MyPath = \serverfolderversion5
Main:
In Main After - MyPath = \serverfolderversion5
使 SetMyPathProperty 成为 Task1 而不是 Main 的依赖项将导致与您的 PropertyScopeTest1.proj 相同的行为.
Making SetMyPathProperty a dependency of Task1 instead of Main will result in identical behaviour to your PropertyScopeTest1.proj.
这篇关于MSBuild 属性范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!