为啥 gcc 要我链接到 libgcc_ext.10.5.dylib?
Posted
技术标签:
【中文标题】为啥 gcc 要我链接到 libgcc_ext.10.5.dylib?【英文标题】:Why does gcc want me to link to libgcc_ext.10.5.dylib?为什么 gcc 要我链接到 libgcc_ext.10.5.dylib? 【发布时间】:2014-11-28 23:27:20 【问题描述】:我已经在 Mac OS X 上从源代码静态构建了 GCC 4.9.2(使用 --disable-shared),仅用于 C 语言(不是 C++),带有静态版本的 libgcc (libgcc.a)。当然,由于我只构建了 libgcc 的静态版本,所以没有 libgcc*.dylib 之类的东西。 GCC 已经构建并安装了 libgcc.a(如预期的那样),这一切都很好。现在,当我使用以下命令调用这个新建的 GCC 副本时(使用简单的 hello, world! 示例):
gcc -v test.c -o test
它默认显示这些编译器标志:
-no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lSystem
不,不,不!我不希望您尝试链接到 libgcc 的共享版本!你不记得我在配置步骤告诉过你吗?如果我使用 -static-libgcc 选项,我会得到:
-no_compact_unwind -lgcc_eh -lgcc -lSystem
libgcc_eh?嗯?在 GCC 编译期间是什么时候构建的?哦对了,不是,所以找不到libgcc_eh.a。
这里发生了什么?我特别告诉 GCC 我不想要共享库,那么为什么它默认尝试链接到它们呢?当然,我可以通过使用 -nodefaultlibs 并手动指定 -lgcc 和 -lSystem 来解决所有这些问题,但我为什么必须这样做呢?
此外,GCC 文档有这样的说法:
-shared-libgcc -static-libgcc 在将 libgcc 作为共享库提供的系统上,这些选项分别强制使用共享版本或静态版本。如果在配置编译器时没有构建 libgcc 的共享版本,则这些选项无效。
因此,基于此,我认为如果我没有特别要求 GCC 构建 libgcc 的共享版本,它不应该假设我想要链接到静态版本以外的任何东西。但是,出于某种原因,它仍然存在。我找不到可以阻止这种情况的配置选项,也找不到让我指定默认链接到哪些“默认库”的选项。似乎 GCC 迫使我链接到一个不存在的共享版本的 libgcc,除非我使用 -nodefaultlibs 禁止它。这似乎倒退了。
【问题讨论】:
【参考方案1】:我想出了如何解决这个问题。我必须在 GCC 的源代码中编辑 /gcc/config/darwin.h 并注释掉宏 REAL_LIBGCC_SPEC 的定义位置。通过不定义这个宏,它可以确保 GCC 在链接期间只传递 -lgcc 和 -lSystem 库标志,这正是我想要的。
编译驱动程序的 GCC 文档解释了这个宏和其他宏的作用:
https://gcc.gnu.org/onlinedocs/gccint/Driver.html
— 宏:LIBGCC_SPEC 另一个 C 字符串常量,它告诉 GCC 驱动程序如何以及何时将 libgcc.a 的引用放入链接器命令行。该常数位于 LIB_SPEC 的值之前和之后。 如果未定义此宏,则 GCC 驱动程序提供一个默认值,将字符串 -lgcc 传递给链接器。
— 宏:REAL_LIBGCC_SPEC 默认情况下,如果定义了 ENABLE_SHARED_LIBGCC,则 LIBGCC_SPEC 不会被驱动程序直接使用,而是根据命令行标志 -static、-shared、-static-libgcc 的值修改为引用不同版本的 libgcc.a , 和 -shared-libgcc。在这些修改不合适的目标上,改为定义 REAL_LIBGCC_SPEC。 REAL_LIBGCC_SPEC 告诉驱动程序如何在链接命令行上放置对 libgcc 的引用,但与 LIBGCC_SPEC 不同的是,它未经修改即可使用。
【讨论】:
以上是关于为啥 gcc 要我链接到 libgcc_ext.10.5.dylib?的主要内容,如果未能解决你的问题,请参考以下文章