Должны ли пути #include в файле C и директива -I, заданная для GCC, совпадать?

Я смотрю демонстрационный проект FreeRTOS для порта AVR. Makefile имеет пути к каталогам, в которых находятся исходные файлы RTOS, через директиву -I. Однако в модуле main.c проекта #include не предоставляет пути, подобного этому:

#include "FreeRTOS.h"

Итак, я не могу понять, что директива -I требуется только для компоновщика, чтобы найти объектные файлы? Означает ли это также, что после того, как файлы скомпилированы в объектный код, для GCC они по сути лежат в одной папке, если он знает, где искать?

У меня возникла эта путаница, потому что я видел подобные операторы #include ранее:

#include <avr/io.h>

Если GCC уже знает местоположение io.h, зачем включать перед ним часть avr?


person A. Munir    schedule 13.09.2020    source источник
comment
У тебя немного задом наперед. -I указывает компилятору искать по этому пути файлы заголовков. Именно по этой причине #include "FreeRTOS.h" не нужен путь. Если бы не было -I, вам нужно было бы указать полный путь в #include (что является плохой практикой).   -  person kaylum    schedule 13.09.2020


Ответы (1)


Когда мы говорим

#include <foo/bar.h>

компилятор обычно ищет файл с именем bar.h в каталоге с именем foo в одном из мест, где он сконфигурирован для поиска заголовков. Например, стандартный путь поиска заголовков обычно содержит `/usr/include', поэтому файл 'bar.h', если он существует, будет найден в '/usr/include/foo'.

Если вы используете переключатель -I следующим образом:

-I /usr/include/foo

вы могли бы в качестве альтернативы написать

#include <bar.h>

потому что вы включили каталог foo в путь поиска заголовка компилятора.

Однако, если foo является какой-то библиотекой или модулем, вероятно, будет более выразительно использовать вариант #include, который включает подкаталог foo, а не манипулировать путем поиска заголовков, чтобы вам не приходилось этого делать.

Для справки, переключатель -I не имеет прямого влияния на поведение компоновки.

Кстати, вариант

#include "foo/bar.h"

условно указал файл в каталоге foo в том же каталоге, что и исходный файл. Однако современные компиляторы, по-видимому, применяют пути заголовков поиска и к этим директивам. Я не уверен, является ли это поведением, основанным на стандартах, или просто авторы компиляторов пытаются угадать наши намерения.

person Kevin Boone    schedule 13.09.2020