web-dev-qa-db-ja.com

glibcがGCCとは別に維持されるのはなぜですか?

GCCはCコンパイラです。 GlibcはCライブラリです。しかし、Cの実装として一緒にバンドルされているコンパイラと標準ライブラリは絶対に必要ではないでしょうか。

たとえば、Cライブラリには、ABIと<limits.h><stdint.h>などのコンパイラ固有のものが含まれていますが、コンパイラとAPIの間で異なります。 「メイン関数の呼び出し方法」などの詳細もコンパイラに依存しますが、実際にはこれらの詳細はLinuxシステムではlibc.soによって提供されます。たとえば、8バイトのintを使用するなど、別のABIで動作するようにコンパイラを変更すると、<limits.h>の内容が間違っているため、Cライブラリが機能しなくなります。

13
Michael Tsang

理由の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コンパイラーを実行しているため、ldcollect2 リンカー、asアセンブラなど)、含まれるヘッダー、リンクされるライブラリとオブジェクトファイル(暗黙的に、C標準ライブラリと- crt )。 GCC options の詳細をご覧ください。

ところで、GCCが期待するものやビルドされたものとは異なるC標準ライブラリを使用できます(例:musl-libcまたはいくつかの dietlibc )、gccへの適切な追加引数をバイパスします...

20