MSBuild何时设置$(ProjectName)属性?

时间:2010-04-15 17:03:19

标签: visual-studio-2010 msbuild tfsbuild

我对MSBuild相当新,我在Wpf项目文件上做了一些自定义,我在VS2010和TFS2010中都在构建。我已按如下方式自定义输出路径:

<OutputPath Condition=" '$(TeamBuildOutDir)' == '' ">$(SolutionDir)build\binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>
<OutputPath Condition=" '$(TeamBuildOutDir)' != '' ">$(TeamBuildOutDir)binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>

这使我可以在桌面上构建时构建到集中式二进制文件目录,并允许TFS在CI构建运行时查找二进制文件。

然而,似乎在这两种情况下,$(ProjectDir)属性在构建时评估为'',这会产生奇怪的结果。进行一些调试时,看起来好像$(ProjectName)是在BeforeBuild执行时设置的,但是我的OutputPath属性在该点之前对它进行了评估。

<ProjectNameUsedTooEarly Condition=" '$(ProjectName)' == '' ">true</ProjectNameUsedTooEarly>

前面的属性与我的OutputPath属性位于同一属性组中。在BeforeBuild目标中,$(ProjectNameUsedTooEarly)的计算结果为true,但$(ProjectName)在此时正常评估项目名称。

我可以做些什么来确保$(ProjectName)在我使用它时得到一个值?

编辑:我刚刚使用Attrice的MSBuild Sidekick来调试我的构建文件,并且在第一个可用于断点的目标(_CheckForInvalidConfigurationAndPlatform)中,似乎已经设置了所有属性。 ProjectName已正确设置,但我的OutputPath属性已使用ProjectName的空白值设置。

1 个答案:

答案 0 :(得分:24)

嗯 - 那里有一点混乱,我会试着理清

  1. 不要使用$(ProjectDir) - 使用$(MSBuildProjectDir) - 这是源代码树中csproj的位置,并由MSBuild.exe设置为保留属性。我认为$(ProjectDir)在导入Microsoft.Common.Targets之后才可用(由Microsoft.Csharp.targets完成)。属性评估始终在文件中“就地”执行,而不是在所有Imports完成后执行。这可以解释为什么您在SideKick工具中看到该属性有效

  2. 同样使用$(MSBuildProjectName)(我认为这将解决您的问题)

  3. 我不确定VS2010和TFS2010(因为它使用的是MSBuild 4.0,毫无疑问是一个新的TeamBuild),但在2008年,在.csproj中很难确定你的构建是否是从命令中调用的行/ IDE构建或从TeamBuild中。我想说的是我认为你的csproj中没有$(TeamBuildOutDir)。我通常测试$(TeamBuildConstants)属性,因为当teambuild调用你的proj文件时,该属性传递的。 YMMV因为我还没有玩过2010年..