如何正确地将Delphi项目划分为BPL?

发布于 2024-11-29 02:18:04 字数 2525 浏览 1 评论 0原文

我工作的公司用Delphi开发了一个系统,包含几十个exe模块,每个模块的源代码都有一定程度的相同。遗憾的是,没有人关心使用库来放入共享代码。这意味着每次在所有这些模块共享的代码中需要修复错误时,程序员都必须分别对所有模块进行更正!总是需要很多时间......

我决定找到一种方法将共享代码放入库中。我考虑过 DLL 和 BPL。在这种情况下,BPL 似乎对程序员更加友好并且麻烦也少得多,特别是该代码仅在我们的软件中且仅在 Delphi 中使用。

我将所有 exe 模块共享的所有代码放入 BPL 中,一切看起来都很好,但有些事情我不明白,如果您向我解释它们,我将不胜感激。

  1. 将代码划分为 BPL 后,我的预期是用我创建的 BPL 部署 exe 文件就足够了。但事实证明他们还需要 rtl100.bpl 和 vcl100.bpl。为什么会这样呢?我只想部署 exe 和我的 BPL。我不想向最终用户提供由 Borland 和第三方公司提供的一大堆库:)。我希望它们在 exe 中编译,就像以前编译它们一样。可以这样做吗?

  2. 到目前为止我所做的是:

    • 我将所有共享 pa 单位放入 BPL。每个 BPL 都包含属于同一类别的单元,因此程序员很清楚在给定的 BPL 中需要什么代码。
    • 每个 BPL 都是一个“运行时和设计时”库。
    • 每个 BPL 都是“显式重建”的。 后两者是 BPL 的默认项目设置。
  3. 如果涉及到 exe 项目:

    • 我删除了之前放入 BPL 的所有单元。
    • 我通过 BDS 2006 中的“工具”->“安装包”菜单安装了 BPL。
    • 在我的 exe 项目设置中,我选中了“使用运行时包构建”选项,并在下面的编辑框中列出了我的所有 BPL 包(仅列出了我的包,因为我清除了出现在那里的所有其他包)。

这就是我所做的一切。 exe 项目可以正确编译,但我无法访问 BPL 的源代码(我无法从我的 exe 项目导航到该代码),即使所有 BPL 都与其源代码文件存储在一起。为什么?我觉得很奇怪。

我总是倾向于写冗长的描述 - 对此感到抱歉:)。我会感谢你的帮助。我只需要对我提到的几点进行几句话的解释:仅使用我的 BPL 部署 exe、我作为一个整体所做的正确性以及无法导航到 BPL 源代码。预先非常感谢您!


谢谢大家的讨论。有人说我选择的方法不是一个好主意。我们的软件由 100 多个模块组成(其中大部分是不同设备的驱动程序)。它们中的大多数共享相同的代码——大多数情况下是类。问题是这些类并不总是被放入单独的、独立的 pa 单元中。我的意思是共享代码通常被放入包含特定于模块的代码的单元中。这意味着当您修复共享类中的错误时,仅将其定义的 pas 单元复制到所有软件模块中并重新编译它们是不够的。不幸的是,您必须将固定的代码片段逐一复制并粘贴到每个模块中,并粘贴到适当的单元和类中。这需要很多时间,这就是我想消除的,选择正确的方法 - 请帮助我。

我认为使用 BPL 将是一个很好的解决方案,但正如你们中的一些人提到的,它有一些缺点。最糟糕的问题是,如果每个 EXE 需要多个 BPL,我们的技术支持人员将必须知道哪个 EXE 需要哪个 BPL,然后为最终用户提供正确的文件。只要我们没有软件更新程序,这对于我们的技术人员和最终用户来说都是一件好事。他们肯定会迷路并生气:-/。

此外,还可能发生兼容性问题 - 如果一个 BPL 被许多 EXE 共享,则对一个 BPL 的修改可能对一个 EXE 有利,但对其他一些 EXE 不利 - @Warren P。

那么我应该做什么才能更快地修复错误这么多项目?我想到了以下方法之一。如果您有更好的想法,请告诉我。

  • 将共享代码放入单独且独立的 pas 单元中,因此当其中一个单元出现错误修复时,只需将其复制到所有项目(覆盖旧文件)并重新编译所有项目即可。

