gcc / g ++:「そのようなファイルやディレクトリはありません」


88

g++ 次の形式のエラーが表示されます。

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

を使用してCプログラムをコンパイルする場合も同じgccです。

何故ですか?


注意:この質問はこれまで何度も質問されてきましたが、そのたびに質問者の状況に固有のものでした。この質問の目的は、他の人が、一度限りの複製として閉じることができるという質問をすることです。よくある質問


4
FAQへの素晴らしい追加。ありがとうございます!
sbi 2012年

回答:


119

コンパイラがfoo.cc。という名前のファイルをコンパイルしようとしました。行番号を押すlineと、コンパイラは次のことを検出します。

#include "bar"

または

#include <bar>

次に、コンパイラはそのファイルを見つけようとします。このため、ディレクトリのセットを使用して調べますが、このセット内にはファイルはありませんbar。includeステートメントのバージョン間の違いの説明については、こちらをご覧ください

コンパイラにそれを見つける方法を伝える方法

g++オプションがあります-I。コマンドラインにインクルード検索パスを追加できます。ファイルbarfrobnicate、に関連する、という名前のフォルダにあると想像してくださいfoo.ccfoo.ccが配置されているディレクトリからコンパイルしていると仮定します)。

g++ -Ifrobnicate foo.cc

インクルードパスをさらに追加できます。あなたが与えるそれぞれは、現在のディレクトリに関連しています。Microsoftのコンパイラには/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>は標準ヘッダーであるため、C ++プラットフォームに標準ライブラリの一部として付属している#includeという名前のファイルになりますlist

これはすべて少し単純化されていますが、基本的な考え方がわかるはずです。

<>/ ""-prioritiesとの詳細-I

gcc-documentationによると、の優先順位include <>は、「通常のUnixシステム」では次のとおりです。

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

C ++プログラムの場合、最初に/ usr / include / c ++ / versionも調べます。上記では、targetは、GCCがコードをコンパイルするように構成されたシステムの正規名です。[...]。

ドキュメントには次のようにも記載されています。

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

この#include<list> / #include"list"例を続けるには(同じコード):

g++ -I. main.cc

そして

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

実際、システムに含まれる-I.フォルダー.よりもフォルダーが優先され、コンパイラエラーが発生します。


9
質問と回答の作成者が同じであるため、コンパイラを「コンパイラ」と呼ぶのはちょっと奇妙だということに気づかせてください。

28
@Jeffrey:質問の作者は、ここの一般的な形式に合わせるつもりだったのかもしれません。ダンノ、彼に聞いてください。
セバスチャンマッハ

1
この答えは間違っています。デフォルトのシステムディレクトリの前に#include <>リストされているディレクトリを調べ-Iます
Jonathan Wakely 2012年

5
ファイルバーがfoo.ccに対して、frobnicateという名前のフォルダーにあると想像してください。」で指定さ-Iれたdirは、コンパイル中のファイルではなく、gccを実行するdirに関連しています。あなたがそうするならば、違いは重要ですg++ -Ifrobnicate blah/foo.cc
Jonathan Wakely 2012年

3
PATH(Linuxシステムの)環境変数の設定は、コンパイラーがファイルを検索する方法にまったく影響しますか?
マットフィリップス

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.