GCCはCコンパイラです。 GlibcはCライブラリです。しかし、Cの実装として一緒にバンドルされているコンパイラと標準ライブラリは絶対に必要ではないでしょうか。
たとえば、Cライブラリには、ABIと<limits.h>
、<stdint.h>
などのコンパイラ固有のものが含まれていますが、コンパイラとAPIの間で異なります。 「メイン関数の呼び出し方法」などの詳細もコンパイラに依存しますが、実際にはこれらの詳細はLinuxシステムではlibc.so
によって提供されます。たとえば、8バイトのint
を使用するなど、別のABIで動作するようにコンパイラを変更すると、<limits.h>
の内容が間違っているため、Cライブラリが機能しなくなります。
理由の1つは [〜#〜] gcc [〜#〜] を構築して、独自のシステム(MacOSX、Solaris、HPUX、または一部のFreeBSDなどの独自のUnixシステム)で使用できることです- C標準ライブラリ 。
Linuxでも、 GNU Glibc ではないC標準ライブラリを使用できます。特に、Linuxシステムで musl-libc または Bionic (Androidシステム)または dietlibc を使用してGCCを構築(または使用)できます。 、など。そしてLinuxシステムは、GNU Glibcを使用し、他のCコンパイラ( Clang またはTinyCCなど)を使用できます。
また、CライブラリはLinuxカーネルに大きく依存しています。カーネルの一部の古いバージョンでは、特定の種類(またはバージョン)のlibc
が必要になる場合があります
そして、GCCは クロスコンパイラ としてビルドできます。
また、「
main
関数を呼び出す方法」などの詳細もコンパイラーに依存しますが、実際には、これらの詳細はLinuxシステムではlibc.so
によって提供されます。
それは正確ではありません。 main
関数は(ホスト環境で) crt によって呼び出され、その一部はGCCによって提供されます(たとえば、私のDebian/Sid/x86-の/usr/lib/gcc/x86_64-linux-gnu/6/crtbegin.o
) 64はlibgcc-6-dev
パッケージからのものです)。 libgcc
についてもお読みください
実際、libc
とGCCの間には、半分隠された関係があります。多くのlibc
ヘッダーが(オプションで)いくつかのgcc builtins または function attributes を使用しているためです。
(したがって、GCC開発者とGNU libc開発者は対話する必要があります)
....別のABIで動作するようにコンパイラを変更した場合...
GCCコンパイラを.../configure
して再構築する必要があります。また、GCCコンパイラにpatchする必要がある場合もあります( ABIと 呼び出し規約 )を記述します。 x32 ABI が良い例です。
ついに、GCC(私を含む)の貢献者またはメンテナが 著作権の割り当て に署名しましたが、GNU glibc
ではありません)。
(GCCライセンスに関しては、注意深く読んでください GCCランタイムライブラリ例外 )
<limits.h>
や<stdint.h>
などのいくつかの標準ヘッダーはGCCによって提供されることに注意してください。 <stdlib.h>
などの他のものは、GCCビルド中に「修正」されます。コンパイラビルドプロシージャは、Libc実装からそれらを取得してパッチを適用します。それでも、他の標準ヘッダー(おそらく<stdio.h>
とそれに含まれる内部ヘッダー)はlibc
から取得されます。 GCC FIXINCLUDES および Fixed Header Files の詳細をご覧ください。
(fixincludesは、私(Basile)がまだよく理解していないものです)
gcc -v -H
を使用してコンパイルすると、実際に実行されるプログラムをより正確に理解できます(gcc
はドライバーであり、cc1
コンパイラーを実行しているため、ld
& collect2
リンカー、as
アセンブラなど)、含まれるヘッダー、リンクされるライブラリとオブジェクトファイル(暗黙的に、C標準ライブラリと- crt )。 GCC options の詳細をご覧ください。
ところで、GCCが期待するものやビルドされたものとは異なるC標準ライブラリを使用できます(例:musl-libc
またはいくつかの dietlibc )、gcc
への適切な追加引数をバイパスします...