哇,这是一个论坛帖子加载的问题。我在我的book中编写了大约20页关于创建可重用的.targets文件,但我会从这里开始介绍这里的基础知识。我认为,关键是制造可重复使用的构建脚本(即.targets文件)是三个要素:
- 地方行为(即目标)为独立的文件
- 将数据(IE属性和物品,这些被称为.proj文件)到自己的文件
- 扩展
- .targets文件应该验证假设
这个想法是,你想把所有的目标放在单独的文件中,然后这些文件将被导入构建过程的文件导入。这些是包含数据的文件。由于您导入.targets文件,因此您可以获得所有目标,就好像它们已经内联定义一样。 .proj和.targets文件之间会有一个无声的合同。该合同在两者都使用的属性和项目中定义。这是需要验证的。
这里的想法并不新鲜。该模式后面跟着.csproj(以及由Visual Studio生成的其他项目)。如果你看看你的.csproj文件,你不会找到一个目标,只是属性和项目。然后朝文件底部输入Microsoft.csharp.targets(可能因项目类型而异)。该项目文件(以及其他导入文件)包含实际执行构建的所有目标。
因此它奠定了这样的:
- SharedBuild.targets
- myProduct的。凸出
凡MyProdcut.proj可能看起来像:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This uses a .targets file to off load performing the build -->
<PropertyGroup>
<Configuration Condition=" '$(Configuration)'=='' ">Release</Configuration>
<OutputPath Condition=" '$(OutputPath)'=='' ">$(MSBuildProjectDirectory)\BuildArtifacts\bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Projects Include="$(MSBuildProjectDirectory)\..\ClassLibrary1\ClassLibrary1.csproj"/>
<Projects Include="$(MSBuildProjectDirectory)\..\ClassLibrary2\ClassLibrary2.csproj"/>
<Projects Include="$(MSBuildProjectDirectory)\..\ClassLibrary3\ClassLibrary3.csproj"/>
<Projects Include="$(MSBuildProjectDirectory)\..\WindowsFormsApplication1\WindowsFormsApplication1.csproj"/>
</ItemGroup>
<Import Project="SharedBuild.targets"/>
</Project>
而且SharedBuild.targets可能看起来像:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This represents a re-usable build file -->
<Target Name="SharedBuild_Validate">
<!-- See http://sedodream.com/2009/06/30/ElementsOfReusableMSBuildScriptsValidation.aspx for more info
about this validation pattern
-->
<ItemGroup>
<_RequiredProperties Include ="Configuration">
<Value>$(Configuration)</Value>
</_RequiredProperties>
<_RequiredProperties Include ="OutputPath">
<Value>$(OutputPath)</Value>
</_RequiredProperties>
<_RequiredItems Include="Projects">
<RequiredValue>%(Projects.Identity)</RequiredValue>
<RequiredFilePath>%(Projects.Identity)</RequiredFilePath>
</_RequiredItems>
</ItemGroup>
<!-- Raise an error if any value in _RequiredProperties is missing -->
<Error Condition="'%(_RequiredProperties.Value)'==''"
Text="Missing required property [%(_RequiredProperties.Identity)]"/>
<!-- Raise an error if any value in _RequiredItems is empty -->
<Error Condition="'%(_RequiredItems.RequiredValue)'==''"
Text="Missing required item value [%(_RequiredItems.Identity)]" />
<!-- Validate any file/directory that should exist -->
<Error Condition="'%(_RequiredItems.RequiredFilePath)' != '' and !Exists('%(_RequiredItems.RequiredFilePath)')"
Text="Unable to find expeceted path [%(_RequiredItems.RequiredFilePath)] on item [%(_RequiredItems.Identity)]" />
</Target>
<PropertyGroup>
<BuildDependsOn>
SharedBuild_Validate;
BeforeBuild;
CoreBuild;
AfterBuild;
</BuildDependsOn>
</PropertyGroup>
<Target Name="Build" DependsOnTargets="$(BuildDependsOn)"/>
<Target Name="BeforeBuild"/>
<Target Name="AfterBuild"/>
<Target Name="CoreBuild">
<!-- Make sure output folder exists -->
<PropertyGroup>
<_FullOutputPath>$(OutputPath)$(Configuration)\</_FullOutputPath>
</PropertyGroup>
<MakeDir Directories="$(_FullOutputPath)"/>
<MSBuild Projects="@(Projects)"
BuildInParallel="true"
Properties="OutputPath=$(_FullOutputPath)"/>
</Target>
</Project>
不要看SharedBuild_Validate
太多目标呢。我在那里提供完整性,但不关注它。你可以在我的博客http://sedodream.com/2009/06/30/ElementsOfReusableMSBuildScriptsValidation.aspx找到更多信息。
要注意的重要部分是可扩展性点。尽管这是一个非常基本的文件,但它具有可重复使用的.targets文件的所有组件。您可以通过传递不同的属性和项目来构建它的行为。你可以扩展它的行为通过覆盖目标(BeforeBuild
,AfterBuild
甚至CoreBuild
),你可以注入自己的目标,为构建具有:
<Project ...>
...
<Import Project="SharedBuild.targets"/>
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
CustomAfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target Name="CustomAfterBuild">
<!-- Insert stuff here -->
</Target>
</Project>
在你的情况我想创建它使用一个SvnExport.targets文件所需的属性:
- SvnExportRoot
- SvnUrl
- SvnWorkingDirectory 您将使用这些属性做出口。
然后为Biztalk构建和部署创建另一个。如有必要,你可以将它分成2个。
然后在您的.proj文件中,您只需导入并设置目标以按正确顺序构建,然后关闭。
这仅仅是创造可重复使用的构建元素的开始,但这应该让轮子在你头上转动。我将把所有这些发布到我的blog以及下载所有文件的链接。
UPDATE:
发表于http://sedodream.com/2010/03/19/ReplacingSolutionFilesWithMSBuildFiles.aspx
由于博客上的可重复使用的目标这篇全面的入门!这会给我一个很好的起点。我认为我尝试的问题是我试图混合驱动构建和可重用的.targets的.proj。 – Filburt
是否有任何“简单”的方法来强制所有包含的.proj文件中的元素?我的意思是,如果包含像 这样的项目,您可能会包含未与自定义目标连接的项目。 OH和@filburt,你应该看看Sayed的书,这是值得的每一分钱! :) –
JohannesH
@JohannesH我会说有一个简单的方法,但它有点太多,打包成评论。也许签出[我的回答良好实践:如何重用.csproj和.sln文件来创建您的MSBuild脚本的CI?](http://stackoverflow.com/a/3071804/205233) - “项目”部分。基本上只包括你的全球进口在最外面的范围,并添加到这个集合。 – Filburt