在Delphi中建立一个大型软件系统

发布于 2024-12-28 09:48:13 字数 1498 浏览 1 评论 0原文

我们有一个已有大约 16 年历史的软件包。它几乎适用于所有版本的 Delphi(除了 .NET 版本)。多年来,当涉及到交叉引用和保持附加包(如第三方库)的正确设置时,事情变得非常混乱。我想知道在保持像这样的大型项目(和项目组)组织性方面是否有一些标准实践

因此,解释一下当前的设置...

这是一个多应用程序系统。这意味着,涉及 12 个可执行项目(以及一些 DLL 和服务项目)。我们还将内容保存在 SourceSafe 中,并且多个开发人员在不同的计算机上处​​理相同的代码。所有这些项目都被转储到一个中央文件夹中。 “Root”文件夹包含主要的 EXE 项目(以及大约 20 个文件夹,所有文件夹都包含单元和表单),它几乎看起来像是一个无尽的文件夹和文件层次结构。仅这个项目就涉及 50 万行代码。

那么所有附加应用程序不一定与这个主要项目正确分离。每个项目都有自己的文件夹,位于主项目的根目录中。

我最关心的两个问题是:

  • 如何正确设置 DCU 文件,以免它们与项目混合在一起? DCU 不应放置在 SourceSafe(以及任何类似的文件)或从项目编译的任何文件中。 Visual SourceSafe 在未检出文件时将其设置为只读,并且在这种情况下无法写入 DCU 文件(以及 EXE 文件等)。那么如何正确地将任何此类文件分离到远程位置以避免与源代码发生任何混合呢?
  • 如何正确设置包和库?我们有以下内容:
    • QuickReports 5.05
    • NativeJpg 库 V302 -
    • 另一个匿名报告库
    • 我们自己的组件包,需要QuickReports、NativeJpg和其他匿名库

这 4 个库都存储在每台计算机完全不同的位置,需要一定的集中化。设置每个新开发人员的计算机的最大困难是从主要开发人员的计算机中找到这些文件并将它们复制到每台其他计算机上的相同位置(并确保库路径正确等)。

我们还需要在同一台计算机上为不同版本的 Delphi 保留完全独立的环境。这意味着每台计算机上的项目副本、每台计算机上的包和库的副本、SourceSafe 中的项目、包和库的副本等。每台计算机都需要具有相同的设置。我们已经利用环境变量来指导我们的项目在哪里查找某些项目文件(和库)。

另一个新问题:XE2 引入了 64 位功能。我们还不打算进行 64 位编译,但我们将来肯定会这样做。如何在所有这些项目中正确区分 32 位和 64 位?

我真正要求的是关于如何优化这样的环境并使其保持最佳组织状态的良好教程的参考。我不希望有人花时间回答问题中的所有这些。这些项目已有超过 15 年的历史,拥有来自世界各地 200 多名开发人员,并且项目之间有大量的交叉引用。例如,一个项目可以使用另一项目的单元,反之亦然。我个人不喜欢这个概念,但它也不是我设计的。我的任务是组织这个系统并详细记录如何在新计算机上设置 Delphi,以便新开发人员处理我们的项目。当我查看我们的项目时(因为我不一定是系统的开发人员,但我正在参与开发),我发现代码的组织方式存在很多混乱。

我假设 Embarcadero 可能有一些关于建立这样的环境的指导方针和标准?

We have a software package which is about 16 years old. It's gone through just about every version of Delphi (besides .NET ones). Over the years, things have become very confusing when it comes to cross-referencing and keeping proper setup for additional packages (like third-party libraries). I was wondering if there is some standard practice when it comes to keeping large projects (and groups of projects) like this organized.

So to explain the current setup...

This is a multi-application system. Meaning, there are 12 executable projects (and a few DLL and service projects) involved. We also keep things in SourceSafe and multiple developers work on the same code on different computers. All of these projects are more-so dumped into a central folder. The "Root" folder contains THE major EXE project (along with about 20 folders, all containing units and forms) and it almost seems like an endless hierarchy of folders and files. This one project alone has half a million lines of code involved.

