Answers:
原因之一是可以在具有自己的C标准库的系统(例如MacOSX,Solaris,HPUX或某些FreeBSD等专有Unix系统)上构建和使用GCC。
即使在Linux上,您也可以拥有一个不是GNU Glibc的C标准库。特别是,您可以在具有musl-libc或Bionic(Android系统)或Dietlibc等的Linux系统上构建(或使用)GCC。Linux系统可以具有GNU Glibc并使用其他C编译器(例如Clang)或TinyCC)。
同样,C库在很大程度上取决于Linux内核。某些旧版本的内核可能需要某种特定类型(或版本)的libc
GCC可作为交叉编译器构建。
诸如“如何调用
main
函数”之类的细节也取决于编译器,但实际上,这些细节是libc.so
在Linux系统上提供的。
那是不完全正确的。该main
功能由crt0东西调用(在托管环境中),其中一些由GCC提供(例如,/usr/lib/gcc/x86_64-linux-gnu/6/crtbegin.o
在我的Debian / Sid / x86-64上是从libgcc-6-dev
软件包中提供的)。另请参阅libgcc
实际上,libc
和GCC 之间存在一些半隐藏的关系,例如,因为(很多)libc
标头使用了某些gcc 内置函数或函数属性。
(因此,GCC开发人员和GNU libc开发人员必须进行交互)
....如果我将编译器更改为可与另一个ABI一起使用...
您需要... /configure
并重新构建GCC编译器,甚至可能需要修补 GCC编译器(以描述您的ABI和调用约定)。该X32 ABI是一个很好的例子。
最后,一些GCC的贡献者或维护者(包括我)签署了一份版权转让,其中涉及GCC,但不涉及GNU glibc
。
(关于GCC许可证,请仔细阅读GCC运行时库异常)
请注意,某些标准标头(例如<limits.h>
或<stdint.h>
由GCC提供);其他的,例如<stdlib.h>
在GCC构建过程中被“修复”的:编译器构建过程从Libc实现中获取它们并对其进行修补。不过,其他标准标头(可能<stdio.h>
包括它的内部标头)也来自libc
。阅读有关GCC FIXINCLUDES和固定头文件的更多信息。
(fixincludes是我(Basile)仍然不太了解的东西)
您可以进行编译,gcc -v -H
以更准确地了解运行了哪些实际程序(因为gcc
是驱动程序,正在运行cc1
编译器,ld
&collect2
链接器,as
汇编器等),包括哪些头文件,链接了哪些库和目标文件(甚至隐式地包括C标准库和crt0)。阅读有关GCC 选项的更多信息。
顺便说一句,您可以使用与GCC期望的或针对其构建的标准库不同的C标准库(例如,musl-libc
或某些Dietlibc),绕过适当的额外参数来gcc
...
gcclibc
基于OS库的,但是版本是GCC而不是OS的一部分。
<stdint.h>
或<limits.h>
确实由GCC提供。其他标头,例如<stdlib.h>
从C库获取的标头,以及在GCC构建期间“固定”的标头。
简短的答案是,如果将两者“捆绑”在一起,则glibc将根据GPL *获得许可,因此,它完全不适合专有项目。尽管FSF和GNU项目不喜欢专有软件,但glibc被许可LGPL作为促进GCC和自由软件生态系统采用的战略选择。GCC实际上是根据GPL许可的,但具有特定的运行时链接例外,因为这种情况有些混乱。glibc已根据LGPL许可使用,以允许明智的共享库情况。
https://www.gnu.org/licenses/gcc-exception-faq.html
此外,glibc具有各种垫片和其他组件,可使其适应不同的操作系统,并且将其分发为与gcc相同的软件包也会使事情变得混乱。
*或者,GCC可以通过其他GPL来获得许可,尽管FSF对此的想法是“在我的尸体上”。