Пакет GCC содержит в себе несколько модулей для поддержки различных инструментов компиляции. И в зависимости от того, какой модуль используется, могут меняться пути поиска заголовочных файлов. Для языков Си и С++ используются следующие модули (инструменты):
- cc1 - Компилятор языка C, принимает на вход препроцессированные .i-файлы и порождает оптимизированные .S-ассемблерные листинги.
- cc1plus – Компилятор языка C++, принимает на вход препроцессированные .i-файлы и порождает оптимизированные .S-ассемблерные листинги.
- cpp – Препроцессор C-based языков программирования (C Pre Processor), таких как C, C++, Objective-C, Objective-C++. Принимает на вход исходные файлы и порождает .i-файлы.
Команда получения списка INCLUDE-директорий для компилятора языка C следующая:
`gcc -print-prog-name=cc1` -v
Да, команда содержит обратные апострофы. Без них результат будет совсем другим. Часть в обратных апострофах будет содержать имя бинарника компилятора Си, который вызывается на исполнение с помощью этих обратных апострофов, получая опцию -v. Данная команда выдаст в стандартный поток различную информацию о компиляторе, среди которой будет список путей поиска подключаемых файлов:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include
End of search list.
Команда для компилятора языка C++ следующая:
`gcc -print-prog-name=cc1plus` -v
В результате будет выведена информация о настройках компилятора Си++, среди которой так же будет список подключаемых по-умолчанию директорий:
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/10
/usr/include/x86_64-linux-gnu/c++/10
/usr/include/c++/10/backward
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include
End of search list.
Следует учитывать, что для C-based языков программирования (C, C++, Objective-C, Objective-C++) для препроцессинга #include-директив, макросов и прочих директив препроцессора используется один и тот же инструмент cpp, так как принципы препроцессинга во всех этих языках одинаковые.
Учитывая, что препроцессор вызывается до компилятора, то для понимания какие еще директории видны для INCLUDE, можно дать команду:
`gcc -print-prog-name=cpp` -v
В результате будет следующий список:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
Таким образом, можно сказать, что при обработке Си кода, в самой базе используются INCLUDE-директории, которые отображаются для инструментов cc1 и cpp. А для обработки Си++ кода используются INCLUDE-директории инструментов cc1plus и cpp. Сам бинарник gcc является оберткой над этими инструментами и из-под себя запускает их, основываясь на опциях командной строки и расширении файлов.