Then all the additional applications aren't necessarily separated properly from this major project. Each of these projects has its own folder based in the main project's root.

The two major concerns of mine are:

  • How to properly set up the DCU files so that they aren't mixed in with the projects? DCU's should NOT be placed in the SourceSafe (and any similar file, for that matter) or otherwise, any file compiled from the project. Visual SourceSafe makes files read-only when they're not checked out, and DCU files (and EXE files and more) cannot be written to in this case. So how to properly separate any of such file to a remote location to avoid any mixture with the source code?
  • How to properly set up packages and libraries? We have the following:
    • QuickReports 5.05
    • NativeJpg library V302 -
    • Another anonymous reporting library
    • Our own component package, which requires QuickReports, NativeJpg, and the other anonymous library

All 4 of those libraries are stored in completely different places of each computer, and need some centralization. The biggest pain of setting up each new developer's computer is locating these from the lead developer's computer and copying them to the same place on each other computer (and making sure the library path is correct, etc.).

We also need to keep completely separate environments for different versions of Delphi on the same computer. This means a copy of the projects on each computer, a copy of packages and libraries on each computer, a copy of the projects and packages and libraries in the SourceSafe, etc. Each computer needs to have an identical setup. We already utilize environment variables to direct our projects where to look for certain project files (and libraries).

Another new concern: XE2 introduces 64bit capabilities. We don't plan on 64bit compiling yet, but we certainly will in the future. How do I properly differentiate 32bit from 64bit in all these projects?

