/usr/includeにヘッダファイルのコピーが複数あるのはなぜですか?

/usr/includeにヘッダファイルのコピーが複数あるのはなぜですか?

私は/usr/includeフォルダを見てレイアウトに慣れようとしましたが、ヘッダファイルのコピーが複数あることがわかりました(少なくとも名前では、実際にファイルが正しいかどうかを比較しませんでした)。正確なコピー)in / usr / includeの複数のサブディレクトリにあります。これは、標準CおよびC ++ヘッダファイルとPOSIX / LSB標準ヘッダファイルの場合に特に当てはまります。

いくつかの例は次のとおりです(注. /は/usr/includeを表します)。

./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h

./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h

./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath

./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h

./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h

なぜこれですか?いくつかのC標準ヘッダファイルがC ++の場所に表示されるのはなぜですか?

コンパイラは1つだけインストールされています(GCC 7)。

答え1

いいえ、正確なレプリカではありません。

調査しようとすると、最上位レベルのファイルには多くの/usr/includesまたは他の条件があり、アーキテクチャに依存しない部分と、より深いアーキテクチャ関連ディレクトリの他のコンテンツのみを定義することが#ifdefわかります。#include一部のアーキテクチャ関連部分は、最終的にいくつかのアーキテクチャ独立部分に依存する可能性があるため、互いに上に複数の包含階層が存在する可能性があります。

同様に、次のファイルには/usr/include/c++C ++にのみ意味のある追加宣言があり、#includesはそのCインクルードファイルに適用されます。

ゲーム名は保守性を向上させるためのデータ重複排除:意図は、glibc開発者が新しいものを追加する必要がある場合、アプリケーションとglibcの間のABIにのみ影響し、アーキテクチャ関連の部分はなく、理想的にはインクルードファイルツリーの1つの場所で追加が発生するだけです。 、glibcを使用するすべてのハードウェアアーキテクチャに適用されます。あるいは、たとえば、新しいシステム呼び出しがLinuxカーネルに追加された場合は、* BSDまたはGNU Hurdシステム呼び出しの定義を中断せずに追加できる場所があります。あるいは、glibcを別のハードウェア/カーネルアーキテクチャに移植する場合は、アーキテクチャに依存しない作業を中断することなく、必要なカーネルABI定義をプラグインできる場所を見つけることができます(必ず必要な場合は除く)。

はい、非常に複雑です。

/usr/include完全なレイアウトは、GCCおよびglibcプロジェクトで選択されたISO CおよびPOSIXの標準要件と選択肢の合計であるため、参照しやすい参照はありません。

私はあなたの建築三重港x86_64-linux-gnuあなたの場合は、gcc -dumpmachineGCCでサポートされているすべてのアーキテクチャで利用可能です)次に、コンパイラのデフォルトの#include <...>ファイル検索パスを調べます。

次の検索パスを表示できます。

  • cpp -v /dev/null -o /dev/null一般Cの場合
  • cpp -x c++ -v /dev/null -o /dev/nullC++の場合

GCC 7 を使用するシステムはありませんが、GCC 6 の場合、C の包含パスのリストは次のとおりです。

...
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...

...C++ の場合、次のようになります。

...
#include <...> search starts here:
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...

ディレクトリが存在する場合は、/usr/local/include/<architecture triplet>リストの直前に追加されます/usr/local/include

したがって、独自のプロジェクトにインクルードファイルのアーキテクチャ固有のバージョンが必要な場合は、そのファイルを に入れることが/usr/[local/]include/<architecture triplet>/でき/usr/[local/]include/ます。パス名には、コンパイラのメジャーバージョン番号が含まれます。

修正しようとしていて、glibc開発者ドキュメントに必要なものが見つからない場合は、glibc開発メーリングリストにアドバイスを求める方が良いでしょう。これは、GCC以外のコンパイラを使用するアーキテクチャでも機能するためです。標準として、アーキテクチャのトリプルルールがない可能性があります。glibcglibc

関連情報