7

当有人构建我的解决方案时,我要运行多个任务,具体取决于解决方案配置:

  • 在发布配置中,为整个解决方案运行 Doxygen (doxygen.exe ....)
  • 在调试和发布配置中,为整个解决方案运行 StyleCop(调用 StyleCop 目标)
  • 在调试配置中,为整个解决方案运行 FxCop (fxcop.exe ...)
  • 和更多

这些都是解决方案级别(全局)任务,因此将其放在每个项目文件中对我来说没有意义。看起来这将是一个普遍的问题,那么您如何处理呢?

我在想我可以创建一个空项目,确保所有其他项目都依赖它并将所有解决方案级别的任务放在其中......?

4

5 回答 5

3

最简单的方法是创建一个名为“Build.csproj”的空项目。将它放在解决方案中并使其依赖于所有其他项目。然后对于简单的任务,您可以使用构建后事件来运行您的工具。如果您需要更高级,您可以修改项目的 Build 目标。

它有几件好事:

  1. 它简单易懂,易于设置和理解。
  2. 它通常不会干扰调试,因为您将不同的项目设置为启动。
  3. 您可以创建忽略项目的配置。
  4. 假设您坚持发布构建事件,它允许 VS 集成而不会发出警告。
于 2012-10-25T14:31:41.173 回答
3

我更喜欢将这些任务放在一个 .targets 文件中,并从我的主要项目中引用它们(大约是那些不生成库的项目)。我还可以Target在该 .targets 文件中创建 s 来组合常见任务的子集。这样,我的一些项目可以方便地运行sharedtask1and sharedtask2,而其他项目运行sharedtask1and sharedtask3,因为我只是添加DependsOnTargets="Shared12"and DependsOnTargets="Shared13"(显然,我会尝试选择描述性的名称)。

这些文章对组织您的 msbuild 任务有一些很好的建议:

创建可靠构建的最佳实践,第 1 部分

创建可靠构建的最佳实践,第 2 部分

编辑

要仅运行一次某些任务,请使用上面第二篇文章中描述的增量构建:

  • 在我上面提示的通用 .targets 文件中,创建一个任务,将所有文件作为输入,并将一些虚拟标记文件作为输出。
  • 让该任务完成您感兴趣的实际工作更新标记文件。
  • 让你所有的项目都依赖于新创建的任务

构建解决方案后,第一个项目将启动上述任务,该任务将输出一个标记文件,只要您的输入文件在构建的其余部分没有更改,该任务就不会再次运行. 现在,这样做的缺点是

  • 如果您的构建导致在此过程中生成或更改文件,则该任务将运行多次
  • 即使您只构建单个项目,该任务也会运行。如果您正在生成文档,这实际上可能是“正确”的行为。如果你想避免这种情况,我认为你必须对你的 msbuild 文件进行真正的微调,但我觉得这就是你想要避免的。
  • 该任务将在构建之前运行,因此任何依赖于要构建的程序集版本的任务都将不走运

要解决最后一个问题,您将不得不放弃从 VS 构建,而是调用自定义任务,该任务将构建解决方案,然后依次执行一个或多个自定义任务)使用命令行中的 msbuild.exe。我意识到这可能不是您正在寻找的开发人员体验。

于 2012-10-23T08:14:59.220 回答
3

这个问题假设您希望每次都构建所有内容,但实际上我并没有发现这种情况。目前,我正在与之合作的团队对构建时间非常敏感。

因此,我建议您不要将构建视为单一事物,而应将其视为具有多种风格。有“它建立了吗?” 构建,为此我会将构建选择(仅限当前项目)映射到一个键,直到我开始使用 reshaper。对于不进行单元测试的人(包括那些开发不可测试的 ui 更改的人),有一个“让我们测试它构建”,如果当然还有“Everything and the kitchen sink build”,文档、stylecop 和任何其他指标都可以获得。

出于这个原因,我建议使用构建服务器。将您的其他目标放在一边,并在您完成所有其他工作后使用它们。我会推荐 TeamCity 的预测试提交功能,这是一种让您的团队能够测试他们不会中断并构建故障条件(例如覆盖率降低)的好方法。

此外,如果您在开发时正在寻找更快速的构建,那么我建议使用 NCrunch,它具有高度优化的构建过程,可以在您编辑文件或 ContinuousTests 后一秒左右运行。

于 2012-10-25T08:18:54.710 回答
1

在我们的解决方案中,我们将此类构建操作放在我们的启动项目中,因为我们不想将它放在每个项目中,并且我们正在运行的项目引用所有其他项目。因此,在该项目的构建后操作上运行的所有操作都将在所有其他项目已经完成之后完成。

于 2012-10-28T05:00:57.277 回答
1

也许我遗漏了一些东西,但为什么不创建一个解决方案文件夹,其中包含对选定目标执行构建后续任务的各种脚本,并从项目的构建后事件中调用它们?IE

  • PostBuildScripts(解决方案文件夹)
    • FxCop.Debug.Target
    • FxCop.Release.Target
    • StyleCop.Release.Target
    • StyleCop.Release.Target
    • Doxygen.Debug.Target
    • Doxygen.Release.Target
    • Others.Release.Target
    • Others.Release.Target

... ETC ...

这些脚本调用以针对目标构建类型运行您的后续任务;如果您实际上不想针对某个构建类型运行它,只需将其留空即可。

在您的项目中进行后期构建:

/PostBuildScripts/FxCop.$(ConfigurationName).Target

/PostBuildScripts/Doxygen.$(ConfigurationName).Target

/PostBuildScripts/StyleCop.$(ConfigurationName).Target

/PostBuildScripts/Others.$(ConfigurationName).Target

... ETC ...

于 2012-10-25T17:26:59.263 回答