What I'm really asking for is a reference to a good tutorial on how to optimize such an environment and keep it organized the best. I don't expect anyone to take the time and answer all this in the question. The projects are over 15 years old, have had the hands of 200+ developers from around the world in it, and has a LOT of cross-referencing between projects. For example, one project may use a unit from another project, and vice-versa. I personally don't like this concept, but I also didn't design it to begin with. I've been given the task to get this system organized and thoroughly documented how to set up Delphi on a new computer for new developers to work on our projects. As I'm looking at our projects (as I'm not necessarily a developer of the system, but am being pulled into development), I'm seeing a lot of confusion in how the code is organized.

I am assuming that possibly Embarcadero has some guidelines and standards on setting up such an environment?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

酷炫老祖宗 2025-01-04 09:48:13

DCU 文件的位置

对于作为编译过程输出的 DCU,您应该在每个项目文件中指定一个 DCU 输出目录。在最新版本的 Delphi 中,默认值就可以了:.\$(Platform)\$(Config)。这会产生如下项目目录的子文件夹:Win32\DEBUGWin64\RELEASE

如果您使用选项集设置项目文件,那么您将能够通过少量选项文件控制此设置(以及所有其他设置)。

第 3 方代码的位置

您应该始终使用第 3 方库作为代码。如果供应商收取更多费用以接收代码形式的库,请付款。完成此操作后,您只需将源代码包含到版本控制系统 (VCS) 中,并以与对待自己的代码大致相同的方式对待它。我说主要是因为你应该避免修改它。

一旦您将所有代码放入 VCS 中,您就可以通过一次检出操作将整个源代码放到新机器上。

项目的组织

我个人非常厌恶使用编译器搜索路径。我不使用它们,而是将项目所需的每个单元都包含在 .dpr 文件中。

如果您确实使用搜索路径,那么您就无法处理变体项目。例如,假设您的客户发现您 2 年前发布的软件版本中存在错误。您希望通过发布该软件 2 年前版本的升级来解决该错误。完全有理由要求他们升级到最新版本是不可行的。也许他们还没有支付升级费用。也许全面升级有一些他们现在不想解决的重大变化。一个完美的例子是所有仍在使用 Delphi 7 的 Delphi 开发人员。

现在,在激发了该场景之后,您将如何为这个已有 2 年历史的项目创建构建环境?如果您使用搜索路径,那么它们将引用当今的库。您将被迫更改搜索路径,或者将旧库复制到当今的库之上。

通过不使用搜索路径并将所有源代码包含在版本控制系统中,可以轻松避免整个令人头疼的问题。

您的目标应该是能够检查程序的任何历史版本并立即构建它。您应该能够完全放心地执行此操作,因为您正在构建与该版本发布时构建的软件相同的软件。这还要求您具有构建自动化,但我无法想象您对于这种规模的项目缺乏这种自动化。

Location of DCU files

Regarding the DCUs that are the output of the compilation process, you should specify a DCU output directory in each project file. The default value for this, in the latest version of Delphi would be fine: .\$(Platform)\$(Config). This results in sub-folders of the project directory like this: Win32\DEBUG or Win64\RELEASE.

If you set-up your project files using option sets then you will be able to control this setting (and all others) from a small number of option files.

Location of 3rd party code

You should always use 3rd party library as code. If the vendor charges more to receive the library as code, pay up. Once you have done so you simply include the source code into your version control system (VCS) and treat it largely the same way as you treat your own code. I say largely because you should avoid modifying it.

Once you have all your code in the VCS then you can put the entire source code onto a new machine with a single checkout operation.

Organisation of your projects

I personally have a strong aversion to using compiler search paths. I don't use them and include every unit that is required in a project in the .dpr file.

If you do use search paths then you make it impossible to work on variant projects.So for example, suppose you have a client that has discovered a bug in the version of the software you released 2 years ago. You would like to address that bug by releasing an upgrade to the 2 year old version of the software. It is perfectly plausible that asking them to upgrade to the latest version is not viable. Perhaps they have not paid for the upgrades. Perhaps the full upgrade has breaking changes that they do not want to tackle right now. A perfect example would be all the Delphi developers still using Delphi 7.

Now, having motivated the scenario, how would you create a build environment for the 2 year old project? If you are using search paths then they will refer to today's libraries. You would be forced to change your search path, or copy the old libraries over the top of today's libraries.

That entire headache is trivially side-stepped by not using search paths and by including all your source in the VCS.

What you should be aiming for is to be able to checkout any historic version of your program and have it build immediately. You should be able to do this with full confidence that you are building identical software to what was built at the time that version was released. This also requires you to have build automation but I can't imagine you are lacking that for a project of this size.

胡渣熟男 2025-01-04 09:48:13

我将讨论文件夹组织。它来自一个软件套件,其中包含 50 多个 exe 和 dll 以及大量第三方库,所以我想我知道您来自哪里...

我们使用 Perforce 作为源代码控制系统,所以我的默认工作区的根文件夹称为 Perforce ,但我还设置了几个其他工作区,它们位于 Perforce2、Perforce3 等中。

常规文件夹设置(从工作区根文件夹开始)

General
  Components
    Delphi
      Indy
        Indy9
        Indy10
      MadCollection
        v2.5.8.0
        v2.6.0.0
  Plugins
Releases
  Released
  ... a folder for each release we publish ... (and equal to a branch in Perforce)
Work
  Acceptance
  Sub1
  Sub2

IDE 中的我的环境库路径为空(甚至不是 BDE 标准路径)都在里面)。这可确保项目的路径声明所需的所有路径,并且项目不依赖于特定计算机的 IDE 设置。

我们在 IDE 中设置了一个指向“General\Components\Delphi”的环境变量(即 MRJ),因此在项目选项中我们将组件的路径声明为 $(MRJ)\MadCollection\2.6.0.0

General 包含我们项目使用的 IDE 插件和组件。我们将使用的所有版本保留在源代码管理中。这样,当我必须切换回旧版本来追踪问题时,我可以简单地拉取它并构建它,因为它的库路径仍然指向该特定版本所需的组件版本。

特定工作分支(Acceptance 或其子分支之一)中的文件夹组织遵循以下模式:

General          
  Includes
  MainComponent1
    Project1
    Project2
    Shared
  MainComponent2  
    Project3
    Project4
    Shared
  Shared
