1. ホーム
  2. c++

[解決済み】gcc/g++:"そのようなファイルやディレクトリはありません"

2022-01-26 04:43:34

質問

g++ のようなエラーが発生します。

foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.

Cプログラムをコンパイルする際も同様に gcc .

それはなぜでしょうか?


ご注意ください。 この質問はこれまでにも何度もありましたが、その都度、質問者の状況に応じた内容になっていました。この質問の趣旨は 他の人が重複しているとして閉じられるような質問をすること は、一度だけです。 よくある質問 .

解決方法は?

という名前のファイルをコンパイルしようとしました。 foo.cc . 行番号を打つと line を、コンパイラは発見します。

#include "bar"

または

#include <bar>

次に、コンパイラはそのファイルを探そうとします。そのために、ディレクトリのセットを使って調べますが、このセットの中には、ファイル bar . include文のバージョンの違いの説明については、以下をご覧ください。 こちら .

コンパイラに場所を教える方法

g++ は、オプション -I . これは、コマンドラインにインクルード検索パスを追加することができます。例えば、あなたのファイル bar という名前のフォルダーに frobnicate からの相対的な foo.cc (があるディレクトリからコンパイルしていると仮定します。 foo.cc があります)。

g++ -Ifrobnicate foo.cc

さらにインクルードパスを追加することができます。あなたが与える各パスは、カレント・ディレクトリからの相対パスです。マイクロソフトのコンパイラは、関連するオプションとして /I Visual Studio では、プロジェクトのプロパティページの「設定プロパティ」-「C/C++」-「一般」-「追加インクルードディレクトリ」で設定できます。

ここで、複数のバージョンの bar を異なるフォルダに保存しておくとします。


// A/bar
#include<string>
std::string which() { return "A/bar"; }


// B/bar
#include<string>
std::string which() { return "B/bar"; }


// C/bar
#include<string>
std::string which() { return "C/bar"; }


// foo.cc
#include "bar"
#include <iostream>

int main () {
    std::cout << which() << std::endl;
}


との優先順位は #include "bar" が一番左です。

$ g++ -IA -IB -IC foo.cc
$ ./a.out
A/bar

ご覧のように、コンパイラが A/ , B/C/ の場合、一番左のヒットで止まってしまいます。

これはどちらの形でも同じです。 include <>incude "" .

の違い #include <bar>#include "bar"

通常は #include <xxx> はシステムフォルダを最初に調べさせます。 #include "xxx" は、現在のフォルダまたはカスタムフォルダを最初に調べます。

プロジェクトフォルダ内に以下のファイルがあるとします。

list
main.cc

main.cc :

#include "list"
....

この場合、コンパイラは #include というファイル list をコンパイルしているため、プロジェクトフォルダ内の main.cc というファイルがあり、その中に list を現在のフォルダにコピーします。

しかし main.cc :

#include <list>
....

で、次に g++ main.cc の場合、コンパイラはシステムフォルダを最初に調べます。 <list> は標準のヘッダーであるため #include という名前のファイルは list は、C++ プラットフォームに標準ライブラリの一部として付属しているものです。

少し簡略化されていますが、基本的な考え方はご理解いただけると思います。

の詳細 <> / "" -優先順位と -I

によると gcc-documentation の優先順位は、1.5%です。 include <> は、quot;通常のUnixシステム"では、次のようになります。

 /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include

C++プログラムの場合は、まず、/usr/include/c++/versionも探します。上記で、ターゲットはGCCがコードをコンパイルするように設定されたシステムの標準的な名前です; [...]。

ドキュメントにも記載されています。

このリストに追加するには、-Idirコマンドラインオプションを使用します。Iで指定されたすべてのディレクトリが、左から右の順に検索されます。 デフォルトのディレクトリの前に . 唯一の例外は、dirがすでにデフォルトで検索されている場合です。この場合、このオプションは無視され、システムディレクトリの検索順序は変更されないままです。

の続きです。 #include<list> / #include"list" の例です(コードは同じ)。

g++ -I. main.cc

そして

#include<list>
int main () { std::list<int> l; }

であり、確かに -I. を優先し、フォルダの . がシステムインクルードよりも優先されるため、コンパイラーエラーが発生します。