12

我正在使用 Embarcadero RAD Studio 2010 (C++)。项目文件 (.cbproj) 有五个不同的标签,其中包含 .bpis 或 .libs 的列表。我想要一些关于链接器如何使用这些库文件列表的信息(在使用或不使用运行时包进行构建时)。

LinkPackageImports

LinkPackageStatics

所有包库

包库

PackageImports
我想我已经理解了最后一个。它包含可以从 IDE 中的项目属性设置的运行时包列表。

这个问题的动机是我试图从我的应用程序中消除不必要的依赖关系。.cbproj 中的这五个标签似乎都包含任意种类的不同库和 bpi。一些我知道我不需要的库,还有一些我认为我不需要的库。从某些列表中删除某些库似乎没有效果,而从其他列表中删除其他库会导致表单的链接器错误[ILINK32 Error] Fatal: Unable to open file 'FILENAME.OBJ'

我正在慢慢解决所有链接器问题,但是当我在这五个列表之一中包含库名称时,确切地知道我告诉链接器做什么会很有帮助。

4

2 回答 2

19

我确信这些信息一定存在于某处,但我无法在任何论坛或文档中找到它。我已经从我自己的实验中推断出所有这些,但我希望从更官方的来源获得反馈。

PackageImports -- 这在 IDE 的项目选项中显示为“运行时包”列表。如果您在 IDE 的“运行时包”列表中添加或删除任何内容,此标记将更新以反映这一点。如果 cbproj 文件中此标记为空或缺失,它将自动填充与安装在 RAD Studio 中的所有设计时包关联的所有运行时包的列表。从命令行构建时,此标记无效。IDE 似乎使用 PackageImports 标记来计算它实际要链接的库。

将库放在此列表中不会(本身)创建任何新的依赖项;您实际上是在告诉 IDE“如果您必须链接这些库中的任何一个,请动态链接它们而不是静态链接”。

AllPackageLibs -- 这是 IDE 的列表,列出了它认为项目成功链接所需的所有库。从命令行构建时,此标记无效。如果您对项目进行更改(例如添加文件),IDE 将尝试重新计算 AllPackageLibs 的内容。#pragma link它根据在项目文件中找到的 s 计算此值。(我通过注释掉#pragma link项目中的所有 s 并注意到在我进行项目修改时没有重新填充 AllPackageLibs 来确定这一点。)

LinkPackageStatics——如果 IDE 在 AllPackageLibs 中找到一个出现在 PackageImports 中的库,它会决定静态链接该库。在这种情况下,IDE 会自动将库名称复制到 LinkPackageStatics。如果从 IDE 构建,此标记将始终从 AllPackageLibs 和 PackageImports 重新计算,因此您在此处手动添加的任何内容都将被链接器忽略。但是,如果从命令行构建,此标记中的所有文件(.libs 或 .bpis)将被链接并出现在 ilink32 命令行的“objfiles”部分中。

LinkPackageImports——如果 IDE 在 AllPackageLibs 中找到一个确实出现在 PackageImports 中的库,它决定动态链接该库。在这种情况下,IDE 会将库名称(扩展名为 .bpi)复制到 LinkPackageImports。如果从 IDE 构建,此标记将始终从 AllPackageLibs 和 PackageImports 重新计算,因此您在此处手动添加的任何内容都将被链接器忽略。但是,如果从命令行构建,则此标记中的所有文件(.libs 或 .bpis)都将被链接并出现在 ilink32 命令行的“libfiles”部分中。

PackageLibs -- PackageLibs 中的任何内容(.libs 或 .bpis)都将由 IDE 直接添加到 LinkPackageStatics(无论 PackageImports 包含什么)。这些库被添加到来自 AllPackageLibs 的库前面的 LinkPackageStatics。命令行构建不受此标记的影响。

每当您希望 IDE 为您修改 LinkPackageStatics 或 LinkPackageImports 时,您需要首先在 IDE 中构建项目;然后对项目选项进行微小的更改(并撤消它);然后保存项目。此时,IDE 会将 LinkPackageStatics 或 LinkPackageImports 写入 cbproj,以便您的项目可以在命令行上链接。

链接库的其他方法——还有几种方法可以指定要链接的文件,它们不涉及这四个标签。您可以将 .lib 直接添加到项目中(右键单击项目 | 添加...),或者您可以#pragma comment (lib, "libraryname.lib")在与项目一起编译的文件之一中插入该行。

如果将 .lib 直接添加到项目中,它将与所有其他要链接的库一起出现在命令行上。如果您使用该#pragma comment技巧,该库将不会出现在命令行上,并且您将无法看到它已链接(除非通过使用tdump和查看导出)。

概括

从命令行链接时,唯一有效的 cbproj 标签(这五个标签)是 LinkPackageStatics(添加到 objfiles 部分的库)和 LinkPackageImports(添加到 libfiles 部分的库)。这些标签的内容由 IDE 从 AllPackageLibs 和 PackageImports 计算,但如果您需要从命令行链接,您可以在 .cbproj 中手动设置它们。

从 IDE 链接时,您通常希望 IDE 为您管理库。如果您需要添加 IDE 无法自动检测到的库,您应该在外部编辑器中打开 .cbproj 文件并将缺少的库添加到 AllPackageLibs 标记。如果您希望库被动态链接,您还应该将库名称添加到“使用运行时包构建”列表(又名 PackageImports)。

如果要确保动态链接所有库,请查看 .cbproj 文件中的 LinkPackageStatics 标记。如果该列表中有任何库,则它们是静态链接的。要解决此问题,请将这些库的名称复制到 PackageLibs 标记中(并将其扩展名更改为 bpi);然后删除 LinkPackageStatics 标记。

于 2012-09-14T19:27:08.870 回答
0

伙计,我希望你已经找到了解决问题的方法,但我认为你只需要禁用 Build With Runtime Packages,禁用 Use Dynamic RTL 并从 Debug 更改为 Release 构建,对于你正在使用的所有项目(http:// bcbjournal.org/articles/vol4/0009/Building_stand-alone_EXEs.htm?PHPSESSID=08f2084c32d5fce05f13518fef23f358)。

如果您有一些无法更改的组件,例如某些二进制文件(dll、lib...),那么如果这些禁用选项之前是用它们构建的,您仍然会依赖于这些禁用选项...

我建议您在构建之前从您的项目中删除所有 *.obj 和 *.exe(除非它们是某些 3rd 方模块的必需品)... 一些较旧的 C++ Builder 版本有一些构建问题已解决方法。

于 2012-09-10T13:52:16.953 回答