gcc / g ++: & quot; Нет такого файла или каталога & quot;

g++ выдает мне ошибки вида:

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

То же самое при компиляции C-программ с gcc,

Это почему?


Пожалуйста, обратите внимание: Этот вопрос задавался много раз прежде, но каждый раз, когда он был специфическим для ситуации спрашивающих. Цель этого вопроса иметь вопрос, что другие могут быть закрыты как дубликаты, раз и навсегда; Часто задаваемые вопросы.

64

Решение

Ваш компилятор только что попытался скомпилировать файл с именем foo.cc, При попадании в номер строки lineКомпилятор находит:

#include "bar"

или же

#include <bar>

Затем компилятор пытается найти этот файл. Для этого он использует набор каталогов для просмотра, но в этом наборе нет файла bar, Для объяснения различий между версиями оператора включения смотрите Вот.

Как сказать компилятору, где его найти

g++ имеет возможность -I, Это позволяет вам добавлять пути поиска в командной строке. Представь, что твой файл bar находится в папке с именем frobnicate, относительно foo.cc (предположим, что вы компилируете из каталога, где foo.cc расположен):

g++ -Ifrobnicate foo.cc

Вы можете добавить больше include-путей; каждый, который вы даете, относится к текущему каталогу. Компилятор 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> это стандартный заголовок, он будет #include файл с именем list это идет с вашей платформой C ++ как часть стандартной библиотеки.

Это все немного упрощено, но должно дать вам основную идею.

Подробности на <>/""-приоритеты и -I

Согласно НКА-документация, приоритет для 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. расставляет приоритеты в папке . по системе включает и мы получаем ошибку компилятора.

83

Другие решения

Других решений пока нет …