gcc / g++: "нет такого файла или каталога"



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



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


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



почему это?





обратите внимание: этот вопрос задавался много раз раньше, но каждый раз он был специфичен для ситуации askers. Цель этого вопроса -есть вопрос, что другие могут быть закрыты как дубликаты, раз и навсегда; a часто задаваемые вопросы.

1287   1  

1 ответ:

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

#include "bar"

или

#include <bar>

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

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

g++ имеет параметр -I. Он позволяет добавлять пути поиска include в командную строку. Представьте, что ваш файл 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

по словам gcc-documentation основная задача include <> находится в "нормальной системе Unix" следующим образом:

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

для программ на C++ он также будет выглядеть в /usr/include/c++/version, first. В приведенном выше target-это каноническое имя системного GCC был настроен для компиляции кода; [...].

в документации также говорится:

вы можете добавить в этот список с параметром командной строки-Idir. Все каталоги с именем-I ищутся в порядке слева направо,перед каталогами по умолчанию. Единственное исключение - когда dir уже ищется по умолчанию. В этом случае параметр игнорируется, а порядок поиска для системных каталогов остается неизменным.

продолжить #include<list> / #include"list" пример (тот же код):

g++ -I. main.cc

и

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

и -I. приоритет папке . над системой включает и мы получаем ошибку компилятора.

Comments

    Ничего не найдено.