Windows          
  SoftwareSuite  
    Scripts
      Tools
  MainComponent1
    Project1
      Dcus
    Project2
      Dcus
  MainComponent2  
  Tools
    Tool1
      Dcus
    Tool2
      Dcus

General 文件夹保存所有平台独立源/文件,Windows 文件夹保存所有 Windows 特定文件。每个组件可以容纳多个项目,并且将有一个共享文件夹,用于在这些项目之间共享源。 General 正下方的共享文件夹保存了所有项目共享的源代码。 Windows 文件夹的设置方式类似。

请注意,每个项目都有自己的 dcus 文件夹。这是在项目选项中配置的。由于路径可以输入为 .dcus,因此我们(至少我)将其设置为任何新项目的默认路径。每个项目将其 dcus 发送到唯一的文件夹可以确保两件事:

  • 只需在版本控制软件中设置过滤器,即可轻松使 dcu 脱离版本控制。
  • 更重要它确保项目的编译/构建永远不会干扰另一个项目的编译/构建。我可以安全地更改设置并构建,因为我知道我不会被另一个项目的先前构建中的 dcu 所困扰。

I'll address folder organisation. This comes from a software suite which has 50+ exe's and dll's and plenty third party libraries, so I guess I know where you are coming from...

We use Perforce as a source control system, so my default workspace's root folder is called Perforce, but I also have a couple of other workspaces set up and they are in Perforce2, Perforce3, etc.

General folder setup (starting from the workspace root folder)

General
  Components
    Delphi
      Indy
        Indy9
        Indy10
      MadCollection
        v2.5.8.0
        v2.6.0.0
  Plugins
Releases
  Released
  ... a folder for each release we publish ... (and equal to a branch in Perforce)
Work
  Acceptance
  Sub1
  Sub2

My Environment library path in the IDE is empty (not even the BDE standard paths are in there). This ensures that a project's paths declare all path's needed and that projects are not reliant upon a particular machine's IDE setup.

We have an environment var (ie MRJ) set up in our IDE's that points to "General\Components\Delphi" so in a project's options we declare the paths to our components as $(MRJ)\MadCollection\2.6.0.0.

General holds IDE plugins and components used by our projects. We keep all versions we use in source control. That way when I have to switch back to an old release to track down a problem, I can simply pull it and build it as its library paths will still point to the version of the components that this specific release needs.

The organisation of folders in a particular work branch (Acceptance or one of its subbranches) follows this pattern:

General          
  Includes
  MainComponent1
    Project1
    Project2
    Shared
  MainComponent2  
    Project3
    Project4
    Shared
  Shared
Windows          
  SoftwareSuite  
    Scripts
      Tools
  MainComponent1
    Project1
      Dcus
    Project2
      Dcus
  MainComponent2  
  Tools
    Tool1
      Dcus
    Tool2
      Dcus

The General folder holds all platform independent sources/files, the Windows folder holds all Windows specific files. Each component can hold multiple projects and will have a share folder for sources shared between those projects. The shared folder directly under General holds sources shared by all projects. The Windows folder is set up in a similar manner.

Note that each project has its own dcus folder. This is configured in the project options. As the path can be entered as .dcus, we (at least I) have this set up as the default for any new project. Each project sending its dcus to a unique folder ensures two things:

  • it is easy to keep dcu's out of version control by simply setting up a filter in your version control software.
  • more importantly it ensures that compilation/build of a project never interferes with the compilation/build of another project. I can safely change settings and build knowing that I won't be bothered by dcu's lying around from a previous build from another project.
挽梦忆笙歌 2025-01-04 09:48:13

我建议采用以下做法:

  1. 保持库路径简单,并确保库路径中的所有内容都是 delphi 附带的文件夹,或者是 d:\Components\ 文件夹中的 DCU 二进制(库)文件夹。< /p>

  2. 使用现代类型的版本控制。我推荐 Mercurial 胜过其他人。 Source Safe 是垃圾,停止使用它。

  3. 备份您的环境(导出注册表项等)并以标准化方式将其恢复到其他开发人员 PC。您可以保留一些 .reg 和 .cmd(批处理)文件来自动设置新系统。您可以将这些脚本放入版本控制系统的组件存储库中。

