【问题标题】:Understanding package imports in the .cbproj file了解 .cbproj 文件中的包导入
【发布时间】:2012-07-31 23:33:18
【问题描述】:

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

LinkPackageImports

LinkPackageStatics

AllPackageLibs

PackageLibs

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

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

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

【问题讨论】:

    标签: linker c++builder c++builder-2010 runtime-packages


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      伙计,我希望你已经找到了解决问题的方法,但我认为你只需要禁用 Build With Runtime Packages,禁用 Use Dynamic RTL 并从 Debug 更改为 Release 构建,对于你正在使用的所有项目(@ 987654321@).

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

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

      【讨论】:

      • 是的,IDE 尝试真的很难为您链接所有正确的库,但有时它只是不正确,您必须去添加库自己在 cbproj 文件中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多