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
, Для объяснения различий между версиями оператора включения смотрите Вот.
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.
расставляет приоритеты в папке .
по системе включает и мы получаем ошибку компилятора.
Других решений пока нет …