gcc / g++: "нет такого файла или каталога"
g++
дает мне ошибки типа:
foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
это то же самое при компиляции C-программ с gcc
.
почему это?
обратите внимание: этот вопрос задавался много раз раньше, но каждый раз он был специфичен для ситуации Аскеров. Цель этого вопроса -есть вопрос, что другие могут быть закрыты как дубликаты, раз и навсегда; a часто задаваемые вопросы.
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++ - >общие - >дополнительные каталоги Include.
теперь представьте, что у вас есть несколько версий 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-документация основная задача include <>
is, на "нормальной системе 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.
приоритет папке .
над системой включает и мы получаем ошибку компилятора.