Где мой компилятор С++ пытается разрешить мои #includes?

Это действительно основной вопрос. Я изучаю С++, и до сих пор я использовал только стандартную библиотеку. Я включаю такие вещи, как <iostream> и без проблем. Теперь я хочу использовать Apache Xerces, поэтому я установил его на свою машину (систему Debian) и следую учебнику, в котором говорится, что мне нужно включить:

#include <xercesc/sax2/SAX2XMLReader.hpp>

но g++ говорит "error: xercesc/sax2/SAX2XMLReader.hpp: Нет такого файла или каталога". Где он смотрит? Нужно ли мне предоставлять больше информации?

Спасибо.

Ответ 1

Используйте параметр --verbose:

[...]
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.2/../../../../include/c++/4.4.2
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.2/../../../../include/c++/4.4.2/i686-pc-linux-gnu
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.2/../../../../include/c++/4.4.2/backward
 /usr/local/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.2/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.2/include-fixed
 /usr/include
End of search list.
[...]

Вы можете использовать опцию -I для добавления каталогов поиска, как описано здесь: http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Directory-Options.html#Directory-Options

Вы также можете использовать переменные среды для постоянного изменения: http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Environment-Variables.html#Environment-Variables
В вашем случае вы можете использовать CPLUS_INCLUDE_PATH.

Ответ 2

Gcc обычно начинает искать включенные файлы в /usr/include. Если у вас есть файлы в других каталогах, вы можете добавить параметр -I в командную строку, чтобы сообщить компилятору также посмотреть там.

Возможно, вам придется установить пакет разработки для Xerces, чтобы получить файлы #include.

Ответ 3

С++ Standard говорит в 16.2/2

Директива предварительной обработки формы #include <h-char-sequence>new-line ищет последовательность определенных реализацией мест для заголовок, идентифицированный однозначно посредством указанной последовательности между < и > разделители

Определенное реализацией означает, что поиск и поиск заголовков и определение местоположения заголовков специфичны для конкретного компилятора. Фактически, возможно, что реализации не могут использовать один заголовок в одном соглашении с файлами, но некоторые фантастические упаковочные системы, например, вся библиотека должна отправлять заголовки в .zip-архиве, расположение такого архива предоставляется компилятору, затем компилятор принимает уход за извлечением из него заголовков и т.д.

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

В случае компилятора GCC используйте опцию -I - подробнее см. Параметры поиска по каталогам в руководстве. Вы также можете использовать переменные среды C_INCLUDE_PATH или CPLUS_INCLUDE_PATH.

Связанный с этим вопрос Как добавить путь включения по умолчанию для gcc в linux?

Ответ 4

Чтобы сказать g++, где искать (кроме его значений по умолчанию), вы используете флаг -I:

g++ -I/foo/bar xyz.cpp

говорит, что он ищет в каталоге /foo/bar и конструирует пути оттуда. Вы можете использовать несколько флагов -I, чтобы указать несколько стартовых точек для начала поиска компилятора.

В моей довольно старой системе Windows Xerces установлен в /xerces, поэтому я установил флаг include:

-I/xerces/include

Что позволяет мне говорить такие вещи, как:

#include "sax2/SAX2XMLReader.hpp"

чтобы включить файл:

/xerces/include/sax2/SAX2XMLReader.hpp

Ответ 5

Две формы директивы #include достаточно хорошо описаны MSDN:

  • Цитированная форма:

Эта форма указывает препроцессору искать файлы include в том же каталоге файла, который содержит оператор #include, а затем в каталогах любых файлов, которые включают (#include) этот файл. Затем препроцессор выполняет поиск по пути, указанному параметром компилятора /I, а затем по путям, указанным переменной среды INCLUDE.

  • Форма углового кронштейна:

Эта форма инструктирует препроцессор для поиска включенных файлов сначала по пути, указанному параметром компилятора /I, а затем при компиляции из командной строки по пути, указанному переменной среды INCLUDE.

Также см. этот (дублирующий/подобный) вопрос (для g++/GCC):

С++ #include семантика

Ответ 6

Чтобы использовать новую библиотеку, недостаточно указать только заголовочный файл. Вам также может потребоваться указать связанную библиотеку, определенную в файле заголовка, с помощью -l [имя библиотеки] и -L [путь к библиотеке], которые вы хотите связать в своем gcc commend.

Для разницы между файлом заголовка и библиотекой, пожалуйста, отметьте это сообщение: Что такое файлы заголовков и файлы библиотеки?