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

时间:2023-01-13 12:12:36

There seems to be two major conventions for organizing project files and then many variations.

Convention 1: High-level type directories, project sub-directories

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

For example, the wxWidgets project uses this style:

例如,wxWidgets项目使用以下样式:

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

Pros:

  • If there are project dependencies, they can be managed from a single file
  • 如果存在项目依赖项,则可以从单个文件管理它们

  • Flat build file structure
  • 平面构建文件结构

Cons:

  • Since test has its own header and cpp files, when you generate the unit test applications for EXE files rather than libraries, they need to include the object files from the application you are testing. This requires you to create inference rules and expand out relative paths for all the source files.
  • 由于test有自己的头文件和cpp文件,因此当您为EXE文件而不是库生成单元测试应用程序时,他们需要包含您正在测试的应用程序中的目标文件。这需要您创建推理规则并扩展所有源文件的相对路径。

  • Reusing any of the projects in another solution requires you to extract the proper files out of the tree structure and modify any build scripts
  • 重用另一个解决方案中的任何项目需要您从树结构中提取适当的文件并修改任何构建脚本

Convention 2: High-level project directories, type sub-directories

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

For example, the Wireshark project uses this style

例如,Wireshark项目使用此样式

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

Pros:

  • Projects themselves are self-contained within their folders, making them easier to move and reuse
  • 项目本身在其文件夹中是自包含的,使其更易于移动和重用

  • Allows for shorter inference rules in the build tools
  • 允许在构建工具中使用更短的推理规则

  • Facilitates hierarchical build scripts
  • 促进分层构建脚本

Cons:

  • If there are dependencies between projects, you need an additional layer of build scripts above the project directories to manage the build order
  • 如果项目之间存在依赖关系,则需要在项目目录上方添加一层构建脚本来管理构建顺序

We are currently using convention 1 on our project and so far it has worked fairly well. Now, I am in the process of adding unit testing (via CxxTest) and facilitating the migration to continuous integration using nmake, convention 1 is causing some serious headaches in the creation of the proper nmake files.

我们目前正在使用我们项目的惯例1,到目前为止它已经运作得相当好。现在,我正在添加单元测试(通过CxxTest)并使用nmake促进向持续集成的迁移,约定1在创建正确的nmake文件时引起了一些严重的麻烦。

My primary requirements/goals are:

  • Reduce the level of effort to maintain the build scripts of the entire solution.

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

  • De-couple projects and their build steps within a solution from other projects.

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

  • Facilitate continuous integration via the use of build scripts for check-out to release media generation for each commit (obviously leveraging other tools such as CruiseControl as well).

    通过使用构建脚本进行签出以便为每次提交释放媒体生成,从而促进持续集成(显然也利用其他工具,如CruiseControl)。

  • Make adding or removing additional projects or source files as easy and least error-prone as possible for the developers.

    为开发人员添加或删除其他项目或源文件尽可能简单且最不容易出错。

So I ask:

  • Are there other pros and cons of either of these methods?
  • 这两种方法都有其他优缺点吗?

  • Is there a clear agrument that favors only one of these conventions?
  • 有没有一个明确的agrument只赞成这些约定之一?

2 个解决方案

#1


4  

[A partial answer.]

[部分回答。]

In "Convention 2: High-level project dirs, type sub-directories," your single con is

在“第2号公约:高级项目目录,键入子目录”中,您的单一内容是

If there are dependencies between projects, you need an additional layer of build scripts above the project directories to manage the build order

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

That can also be viewed as a pro, in many projects.

在许多项目中,这也可以被视为专业人士。

If you have a lot of repetitive general definitions, one would probably want an include file for the build scripts, where solution-wide constants & parameters could be defined. So the "additional layer of build scripts" will frequently happen anyway, even if there are no (direct) dependencies.

如果您有许多重复的通用定义,那么可能需要构建脚本的包含文件,其中可以定义解决方案范围的常量和参数。因此,即使没有(直接)依赖项,“构建脚本的附加层”也会经常发生。

It's a pro in that there's still room for a more modular approach in building. On the other hand, if you want to reuse a project in another, unrelated solution, you would need to compose a different definitions file. (On the other other hand, if there were a single build file for the whole solution, as in Convention 1, you would need a different build script.) As for your maintenance requirement, that's (IMO) very project-dependent.