I recommend the following practices:

  1. Keep your library path simple, and make sure everything in the library path is either a folder that ships with delphi, or a DCU binary (library) folder in your d:\Components\ folder.

  2. Use a MODERN type of version control. I recommend Mercurial over others. Source Safe is crap, stop using it.

  3. Back up your environment (export registry keys etc) and restore it to the other developer PCs in a standardized way. You can keep a few .reg and .cmd (batch) files around to automate setup of a new system. you can put these scripts in your component repository in your version control system.

心如狂蝶 2025-01-04 09:48:13

在之前主要讨论的范围之外,我建议:

  • 单元测试 - 例如使用 DUnit
  • 持续集成。只是为了确保所有这些项目都可以在另一台机器上编译并且测试没问题。

所以这与项目组织和 VCS 策略密切相关。

Outside the scope that was largely discuss before, I would recommend :

  • Unit testing - with DUnit for example
  • Continuous integration. Just to be sure that all these projects can compile on another machine and that tests are ok.

So this is heavily related to project organization and VCS strategy.

記柔刀 2025-01-04 09:48:13

对于类似的设置,我工作的一家公司发现此配置很有用:

  • 所有第三方库(组件等)都转到固定位置(C:\Delphi\name-version)
  • Delphi 项目可以从任何地方的版本控制中检出(驱动器 C: 或 D: 且文件夹名称并不重要),因为所有项目和脚本都使用相对路径
  • 所有项目都是一个主项目文件夹的子文件夹,因此检查此文件夹将带来 Delphi 项目和工作站的其他相关资源以及版本控制更新很容易做到,
  • 我们使用位于主文件夹中的构建脚本(用 Apache Ant 编写),并迭代所有文件夹来构建 Delphi 应用程序并运行单元和集成测试
  • 构建脚本还可以在每次提交时在构建服务器(Hudson CI)上自动运行,以查看是否有问题

关于组件库的注释:避免包安装尽可能在运行时创建组件。如果您需要快速对项目的五年前版本进行修复,卸载/安装十几个软件包可能会变得令人沮丧。至少对于非可视组件来说,运行时创建可以节省大量时间。

在源代码管理中签入第三方代码非常有帮助,例如共享尚未作为新官方版本提供的修复程序。 Subversion 文档章节中介绍了最佳实践供应商分支< /a>
另外,通过 Subversion,您可以使用 svn:externals 将特定版本(标签)直接放入项目目录结构中。这可以与第三方库和您自己的源代码一起使用,并使依赖关系管理更容易,工作站设置更容易。

ps Ant 构建脚本定义了所有内容的搜索路径,因此它是所有开发人员的“参考”如何配置 IDE、在哪里放置第三方库以及使用哪些编译器标志

p.ps 你的项目听起来很多很有趣 - 我愿意接受合同工作:)

For a similar setup, a company I worked for found this configuration useful:

  • all third party libraries (components etc.) go to a fixed location (C:\Delphi\name-version)
  • Delphi projects can be checked out from version control anywhere (drive C: or D: and folder name does not matter), as all projects and scripts use relative paths
  • all projects are sub folders of one main project folder so checking out this one will bring the Delphi projects and other relevant resources to the workstation, and a version control update is easy to do
  • we use a build script (written in Apache Ant) which sits in the main folder, and iterates over all folders to build the Delphi apps and run unit and integration tests against a development database server, to verify all changes work before checking in to source control
  • the build script can also be run automatically on a build server (Hudson CI) on every commit to see if something broke

And a note about component libraries: avoid package installation where possible, prefer creation of components at run time. If you quickly need to apply a fix to a five year old version of a project, uninstalling / installing a dozen of packages can become frustrating. At least for non-visual components, run-time creation is a huge time saver.

