如何使用nmake为C++项目组织项目树?

17

组织项目文件有两种主要惯例,以及许多变体。

惯例1:高层次的类型目录,项目子目录

例如,wxWidgets 项目采用这种风格:

/solution
   /bin
      /prj1
      /prj2
   /include
      /prj1
      /prj2
   /lib
      /prj1
      /prj2
   /src
      /prj1
      /prj2
   /test
      /prj1
      /prj2

优点:

  • 如果项目有依赖项,它们可以从单个文件中管理
  • 扁平的构建文件结构

缺点:

  • 由于测试有其自己的头文件和cpp文件,当你为EXE文件而不是库生成单元测试应用程序时,它们需要包含来自你正在测试的应用程序的目标文件。这要求您创建推理规则并展开所有源文件的相对路径。
  • 在另一个解决方案中重用任何项目都需要从树形结构中提取出正确的文件并修改任何构建脚本

惯例2:高级项目目录,类型子目录

例如,Wireshark 项目使用此风格

/solution
   /prj1
      /bin
      /include
      /lib
      /src
      /test
   /prj2
      /bin
      /include
      /lib
      /src
      /test

优点:

  • 项目本身被封装在文件夹中,易于移动和重用
  • 构建工具中的推理规则变短
  • 有助于建立分层式的构建脚本

缺点:

  • 如果项目之间存在依赖关系,则需要在项目目录之上添加另一层构建脚本来管理构建顺序。

我们目前正在使用方法1进行项目开发,效果不错。现在,我正在添加单元测试(通过CxxTest实现)以及使用nmake实现持续集成,但方法1在创建适当的nmake文件时会遇到一些严重问题。

我的主要需求/目标是:

  • 降低整个解决方案构建脚本的维护工作量。

  • 将解决方案中的项目及其构建步骤与其他项目分离。

  • 通过使用构建脚本从检出到发布媒体生成为每个提交实现持续集成(显然还利用其他工具如CruiseControl等)。

  • 为开发者尽可能地简化添加或删除其他项目或源文件的过程,同时减少错误。

因此我问:

  • 这两种方法是否还有其他优缺点?
  • 有没有明确的论点支持仅采用其中一种约定?

我删除了关于使用Lakos的书的原始答案,因为它实际上并没有回答问题。不过我仍然推荐这本书:《大规模C++软件设计》。 - grieve
谢谢,这本书已经在我的亚马逊阅读愿望清单上了 =] - Zach Burlingame
2个回答

4

[部分答案。]

在“Convention 2: High-level project dirs, type sub-directories”中,您唯一的缺点是

如果项目之间存在依赖关系,则需要在项目目录上方添加另一层构建脚本以管理构建顺序

在许多项目中,这也可以视为优点。

如果有很多重复的通用定义,则可能希望为构建脚本使用包含文件,其中可以定义解决方案范围内的常量和参数。因此,“构建脚本的附加层”通常会发生,即使没有(直接)依赖关系。

它的优点在于在构建时仍有更多的模块化方法。另一方面,如果您想在另一个不相关的解决方案中重用项目,则需要组合不同的定义文件。 (另一方面,如果整个解决方案都有单个构建文件,如Convention 1中所示,则需要不同的构建脚本。)至于维护要求,那是(我认为)非常依赖于项目的。

我的感觉倾向于Convention 2,但远非明显的胜利。实际上,您对Convention 1的经验一直很好,直到最近,这可能是最大的优点:具有某种组织经验的团队是一项宝贵的资产。


我完全同意Con实际上可以成为Pro的说法。我正在努力想出它的缺点,但其中一些可能是因为我更熟悉Convention 1的原因。 - Zach Burlingame

1

考虑使用NTFS连接点,这样您就可以同时拥有两个组织。快速定义:“连接点是微软对符号链接的实现,但仅适用于目录。”

使用Convention 2来进行“真实”布局,因为它使得项目易于移动。然后创建一个Convention 1视图:

mkdir /solution/test
linkd /solution/test/prj1 /solution/prj1/test
linkd /solution/test/prj2 /solution/prj2/test

现在您已经...

/solution
  /test
    /prj1
    /prj2 

... 这就是期望的结果。

如果您认为有益,您可以对 /src 或其他目录执行相同的操作。从 Convention 1 视图受益的测试脚本位于 /solution/test 中。


1
一个有趣的想法,但它存在一些问题。首先,正确维护“真实”和“链接”树是不可取的。更重要的是,SVN(以及大多数Windows应用程序,包括Explorer.exe)不能正确处理硬链接或联接,并可能导致不良命令结果。 - Zach Burlingame
1
很遗憾,连接点(符号链接)并不像在*nix上那样成为Windows“文化”的一部分,因为它们确实可以简化某些任务。希望随着时间的推移,它们的应用程序和工具支持会得到改善。 - j_random_hacker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接