自从我开始将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
的目录的绝对路径?
答案 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)导入标签允许使用通配符。这样就可以导入文件 - 换句话说,扩展构建过程 - 只需将其放在特定位置,并且不编辑现有文件。