g++
me dá erros no formulário:
foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
É o mesmo ao compilar programas C com gcc
.
Por que é que?
Observação: Esta pergunta já foi feita muitas vezes antes, mas cada vez era específica para a situação de quem pergunta. O objetivo desta pergunta é ter uma pergunta que outras pessoas podem ser fechadas como duplicatas , de uma vez por todas; um FAQ .
Respostas:
Seu compilador acabou de tentar compilar o arquivo chamado
foo.cc
. Ao atingir o número da linhaline
, o compilador encontra:#include "bar"
ou
#include <bar>
O compilador então tenta encontrar esse arquivo. Para isso, ele usa um conjunto de diretórios para pesquisar, mas dentro desse conjunto, não há nenhum arquivo
bar
. Para obter uma explicação da diferença entre as versões da instrução include, clique aqui .Como dizer ao compilador onde encontrá-lo
g++
tem uma opção-I
. Ele permite que você adicione caminhos de pesquisa de inclusão à linha de comando. Imagine que seu arquivobar
está em uma pasta chamadafrobnicate
, relativo afoo.cc
(suponha que você esteja compilando a partir do diretório ondefoo.cc
está localizado):g++ -Ifrobnicate foo.cc
Você pode adicionar mais caminhos de inclusão; cada um dado é relativo ao diretório atual. O compilador da Microsoft possui uma opção de correlação
/I
que funciona da mesma maneira, ou no Visual Studio, as pastas podem ser definidas nas páginas de propriedades do projeto, em Propriedades de configuração-> C / C ++ -> Geral-> Diretórios adicionais de inclusão.Agora imagine que você tenha várias versões de
bar
em pastas diferentes, dadas:// 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; }
A prioridade com
#include "bar"
é a mais à esquerda:Como você vê, quando o compilador começou a olhar através
A/
,B/
eC/
, ele parou na primeira ou hit mais à esquerda.Isso é verdade para ambas as formas
include <>
eincude ""
.Diferença entre
#include <bar>
e#include "bar"
Normalmente,
#include <xxx>
faz com que ele examine primeiro as pastas do sistema e primeiro as pastas#include "xxx"
atuais ou personalizadas.Por exemplo:
Imagine que você tenha os seguintes arquivos na pasta do seu projeto:
list main.cc
com
main.cc
:#include "list" ....
Para isso, seu compilador irá colocar
#include
o arquivolist
na pasta do seu projeto, pois ele atualmente compilamain.cc
e existe esse arquivolist
na pasta atual.Mas com
main.cc
:#include <list> ....
e
g++ main.cc
, em seguida , seu compilador examinará primeiro as pastas do sistema e, por<list>
ser um cabeçalho padrão, encontrará#include
o arquivo nomeadolist
que vem com sua plataforma C ++ como parte da biblioteca padrão.Tudo isso é um pouco simplificado, mas deve lhe dar uma ideia básica.
Detalhes sobre as prioridades
<>
/""
e-I
De acordo com a documentação do gcc , a prioridade para
include <>
é, em um "sistema Unix normal", como segue:/usr/local/include libdir/gcc/target/version/include /usr/target/include /usr/include
A documentação também afirma:
Para continuar nosso
#include<list> / #include"list"
exemplo (mesmo código):g++ -I. main.cc
e
#include<list> int main () { std::list<int> l; }
e, de fato, o
-I.
prioriza a pasta.
sobre o sistema inclui e obtemos um erro do compilador.fonte
#include <>
procure nos diretórios listados com-I
antes dos diretórios padrão do sistema-I
são relativos ao diretório onde você executa o gcc, e não ao arquivo que está sendo compilado. A diferença é significativa se você fizer issog++ -Ifrobnicate blah/foo.cc
PATH
variável de ambiente (em sistemas Linux) afetam como o compilador procura por arquivos?