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