就后面修改的代码而言,这个解决方案似乎没问题。但我们也有具有通用功能和程序的 pas 单元,这些单元通常不进行修改 - 我们会在必要时添加新功能,但在单个项目中。因此,想象一下,您在 100 个模块之一中编写了一个新函数,并将其放入其通用单元中。一两个月后,您修改了一个不同的模块,并且您认为您需要两个月前编写的相同功能。您必须找到该模块(如果您不记得它是哪一个,那会很困难)并将该函数复制到您的代码中。显然 - 只要它们单独存储在每个项目中,每个模块中的通用单元就会变得完全不同。然后,如果需要修复错误……整个故事就会重复。

  • 为所有共享代码创建 BPL,但将它们链接到 EXE,以便 EXE 是独立的。

对我来说,这似乎是现在最好的解决方案,但也有几个缺点。如果我在 BPL 中修复错误,每个程序员都必须更新他们计算机上的 BPL。如果他们忘记了怎么办?但我仍然认为这是一个小问题。如果我们注意互相通报变化,一切都会好起来的。

  • @CodeInChaos:我不知道我是否正确理解了你。您的意思是在项目之间共享 pa 文件吗?怎么做呢?我们将源代码存储在 SVN 中。这意味着我们必须将共享代码存储在单独的文件夹中,并让所有项目在那里搜索该代码,对吗?并从SVN下载一个项目及其依赖的所有文件夹...

请帮我选择一个好的解决方案。我只是不希望公司仅仅因为愚蠢的软件开发方法而在错误修复上损失更多的时间和金钱。

非常感谢。

The company I work for develops a system in Delphi, that contains dozens of exe modules, and each of them is identical to a certain degree if it comes to source code. Sadly, nobody has ever cared about using libraries to put the shared code in. This means that each time there is a bug fix to do in the code all these modules share, a programmer has to make corrections in all of them separately! It always takes so much time...

I decided to find a method to put the shared code into libraries. I considered DLLs and BPLs. In this case BPLs seemed much more programmer-friendly and much less troublesome, especially that the code is used only in our software and only in Delphi.

I put all the code shared by all the exe modules into BPLs and everything seems fine, but there are certain things I don't understand and would be grateful if you explained them to me.

  1. What I expected after dividing the code into BPLs was that it would be enough to deploy exe files with the BPLs I created. But it turned out that they need an rtl100.bpl and vcl100.bpl as well. Why is it so? I want to deploy exes and my BPLs only. I don't want to provide end users with a whole bunch of libraries supplied by Borland and third party companies :). I want them to be compiled within exes as they used to be compiled before. Is it possible to do that?

  2. What I did so far was:

    • I put all shared pas units to BPLs. Each BPL contains units belonging to the same category so it is clear for programmers what code to expect in a given BPL.
    • Each BPL is a "runtime and designtime" library.
    • Each BPL is "rebuilt explicitly".
      The two latter are default project settings for BPLs.
  3. And if it comes to the exe projects:

    • I deleted all units that I had earlier put to BPLs.
    • I installed my BPLs from the Tools->Install package menu in BDS 2006.
    • In my exe project settings I checked the option "build with runtime packages" and I listed all my BPL packages in the edit box below (only my packages, as I cleared all other ones that appeared there).

This is all I did. The exe projects compile properly, but I have no access to the source code of BPLs (I can't navigate into that code from my exe projects), even though all BPLs are stored together with their source code files. Why? It seems strange to me.

I always tend to write lengthy descriptions - sorry for that :). I will appreciate your help. I just need a few words of explanation to the points I mentioned: deploying exe with my BPLs only, the correctness of what I did as a whole, and the inability to navigate into BPL source codes. Thank you very much in advance!


Thank you all for the discussion. Some said the approach I chose was not a good idea. Our software consists of more than 100 modules (most of them being something like drivers for different devices). Most of them share the same code - in most cases classes. The problem is that those classes are not always put into separate, standalone pas units. I mean that the shared code is often put into units containing code specific to a module. This means that when you fix a bug in a shared class, it is not enough to copy the pas unit it is defined in into all software modules and recompile them. Unfortunately, you have to copy and paste the fixed pieces of code into each module, one by one, into a proper unit and class. This takes a lot of time and this is what I would like to eliminate, choosing a correct approach - please help me.

I thought that using BPLs would be a good solution, but it has some downsides, as some of you mentioned. The worst problem is that if each EXE needs several BPLs, our technical support people will have to know which EXE needs which BPLs and then provide end users with proper files. As long as we don't have a software updater, this will be a great deal for both our technicians and end user. They will certainly get lost and angry :-/.

