【问题标题】:If clang++ and g++ are ABI incompatible, what is used for shared libraries in binary?如果 clang++ 和 g++ 不兼容 ABI,那么二进制中的共享库使用什么?
【发布时间】:2015-12-03 07:16:42
【问题描述】:

clang++ 和 g++ 不兼容 ABI,即使对于像标准容器这样的核心,根据例如 clang++ 网站。

Debian 附带 C++ 共享库,即 libboost 等...,它们是用 ~something 编译的,并且使用这两种编译器的用户程序通常都可以工作,并且库名称不会与用于它们的编译器混淆。当您安装 clang 时,debian 不会去拉入您系统上安装的每个 C++ 库的重复版本。

有什么关系? clang 链接到发行版提供的 C++ 库的能力是否比编译器开发人员描述的(谢天谢地谨慎)强得多?

【问题讨论】:

  • 我认为实际上,clang 应该是与 gcc 兼容的 ABI,否则你是对的,这将是一场巨大的噩梦。不过我不确定。我认为 clang 基本上需要采用这个策略才能起步。
  • 我不想说它们是重复的,确切地说。这个问题指的是非常具体的版本。
  • libc++ 与 libstdc++ 不兼容,但与 libstdc++ 的 clang 应该与带有 libstdc++ 的 g++ 兼容。

标签: c++ shared-libraries abi


【解决方案1】:

这可能无法正确回答确切的问题:

前段时间我尝试用 gcc 编译一些目标文件,用 clang 编译另一个目标文件。最后,我将所有内容连接在一起,并且工作正常。

我相信 Linux 发行版使用 gcc,因为我检查了一些 Ubuntu 和 CentOS 的 Makefile,他们使用了 gcc。

【讨论】:

  • 并非所有发行版,例如OpenMandriva 几乎在整个 dsitro 中都使用 Clang。
  • 我在 Centos 上,我尝试将使用 clang 构建的静态库与使用 g++ 构建的可执行文件链接,我收到链接器错误,这清楚地表明 ABI 不兼容
【解决方案2】:

G++ 和 Clang 对于绝大多数完全 ABI 兼容。此外,标准容器的 ABI 不兼容性是标准库实现(libstdc++ 或 libc++)的属性,而不是编译器。因此,无需重新编译。

如果 Clang 与 g++ 的 ABI 不兼容,它就永远无法起步,因为如果没有预先存在的大量追随者,它将基本上无法使用。事实上,Clang 与 GCC 非常兼容,它们几乎模仿了 g++ 的所有命令行界面、编译器内在函数、错误等,因此您可以直接使用 Clang 而不是 G++,并且在绝大多数情况下,一切都会工作就好。

【讨论】:

  • 这完全正确。 Clang 使用 GCC 的名称修饰和 GCC 的调用约定。它与 GCC 非常兼容,以至于在带有 Xcode 的 OS X 上,g++ 实际上是指向clang++ 的符号链接。
  • 更正确地说,它是 ABI,而不是 GCC。 Itanium ABI 独立于 GCC。
  • 我从未听说过。你能举一些clang++模仿的g++ bug的例子吗?
【解决方案3】:

即使是像标准容器这样的核心

标准容器并不是“核心”。 (对于典型实现)它们完全在头文件中使用有效的 C++ 实现,如果您使用 G++ 和 Clang++ 编译相同的头文件,您将获得与 ABI 兼容的输出。如果您使用不同版本的容器标头,而不仅仅是使用 Clang 而不是 GCC,那么“即使对于像标准容器这样的核心”,您也应该只获得不兼容性。

GCC 和 Clang 都符合跨供应商、跨平台的 C++ ABI(最初为 Itanium 架构开发,但也用于 x86、x86_64、SPARC 等)真正核心ABI 指定了类布局、名称修饰、异常处理、vtables 等内容,Clang 和 GCC 都遵循它。

换句话说,如果您使用 GCC 和 Clang 编译相同的源代码,您将获得与 ABI 兼容的二进制文件。

如果您想更好地了解这些内容,请查看我的 What's an ABI and why is it so complicated? 幻灯片。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-16
    • 2018-06-12
    • 2012-07-25
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多