Checking in third party code in source control can be very helpful, for example to share fixes which are not yet available as new official releases. Best practices are covered in the Subversion documentation chapter Vendor Branches.
Plus, with Subversion you can use svn:externals to place a specific version (tag) right into a project directory structure. This can be used both with third party library and with your own source code, and makes dependency management easier and workstation setup easier.

p.s. the Ant build script defines the search paths for everything, so it is 'the reference' for all developers how to configure the IDE, where to put the third party libs and which compiler flags to use

p.p.s. your project sounds like a lot of fun - I am open for contract work :)

枕花眠 2025-01-04 09:48:13

我的团队使用虚拟化,当我们回想起来时,这确实是一个很好的举措。
我们使用 MacBook Pro 笔记本电脑和 VmWare Fusion,但我确信其他软件包也能正常工作,例如 VirtualBox 或 VirtualPC。

知道当新开发人员开始或旧安装遇到问题时,只需从主映像复制新的 VM 映像,并且设置与原始设置完全相同,这总是一种很好的感觉。主映像存储在快速 USB2 磁盘上。现在,当 Thunderbolt 和 USB3 出现时,复制图像的速度会更快。只要有内存,现代计算机就不必真正担心性能。 8 GB 应该足以并行运行 2 个图像。虚拟化的另一个优点是可以很容易地尝试假设场景。尝试不同的配置和版本,而不会有任何干扰真实工作环境的风险。

顺便说一句,我也认为 SourceSafe 很糟糕......:-)

My team use virtualization and when we see back it was a real good move.
We use MacBook Pro laptops and VmWare Fusion, but I'm sure other packages work fine as well like VirtualBox or VirtualPC.

It is always a good feeling to know that when a new developer starts or an old installation got trouble it is just to copy a new VM image from the master image and the setup is exactly as the original. The master image is stored on a fast USB2-disk. Now when Thunderbolt and USB3 is coming it would be even faster to copy an image. And there is no real concern about performance on a modern computer as long as there is memory. 8 GB should be enough to run 2 images in parallell. Another advantage of virtualization is that it is so easy to try What if scenario. Experiment with different configuarations and versions without any risk to disturb the real working environment.

Btw I also think that SourceSafe is crap... :-)

前事休说 2025-01-04 09:48:13

一些提示:

  • 为属于该项目的所有应用程序创建一个 groupproject 文件,每个应用程序都在 groupproj 文件下自己的目录中

  • 您应该能够指定要包含到版本控制系统中的文件类型。确保将 Delphi 设置为以文本格式写入 DFM 文件。

  • 您可以告诉 Delphi 在每个应用程序下名为“dcu”的子目录中输出 DCU(减少 Visaul 混乱)。

  • 第三方的东西通常坚持安装在不同的位置,对此你无能为力。制作一份文档,描述如何设置完整的工作环境并使其保持最新

  • 在虚拟机中进行开发。新开发人员获得 VM 的副本。

  • 针对不同的 Delphi 版本进行维护?重新考虑一下,尝试使用一个版本。如果您绝对必须为每个版本拥有两个组项目和目录结构。 [我假设您没有使用两个 Delphi 版本编译同一个应用程序,那是开发人员的地狱]

  • Delphi XE2 将输出到不同的 32/64 子目录,这应该不会出现问题。

Somé tips:

  • Make one groupproject file for all the apps belonging to the project, each app in its own dir under the groupproj file

  • You should be able to specify which file types to include into your version control system. Make sure you set Delphi to write DFM files in text format.

  • You could tell Delphi to output DCUs in subdirs named 'dcu' under each app (less visaul clutter).

  • Third party stuff often insists on installing in distinct locations, there's not much you can do about it. Make a document describing how to setup a complete working environment and keep it up-to-date

  • Develop in virtual machines. A new developer gets a copy of the VM.

  • Maintaining for different Delphi versions? Rethink that, try to go to one version. If you absolutely must have two groupprojects and directory structures for each version. [I'm assuming you're not compiling the same app with two Delphi version, that's developer hell]

  • Delphi XE2 will output to different 32/64 subdirectories, that should give no problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文