Also compatibility issues may happen - if one BPL is shared by many EXEs, a modification of one BPL can bee good for one EXE and bad for some other ones - @Warren P.

What should I do then to make bug fixes quicker to make in so many projects? I think of one of the following approaches. If you have better ideas, please let me know.

  • Put shared code into separate and standalone pas units, so when there is a bug fix in one of them, it is enough to copy it to all projects (overwrite the old files) and recompile all of them.

This solution seems to be OK as far as a rearly modified code is concrened. But we also have pas units with general use functions and procedures, which often undrego modifications - we add new functions there whenever necessary, but in single projects. So imagine that you write a new function in one of the 100 modules and put it into its general use unit. After a month or two you modify a different module and you think you need the same function you wrote 2 months ago. You have to find the module (it's difficult if you don't remember which one it was) and copy the function to your code. And obviously - the general use units become completely different in each module as long as they are stored in each project separately. And then, if there is a bug fix to do... the whole story repeats.

  • Create BPLs for all the shared code, but link them into EXEs, so that EXEs are standalone.

For me it seems the best solution now, but there are several cons. If I do a bug fix in a BPL, each programmer will have to update the BPLs on their computer. What if they forget? But still, I think it is a minor problem. If we take care of informing each other about changes, everything should be fine.

  • @CodeInChaos: I don't know if I understood you properly. Do you mean sharing pas files between projects? How to do that? We store source codes in SVN. This means that we would have to store shared code in a separate folder and make all projects search for that code there, right? And download from the SVN a project and all folders it is dependent on...

Please, help me choose a good solution. I just don't want the company to lose much more time and money than necessary on bugfixes just because of a stupid approach to software development.

Thank you very much.

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

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

发布评论

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