这是一个专业人士,因为在建筑方面还有更多模块化方法的空间。另一方面,如果要在另一个不相关的解决方案中重用项目,则需要编写不同的定义文件。 (另一方面,如果整个解决方案只有一个构建文件,就像在第1条中那样,你需要一个不同的构建脚本。)至于你的维护需求,那个(IMO)非常依赖项目。

My feeling leans towards Convention 2, but it's far from a clear win. In fact, your experience with Convention 1, which was working well until recently, may be the biggest pro of all: a team of people with experience with a certain organization is a valuable asset.

我的感觉倾向于第2号公约,但它远非明显的胜利。事实上,您在第一次会议上的体验可能是最重要的职业选手:拥有某个组织经验的团队是一项宝贵的资产。

#2


1  

Consider using NTFS junction points so you can have both organizations at once. Quick definition: "a junction point is Microsoft's implementation of symbolic links but it only works for directories."

考虑使用NTFS交接点,这样您就可以同时拥有这两个组织。快速定义:“联结点是Microsoft的符号链接实现,但它只适用于目录。”

Use Convention 2 for the "real" layout, because it makes the projects easy to move around. Then make a Convention 1 view:

使用Convention 2进行“真实”布局,因为它使项目易于移动。然后制作一个公约1视图:

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

Now you have ...

现在你有......

/solution
  /test
    /prj1
    /prj2 

... which was the desired result.

......这是理想的结果。

You could do the same thing for /src or the other directories if you find it beneficial. Test scripts that benefit from a Convention 1 view live in /solution/test.

如果你觉得它有用,你可以为/ src或其他目录做同样的事情。受益于Convention 1视图的测试脚本位于/ solution / test中。

#1


4  

[A partial answer.]

[部分回答。]

In "Convention 2: High-level project dirs, type sub-directories," your single con is

在“第2号公约:高级项目目录,键入子目录”中,您的单一内容是

If there are dependencies between projects, you need an additional layer of build scripts above the project directories to manage the build order

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

That can also be viewed as a pro, in many projects.

在许多项目中,这也可以被视为专业人士。

If you have a lot of repetitive general definitions, one would probably want an include file for the build scripts, where solution-wide constants & parameters could be defined. So the "additional layer of build scripts" will frequently happen anyway, even if there are no (direct) dependencies.

如果您有许多重复的通用定义,那么可能需要构建脚本的包含文件,其中可以定义解决方案范围的常量和参数。因此,即使没有(直接)依赖项,“构建脚本的附加层”也会经常发生。

It's a pro in that there's still room for a more modular approach in building. On the other hand, if you want to reuse a project in another, unrelated solution, you would need to compose a different definitions file. (On the other other hand, if there were a single build file for the whole solution, as in Convention 1, you would need a different build script.) As for your maintenance requirement, that's (IMO) very project-dependent.

这是一个专业人士,因为在建筑方面还有更多模块化方法的空间。另一方面,如果要在另一个不相关的解决方案中重用项目,则需要编写不同的定义文件。 (另一方面,如果整个解决方案只有一个构建文件,就像在第1条中那样,你需要一个不同的构建脚本。)至于你的维护需求,那个(IMO)非常依赖项目。

My feeling leans towards Convention 2, but it's far from a clear win. In fact, your experience with Convention 1, which was working well until recently, may be the biggest pro of all: a team of people with experience with a certain organization is a valuable asset.

我的感觉倾向于第2号公约,但它远非明显的胜利。事实上,您在第一次会议上的体验可能是最重要的职业选手:拥有某个组织经验的团队是一项宝贵的资产。

#2


1  

Consider using NTFS junction points so you can have both organizations at once. Quick definition: "a junction point is Microsoft's implementation of symbolic links but it only works for directories."

考虑使用NTFS交接点,这样您就可以同时拥有这两个组织。快速定义:“联结点是Microsoft的符号链接实现,但它只适用于目录。”

Use Convention 2 for the "real" layout, because it makes the projects easy to move around. Then make a Convention 1 view:

使用Convention 2进行“真实”布局,因为它使项目易于移动。然后制作一个公约1视图:

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

Now you have ...

现在你有......

/solution
  /test
    /prj1
    /prj2 

... which was the desired result.

......这是理想的结果。

You could do the same thing for /src or the other directories if you find it beneficial. Test scripts that benefit from a Convention 1 view live in /solution/test.

如果你觉得它有用,你可以为/ src或其他目录做同样的事情。受益于Convention 1视图的测试脚本位于/ solution / test中。