29

私のLIBRARY_PATH環境変数にはカスタムディレクトリがあります: /cs/public/lib/pkg/opencv/lib.

しかし、 を使用するg++ --print-search-dirsと、代わりに次のようになります。

libraries: =
/cs/public/lib/pkg/opencv/lib/x86_64-suse-linux/4.6/:
/cs/public/lib/pkg/opencv/lib/../lib64/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/../lib64/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../lib64/:
/lib/x86_64-suse-linux/4.6/:
/lib/../lib64/:
/usr/lib/x86_64-suse-linux/4.6/:
/usr/lib/../lib64/:
/cs/public/lib/pkg/opencv/lib/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../:
/lib/:
/usr/lib/

g++ は、変数で明示的に指定する前に、これらの代替手段と他のシステムの場所全体を調べるのはなぜですか? また、これはどこに文書化されていますか?LIBRARY_PATH

システムのデフォルトが LIBRARY_PATH および LIBRARY_PATH/../lib64 などの前に検索されたかどうかは理解できますが、g++ は LIBRARY_PATH/../lib64、次にシステム パス、次に LIBRARY_PATH を配置します。この注文はどこに文書化されていますか?

私のg ++​​バージョンはg++ (SUSE Linux) 4.6.2

私のOSはopenSUSE 12.1 (x86_64)

4

7 に答える 7

11

同様の質問がここで尋ねられました: g++ は /lib/../lib/ を検索し、次に /lib/ を検索します。

これらの恐ろしく見える検索パスは、少なくとも部分的には、コンパイラ自体がビルドしたときに、たとえば構成フェーズ中に決定されます。GCC の複数のコピーをインストールして、それぞれに異なる結果を与えることができるため、環境変数を超えていることは明らかですgcc --print-search-dirs。また、 g++ ラッパーも検索パスに影響を与えていることを指摘し、異なる結果g++ --print-search-dirsを与えることに注意してください。gcc --print-search-dirs構成/ビルド時間の違いに加えて、GCC は自身の実行可能ファイルがあるパスを明確に認識しており、そのパスのサブディレクトリを検索します。この錬金術の多くは、GCC ドキュメントで見つけることができます:
http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Directory-Options.html#Directory-Options
http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Environment-Variables.html#環境変数

私の知る限り、GCC の独自のコピーをコンパイルせずにできる最も強力なことは、 -L オプションを使用してカスタム ライブラリを指定することです。私がこれを言う理由は、-L が LIBRARY_PATH などの前に検索されるためです (環境変数に関する上記のリンクを参照してください)。より許容できるようにするために、.bashrc ファイルに -L オプションを含む g++ のエイリアスを追加できます。

決定的な答えが必要な場合は、GCC ソース コードのコピーをダウンロードするのが 1 つの方法です。たとえば、gcc.c には、次の非常に示唆に富んだコメントが表示されます。

/* Build a list of search directories from PATHS.
   PREFIX is a string to prepend to the list.
   If CHECK_DIR_P is true we ensure the directory exists.
   If DO_MULTI is true, multilib paths are output first, then
   non-multilib paths.
   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
   It is also used by the --print-search-dirs flag.  */

ただし、コメントに続く機能はあまり明白ではありません。

于 2012-09-18T17:44:09.990 に答える
7

これは multilib at work です。これは、1 台のマシンで複数のアーキテクチャ用のライブラリ (ただし、コンパイルおよびビルド ツールチェーン全体も) を持つことを可能にするメカニズムです。This Wikiは次のように述べています。 -L パスにライブラリが見つかりません。単一のコンパイルで複数の直交 ABI 変更オプションが使用されている場合、複数の multilib サフィックスを連続して使用できます。".

したがって、上記の説明によれば、デフォルト パスとカスタム パスを区別しないため、アーキテクチャ マーカー文字列またはそのさまざまなバリアントが、コンパイラが受け取る各ライブラリ検索パスに追加されます。カスタム パスは行の最初にありますが、他のパスと同じ「拡張」プロセスを経ます。

i386 との互換性を処理する必要があるため、ほとんどの x64 ディストリビューションではデフォルトで multilib メカニズムが使用されているようです。これは、実際にはほとんどのインストールを意味します。

于 2012-09-18T20:51:29.323 に答える
2

私はまったく同じ問題を抱えています:

Fedora 17, gcc 4.7 and gcc 4.3
CentOS 6.3, gcc 4.4
Unubuntu 12, gcc 4.6

したがって、これはほとんどの gcc バージョンの問題のようです。おそらく、この奇妙な動作は、少なくとも this によると、gcc 4.2 で最初に登場しまし

スペックを複製して遊んでみました。*multilib仕様は、プラットフォームに応じて特定の文字列を追加するために使用されているようです。たとえば、私の元のスペースは次のようになりました。

*multilib:
. !m64 !m32;64:../lib64 m64 !m32;32:../lib !m64 m32;

gcc appendedの代わりに thenに変更64:../lib64したとき。しかし、その他の仕様の意味を完全に解読することはできませんでした。64:../lib../lib64../lib*multilib

于 2012-10-03T08:34:15.807 に答える
-1

パスは、組み込み仕様によって定義されます。仕様は、パイプラインがソース コードを処理して結果を取得する方法を定義します。GCC はコンパイルを実行するだけです。

を介して GCC に独自の仕様ファイルを与えることができ、 IIRCを使用-spec=して組み込みの仕様を取得できます。-dumpspecs

これはおそらく GCC マニュアルのどこかで説明されています。

于 2012-09-20T13:11:40.633 に答える
-1

クロスコンパイルに必要なようです。変更ログから:

  Wed Mar 29 14:53:23 1995  Jim Wilson  <wilson@cygnus.com>

          * gcc.c (process_command): Delete code modifying gcc_exec_prefix.
          (main): Put it here after last use of gcc_exec_prefix.  For cross
          compiler, set startfile_prefixes if gcc_exec_prefix is set and
          standard_startfile_prefix is a relative path.

startfile_prefixessearch-dirs フラグで出力されているものです。からgcc/gcc.c:

    if (print_search_dirs)
      {
        printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
        printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
        printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
        return (0);
      }
于 2012-09-16T17:13:27.053 に答える
-1

コンパイラは、最初にデフォルト パスを調べてから、他のパスを調べます。印刷時にどのようにソートされます?

于 2012-09-16T17:15:05.483 に答える