评论(4

哭了丶谁疼 2024-12-06 02:18:04

尽管这个问题有一个公认的答案,但我还是会尝试一下。

标题询问如何将项目划分为 bpls,但真正的问题似乎是:
“在项目之间共享代码的最佳方式是什么?”

有几种方法可以做到这一点:

  • 共享单元
  • Dlls
  • BPL

无论您选择哪个方向,您都可能需要重组您的项目。从您的描述来看,听起来每个项目都是相对孤立地开发的。使用复制/粘贴来共享代码,这很快就会失去同步并导致大量重复工作。因此,让我们检查一下共享代码的每种技术。

共享单元


这是最直接的方法。您创建一个共享位置,并将您想要在项目之间重用的代码放置到此位置。这些单元静态链接到您的项目中,因此您无需担心与主要可执行文件一起部署额外的依赖项。静态链接单元是迄今为止最容易排除故障和调试的单元。

编译器需要能够找到您的共享单元。有 4 种方法可以告诉编译器去哪里查找。

  1. 将它们添加到项目中 - SHIFT+F11 - 将单元引用添加到项目文件(dpr、dproj)中。如果该单元与项目文件位于同一目录树下,IDE 通常会使用相对路径,否则它将使用绝对路径,如果开发人员计算机的配置不同,这可能会出现问题。
  2. 项目的搜索路径 - CTRL+SHIFT+F11 Delphi Compiler >搜索路径 - 添加一个目录,编译器将在其中查找项目中任何单元的 use 子句中提到的单元。如果可以的话最好使用相对路径。您还可以使用环境变量:$(MyPath)
  3. 全局搜索路径 - 工具 >选项>环境选项>德尔福选项>库-Win32>库路径 - 此处列出的任何路径均可用于计算机上的所有项目。 这取决于机器
  4. 命令行 - 如果您从脚本或构建自动化工具构建,则可以使用 dcc32 的 -U 开关或 msbuild 的 /property 设置搜索路径:UnitSearchPath= 开关。

选项 1 和 2 将是最有用的。

就您的 SVN 存储库而言,您有一些组织项目和共享单元的选项。最简单的方法是将所有项目与共享单元一起放置在单个主干下:

Projects
    trunk
        ProjectA
        ProjectB
        ProjectC
        Library (shared units)

如果由于某种原因上述结构不可能,您可以尝试此替代方案:

ProjectA
    trunk
        Library (branch of main library)
ProjectB
    trunk
        Library (branch of main library)
ProjectC
    trunk
        Library (branch of main library)
Library
    trunk (main library)

在此配置中,对每个项目的库文件夹所做的更改将不会立即可用其他项目。每个项目都需要定期与主库项目同步更改。这样做的副作用是,破坏其他项目的更改将被延迟,直到其他项目同步为止。您认为这是好事还是坏事取决于。一方面,当开发人员对所涉及的代码仍然记忆犹新时,修复错误会更容易、更便宜。另一方面,如果您不练习单元测试(我强烈建议您这样做)或者代码非常脆弱,或者您的开发人员容易做出鲁莽的更改,您可能需要控制将这些更改推送到其他项目的频率。

Dlls


Dll 允许您通过在运行时链接到代码来共享代码。它们公开可以从主可执行文件或另一个 dll 调用的函数。

虽然 dll 始终在运行时链接,但您可以决定它们是在应用程序启动时加载还是仅在需要时加载。启动时加载称为静态加载,在 Delphi 中是使用 external 指令完成的。包装系统 api 调用的绝大多数 rtl/vcl 类都使用静态加载。 动态加载可以延迟 dll 的加载,直到需要时才加载。这使用了 WinAPI 函数 LoadLibrary 和 GetProcAddress。对 FreeLibrary 的相应调用将卸载 dll。

不幸的是,标准 dll 限制了可以传递的数据类型。如果您需要从非 Delphi 项目访问 dll,您将需要限制自己使用 C 风格的数据类型。如果您只将 dll 与 Delphi 项目一起使用,那么您也可以安全地使用 Delphi 字符串和动态数组,前提是您在 dll 和任何使用它的项目中使用 SharedMem 单元。

您可以安全地在 dll 中使用对象,不会出现任何问题,但如果您想在 dll 和应用程序之间传递对象,则需要提取对象的数据并将其作为原始类型传递,然后将其重新组装成另一端的对象。这称为(反)序列化或编组,并且有比自己动手更简单的方法来做到这一点。

COM(组件对象模型)在 Delphi 中得到了很好的支持,但它有一些学习曲线。使用 COM 对象非常简单,但如果您不熟悉 COM,那么设计一个对象就会花费一些时间。 COM 的优点是它是语言中立的,并且受到大多数面向 Windows 平台的语言(包括面向 .NET 框架的语言)的支持。

Bpls


Bpls(也简称为“包”)是特殊格式的 dll,可以使对象的处理变得更加容易。与标准 dll 一样,它们在运行时链接,并且可以静态或动态加载。它们比 COM dll 更容易学习和使用,并且比 COM 能够更无缝地集成到您的项目中。包由两部分组成:bpl 和 dcp。 dcp 类似于编译普通单元文件时生成的 dcu 文件,只不过它包含一大堆单元。使用在 bpl 中编译的类非常简单,只需将 dcp 添加到项目的包列表中,然后将一个单元添加到项目单元之一的 use 子句中即可。

部署应用程序时,您还需要安装 bpl。正如其他人所指出的,如果您使用任何形式,您必须至少包含 rtl 包,并且很可能包含 vcl 包。有一种方法可以在您的项目中部署 Borland 提供的 bpls。您可以创建一个“迷你”rtl 包,其中仅包含您的项目所需的单元。困难在于确定要包括哪些单位。

摘要


根据您给出的描述,创建一个共享单元文件库以进行静态链接可能是最方便的途径。我还建议尝试一个名为 Simian 的程序。它将帮助您追踪代码库中的重复代码,以便将其包含在共享库中。它不直接支持 pascal,但它使用纯文本解析器并对其配置进行了一些调整,完成了足够好的工作。

另外,我怎么强调单元测试的价值都不过分。特别是当您转向共享库时。当开发人员更改类并破坏不相关的项目时,一套频繁运行的编写良好的单元测试将为您提供即时反馈。

Even though this question has an accepted answer I'm going to take a stab at it.

The title asks how to divide a project into bpls but the real question appears to be:
"What's the best way to share code between projects?"

There are a few ways to do this:

  • Shared units
  • Dlls
  • BPLs

Regardless of which direction you go you will likely need to restructure your projects. From your description it sounds like each project is developed in relative isolation. Code is shared using copy/paste, which quickly gets out of sync and result in a lot of duplicated effort. So lets examine each of the techniques for sharing code.

Shared units


This is the most straightforward approach. You create a shared location and place code you would like to reuse among your projects into this location. The units are statically linked into your projects so you don't need to worry about deploying extra dependencies along with the main executables. Statically linked units are by far the easiest to troubleshoot and debug.

The compiler needs to be able to find your shared units. There are 4 ways to tell the compiler where to look.

  1. Add them to the project - SHIFT+F11 - Adds a reference to the unit into the project files (dpr, dproj). The IDE will normally use relative paths if the unit is located under the same directory tree as the project files, otherwise it will use absolute paths, which can be problematic if developer machines aren't configured identically.
  2. The project's Search Path - CTRL+SHIFT+F11 Delphi Compiler > Search path - Add a directory and the compiler will look there to find units mentioned in the uses clause of any unit in the project. Its best to use relative paths if you can. You can also use environment variables: $(MyPath)
  3. Global Search Path - Tools > Options > Environment Options > Delphi Options > Library - Win32 > Library Path - Any paths listed here are available to all projects on a machine. This is machine dependant
  4. Command line - If you build from a script or build automation tool you can set the search path using the dcc32's -U switch or msbuild's /property:UnitSearchPath= switch.

Options 1 and 2 will be the most useful.

As far as your SVN repository goes you have a few options for organizing the projects and shared units. The simplest would be to place all projects under single trunk along with the shared units:

Projects
    trunk
        ProjectA
        ProjectB
        ProjectC
        Library (shared units)

If for some reason the above structure isn't possible you could try this alternative:

ProjectA
    trunk
        Library (branch of main library)
ProjectB
    trunk
        Library (branch of main library)
ProjectC
    trunk
        Library (branch of main library)
Library
    trunk (main library)

In this configuration changes made to each project's library folder would not be immediately available to the other projects. Each project would need to synchronize changes with the main Library project on a regular basis. A side effect of this is that changes that break other projects will be delayed until the other projects are synchronized. Whether you consider this a good or bad thing depends. On the one hand bugs are easier and cheaper to fix when the code they involve is still fresh in the developer's mind. On the other hand if you don't practice unit testing (which I highly recommend you do) or the code is very fragile or you just have developers prone to making reckless changes you may want to control how frequently those changes get pushed into other projects.

Dlls


Dlls allow you to share code by linking to it at runtime. They expose functions that can be called from a main executable or another dll.

While dlls are always linked at runtime you decide whether they are loaded at application startup or only when needed. Loading at startup is called static loading and in Delphi is accomplished using the external directive. The vast majority of the rtl/vcl classes that wrap system api calls use static loading. Dynamic loading lets to delay the loading of a dll until it is required. This uses the WinAPI functions LoadLibrary and GetProcAddress. A corresponding call to FreeLibrary will unload a dll.

Unfortunately standard dlls limit what kind of datatypes can be passed. If you need to access a dll from non-Delphi projects you will need to limit yourself to using c style data types. If you will only be using a dll with Delphi projects you can safely use Delphi strings and dynamic arrays as well if you use the SharedMem unit in the dll and any projects that use it.

You can safely use object's within the dll without problems but if you want to pass objects between the dll and the application you'll need to extract the object's data and pass it as primitive types and reassemble it into an object on the other end. This is called (de)serialization or marshalling and there are much easier ways to do this than rolling your own.

COM (Component Object Model) is well supported in Delphi but it has a bit of a learning curve. Consuming COM objects is pretty straightforward but designing one will take time if you're not familiar with COM. COM has the advantage that it is language neutral and is supported in the majority of languages targeting the Windows platform (including languages targeting the .NET framework).

Bpls


Bpls (also called simply "packages") are specially formatted dlls that make working with objects a lot easier. Like standard dlls they are linked at runtime and can be statically or dynamically loaded. They are easier to learn and use than COM dlls and provide more seamles integration into your projects than COM. Packages are composed of two parts: the bpl and the dcp. The dcp is like the dcu files generated when you compile a normal unit file except it contains a whole bunch of units in it. Using a class that is compiled in a bpl is as simple as adding the dcp to the project's package list then adding a unit to a uses clause of one of the project's units.

When you deploy the app you'll need to install the bpl as well. As other's have noted you have to include the rtl package at a minimum and most likely the vcl package if you use any forms. There is a way around deploying Borland supplied bpls with your projects. You can create a "mini" rtl package that contains only the units your project need. The difficultly is in determining which units to include.

Summary


From the description you've given creating a library of shared unit files to statically link against may be the most expedient route. I would also suggest trying out a program called Simian. It will help you track down duplicate code in your code base for inclusion in your shared library. It doesn't directly support pascal but it does a decent enough job using the plain text parser with a little tweaking of its configuration.

Also I can't stress enough the value of unit testing. Especially if you're moving toward shared libraries. A suite of well written unit tests run on a frequent basis will give you instant feedback when a developer changes a class and it breaks an unrelated project.

榕城若虚 2024-12-06 02:18:04

想象一下,您有一个包含 EXE 和两个不同 BPL 模块的项目,并且在该代码库中的某处,有一行内容为 if MyObject is TStringList then DoSomething;is 运算符的工作原理是检查存储在 VMT 中的对象的类元数据,然后通过 ClassParent 指针跟踪 VMT 链,以查看其中是否有任何一个与TStringList 的类引用(也是 VMT 指针)。为了确保它能正常工作,TStringList 需要一个单独的 VMT,它在整个程序中都是相同的,无论它分为多少个 BPL,这意味着它必须位于自己的包中。这就是为什么像 rtl*.bpl 和 vcl*.bpl 这样的系统运行时是必要的,而您对此无能为力。这是使用 BPL 费用的一部分。

至于无法调试,您需要确保 BPL 是在启用调试信息的情况下构建的,并且调试器知道如何找到 DCP(包含 BPL 调试信息的文件)所在的文件夹。而且您将无法跟踪系统 BPL,因为您的版本未附带启用调试的 DCP。它们是最近才添加的,我想是在 XE 中,但也可能是在 D2010 中。

Imagine you have a project with an EXE and two different BPL modules, and somewhere in that codebase, there's a line that says if MyObject is TStringList then DoSomething;. The is operator works by examining the object's class metadata, stored in the VMT, and then following a chain of VMTs through the ClassParent pointer, to see if any of them match the class reference (also a VMT pointer) for TStringList. In order to make sure that this will work correctly, there needs to be one single VMT for TStringList that's the same throughout your entire program, no matter how many BPLs it's divided up into, which means it has to be in its own package. That's why system runtimes like rtl*.bpl and vcl*.bpl are necessary, and there's not much you can do about that. It's part of the price of using BPLs.

As for not being able to debug, you need to make sure that the BPLs are built with debug info enabled and that the debugger knows how to find the folder where the DCP (the file containing the debug info for the BPL) is located. And you won't be able to trace into system BPLs, because debug-enabled DCPs weren't shipped with your version. They were added pretty recently, I think in XE but it might have been in D2010.

断舍离 2024-12-06 02:18:04

为什么我无法浏览我的源代码?有办法解决这个问题吗?

您无法浏览包中包含的单元的源代码,因为它们既不在您的项目、库或搜索路径中。

configuring your search path

我解决此问题的方法是将目录添加到项目搜索路径中。这样,编译器就不会知道这些文件(并且不会尝试重新编译它们),但 IDE 可以让您浏览它们的内容并调试它们。

Why can't I browse my source code? Is there a way to fix this?

You can not browse the source code of the units included in the packages because they are neither in your project, your library or search path.

configuring your search path

The way I solve this is adding the directories to the project search path. This way the compiler does not know about those files (and does not try to recompile them) but the IDE let's you browse their content and debug into them.

素衣风尘叹 2024-12-06 02:18:04

“在我的 exe 项目设置中,我选中了“使用运行时包构建”选项

,这就是为什么您无法在没有 BPL 等的情况下进行部署 - 这个选项让很多开发人员感到困惑 -“使用运行时包构建”意味着您将需要在运行时提供 bpl。 取消选中该选项,包将在编译时链接到您的 exe(您的 exe 的大小将会增加。)“使用运行时包构建”背后的想法是保持大小。 exe 已关闭并且允许多个应用程序共享通用的 bpl,因为它们在编译时没有链接到 exe - 这是您现在遇到的缺点 - 您必须将您的 bpl 与您的 exe 一起分发。

"In my exe project settings I checked the option "build with runtime packages"

That is why you cannot deploy without the BPL's etc - this option is confusing for a lot of developers -"build with runtime packages" means that you will need the bpl's present at runtime. Uncheck that option and the packages will be linked into your exe at compileTime. (Your exe will g-r-o-w in size.) The idea behind the "build with runtime packages" is to keep the size of exe's down and allow several apps to share common bpl's because they are NOT linked into the exe @ compileTime - that's the upside. The downside you are now experiencing - you must distribute your bpl's with your exe.

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