Как сказать g++ компилятор, где искать включенные файлы?

В "рабочем каталоге" у меня много файлов *.cpp и *.h, которые #include друг друга и файлы из подкаталогов.

Например:

#include "first.h"
#include "second.h"
#include "dir1/third.h"
#include "dir2/fourth.h"

В моем собственном каталоге (отличном от "рабочего" каталога) я хотел бы создать новый файл *.cpp и *.h, который включает один из файлов из "рабочего" каталога. Например:

#include "/root/workingdirectory/first.h"

Однако это не сработает. Поскольку "first.h" может включать "second.h" и "second.h" не находится в моем каталоге. Есть ли способ сообщить компилятору, что он должен искать включенные файлы не в текущем, а в рабочем каталоге: /root/workingdirectory/?

Чтобы сделать его еще более сложным, dir1 и dir2 не находятся в моем рабочем каталоге. Они расположены в /root/workingdirectory2/. Итак, мой второй вопрос заключается в том, можно ли решить эту проблему, сообщив компилятору, что подкаталоги расположены где-то еще?

Мне также нужно добавить, что я не использую среду для разработки и компиляции из командной строки (используя g++).

Ответ 1

Прочитать точное руководство

Это там для всех, чтобы читать. У вас даже есть выбор того, что использовать (я бы пошел первым):

-Idir

Добавьте директорию каталога в начало списка каталогов для поиска файлов заголовков. Это можно использовать для переопределения файла заголовка системы, подставляя вашу собственную версию, поскольку эти каталоги просматриваются перед каталогами заголовков системных заголовков. Однако вы не должны использовать эту опцию для добавления каталогов, содержащих файлы заголовков систем поставщика (используйте для этого -isystem). Если вы используете более одного параметра -I, каталоги сканируются в порядке слева направо; после этого появятся стандартные системные каталоги.

Если стандартная система включает каталог или каталог, указанный с помощью -isystem, также указывается с помощью -I, опция -I игнорируется. Каталог по-прежнему выполняется, но в качестве системного каталога в его нормальном положении в системе есть цепочка. Это делается для того, чтобы гарантировать, что процедура GCC для исправления багги системных заголовков и порядок для директивы include_next не будут непреднамеренно изменены. Если вам действительно нужно изменить порядок поиска для системных каталогов, используйте параметры -nostdinc и/или -isystem.

-iquotedir

Добавьте директорию каталога в начало списка каталогов для поиска файлов заголовков только для случая #include "file"; они не ищут #include <file>, иначе как -I.

Ответ 2

Как вам уже сказали, полезно прочитать руководство - в частности в этой главе - и даже более конкретно прямо здесь.

В частности, вы хотите

g++ -I/root/workingdirectory -I/root/workingdirectory2

Обратите внимание также на документацию по синтаксису директивы #include, описанную здесь как:

2.1 Включить синтаксис

Оба файла заголовка пользователя и системы включаются с использованием предварительной обработки директива #include. Он имеет два варианта:

#include <file>

Этот вариант используется для файлов системных заголовков. Он ищет файл с именем file в стандартном списке системных каталогов. Вы можете добавить каталоги в этот список с помощью -I (см. Invocation).

#include "file"

Этот вариант используется для файлов заголовков вашей собственной программы. Он ищет файл с именем file сначала в каталоге содержащий текущий файл, затем в каталогах цитат, а затем те же каталоги, используемые для <file>. Вы можете добавлять каталоги до список каталогов котировок с опцией -iquote. Аргумент #include, независимо от того, заключены ли они с кавычками или угловыми скобками, ведет себя как строковая константа в том, что комментарии не распознаются, и имена макросов не расширены. Таким образом, #include <x/*y> указывает включение файла заголовка системы с именем x/* y.

Однако, если обратные косые черты происходят внутри файла, они считаются обычные текстовые символы, а не символы перехода. Ни один из символов управляющие последовательности, соответствующие строковым константам в C, обрабатываются. Таким образом, #include "x\n\\y" указывает имя файла, содержащего три обратные косые. (Некоторые системы интерпретируют \ как разделитель пути. из них также интерпретировать / таким же образом. Он наиболее переносим для использования только /.)

Это ошибка, если на строке есть что-либо (кроме комментариев) после имени файла.

Итак, например

#include "first.h"

начнет искать в том же каталоге, что и файл .cpp, содержащий эту директиву (или относительный путь относительно этого каталога).

Если вы хотите использовать путь include (указанный -I), вы должны использовать

#include <dir1/third.h>

Обычная практика заключается в использовании формы #include "local.h" для заголовков внутри библиотеки/пакета/модуля (однако вы решили организовать это), а форма #include <external.h> для заголовков из внешних/сторонних или системных библиотек.

Ответ 3

Для gcc это параметр -I для заголовка . Для файлов .cpp вам нужны только те, которые отображаются в качестве аргумента для команды gcc.