如何创建MSBuild .proj文件的公共存储库?

时间:2009-08-09 12:17:59

标签: msbuild

自从我开始将MSBuild用于我们的项目以来,我创建了几个由我们的存储库中的多个项目共享的.proj脚本。所有这些共享脚本都位于一个目录中。

到目前为止,我一直在使用相对路径来指代共享脚本,如下所示:

<MSBuild Projects="..\..\common\build\MyScriptA.proj" Properties="ABC=XYZ"/>

但是,每个项目还会导入一个常见的.proj脚本,如下所示:

<Import Project="..\..\common\build\CommonImports.proj"/>

<Import>其他几件事并定义了一些属性。

今天早上我想我可以用变量替换相对路径,可能是$(CommonDir),这可以通过导入上面提到的CommonImports.proj来定义。这将使我能够调用这样的常见任务:

<MSBuild Projects="$(CommonDir)\MyScriptA.proj" Properties="ABC=XYZ"/>

但是,我无法找到一种方法来定义此$(CommonDir)变量,使其在导入CommonImports.proj的所有其他MSBuild脚本中都能正常工作,而不管它们的位置如何。< / p>

This question提供了几种创建包含来自相对路径的绝对路径的属性的方法,但如果我所做的只是<Import>定义属性的脚本,那么这些方法似乎都不起作用。

问题1 :我对MSBuild相当新鲜;有没有更好的方法来创建可以通过<MSBuild>任务运行的可重用.proj脚本的“库”?我知道$(MSBuildExtensionsPath),但我希望常见任务驻留在我的结帐中,这样我们的构建机器会在执行结账时自动获取最新版本的常见任务。

问题2 :如何在$(CommonDir)中定义CommonImports.proj,以使其包含包含CommonImports.proj的目录的绝对路径?

3 个答案:

答案 0 :(得分:2)

我想知道你是不是应该把它放在MSBuild路径中:

例如,this project通过以下方式消费:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

并将其自身安装到:

{program files}\MSBuild\MSBuildCommunityTasks

那么也许定义你自己的特定子文件夹,并从那里使用?

<Import Project="$(MSBuildExtensionsPath)\romkyns\CommonImports.proj"/>

等。因为$MSBuildExtensionsPath变量是单独定义的,所以你不应该有这么多困难。也许

答案 1 :(得分:1)

这对我们来说最有效。

首先,将所有可重用的内容签入VCS中的/common/build/目录。

然后,添加/common/build/CommonImports.proj,看起来像这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         ToolsVersion="4.0">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  <Import Project="ILMerge.proj"/>
  <Import Project="Mage.proj"/>
  <Import Project="InnoSetup.proj"/>
  <UsingTask TaskName="RT.Tasks.AssemblyVersion" AssemblyFile="Tasks\Release\RT.Tasks.dll"/>
  <UsingTask TaskName="RT.Tasks.WaitForProcessesToTerminate" AssemblyFile="Tasks\Release\RT.Tasks.dll"/>
  <PropertyGroup>
    <BuildSingleProj>$(Root)\common\build\BuildSingle.proj</BuildSingleProj>
  </PropertyGroup>
</Project>

这会导入一切使用的项目和任务,并定义一切共享的属性组。然后,在每个构建脚本中添加它:

<PropertyGroup>
  <Root>..\..</Root>
  [... other global properties ...]
</PropertyGroup>
<Import Project="$(Root)\common\build\CommonImports.proj"/>

答案 2 :(得分:1)

这不是一个详细的答案,但这里有一些注意事项,当人们解决这个问题时,它们通常非常有用。所有都需要MSBuild 4.0或更高版本。

(1)$(MSBuildThisFile)属性和类似属性。它允许导入的文件引用相对于自身的文件,而不是引入它们导入的项目。这会将它们与导入的项目分开。

(2)“GetDirectoryNameOfFileAbove”功能。见here。这个非常有用的功能使项目可以导入他们不知道位置的文件。将源文件顶部的共享文件(或从其他地方导入其他文件的单个存根共享文件)放在源树的顶部。然后在它下面的项目中使用此函数来查找存根并导入它,从而导入所有共享构建过程。

(3)导入标签允许使用通配符。这样就可以导入文件 - 换句话说,扩展构建过程 - 只需将其放在特定位置,并且不编辑现有文件。