Программирование ARM gcc: опции для управления препроцессором Thu, May 30 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

gcc: опции для управления препроцессором Печать
Добавил(а) microsin   

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

Если вы используете опцию -E, то ничего не произойдет, кроме обрабработки препроцессора. Некоторые из этих опций имеет смысл использовать только вместе с -E, поскольку они делают вывод препроцессора неподходящим для фактической компиляции.

В дополнение к перечисленным ниже опциям также существует несколько опций для управления путями поиска подключаемых файлов (см. [2]). Опции для управления диагностиками препроцессора перечислены в руководстве [3].

-D name

Определяет name как макрос со значением 1.

-D name=definition

Содержимое definition преобразуется в токен и обрабатывается так, как если бы оно появилось как строка ‘#define name definition’ в заголовке или модуле. В частности, из строки definition вырезаются символы новой строки.

Если вы запустили препроцессор из шелла, или из программы наподобие шелла, то может понадобиться синтаксис обрамления кавычками, чтобы защитить такие символы, как пробел, и строка корректно передавалась в интерпретатор шелла.

Если вы хотите определить в командной строке макрос, выглядящий как функция, то записывайте его список аргументов перед знаком равенства в скобках (если аргументы есть). Скобки значимы для большинства оболочек шелла, так что вам следует цитировать (обрамлять кавычками) опцию. Для шелов sh и csh работает определение наподобие -D'name(args…)=definition'. Например, для bash, чтобы эмулировать строковое определение IP-адреса наподобие #define HOST_IP "192.168.0.1", используйте опцию -D'HOST_IP="192.168.0.1"'.

Опции -D и -U обрабатываются в том же порядке, в каком они указываются в командной строке. Все опции -imacros file и -include file обрабатываются после всех опций -D и -U.

-U name

Отменяет педыдущее определение для name, либо встроенное, либо предоставленное через опцию -D.

-include file

Обрабатывает файл file как если бы директива #include "file" появилась в первой строке главного модуля исходного кода. Однако первым каталогом, в котором происходит поиск для файла, является рабочая директория препроцессора вместо директории, в котором содержится главный обрабатываемый исходный файл. Если в рабочей директории файл не найден, то поиск продолжается в оставшейся части цепочки поиска #include "...", как обычно.

Если предоставлено несколько опций -include, то файлы подключаются в том порядке, в каком они появились в командной строке.

-imacros file

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

Все файлы, указанные через -imacros, обрабатываются перед файлами, указанными через -include.

-undef

Не делает предварительное определение любых специфичных для системы или для GCC макросов. Стандартные предопределенные макросы остаются определяемыми.

-pthread

Определяет дополнительные макросы для использования библиотекой потоков POSIX. Вы должны использовать эту опцию в соответствии как с компиляцией, так и линковкой. Эта опция поддерживается на GNU/Linux target-ах, на большинстве других деривативов Unix, и также на x86 Cygwin и MinGW target-ах.

-M

Вместо вывода результата препроцессинга выведет правило, подходящее для make, описывающее зависимости главного исходного файла. Препроцессор выведет одно правило make, содержащее имя объектного файла для этого исходного файла, двоеточие, и имена всех подключенных файлов, включая те, которые были задействованы опциями командной строки -include или -imacros.

За исключением случая, когда применено уточнение (через -MT или -MQ), имя объектного файла состоит из имени исходного файла с любым суффиксом, замененным на суффикс объектного файла, и удаленными любыми именами директорий. Если подключается множество файлов, то правило разделяется на несколько строк с использованием символов \ и \n. У правила нет команд.

Эта опция не подавляет отладочный вывод препроцессора, такой как -dM. Чтобы избежать микширования такого отладочного вывода с правилами зависимостей, вы должны явно указать файл вывода зависимостей с помощью -MF, или использовать переменную окружения наподобие DEPENDENCIES_OUTPUT (см. описание переменных окружения, влияющих на GCC [4]). Отладочный вывод все еще будет отправлен в обычный поток вывода (stdout).

Передача -M драйверу подразумевает -E, и подавляет warning-и с неявным указанием -w.

-MM

Работает подобно -M, но не упоминает заголовочные файлы, которые найдены директориях системных заголовков, или файлы заголовков, которые явно или косвенно подключены из таких заголовков.

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

-MF file

При использовании вместе с -M или -MM указывает файл, куда будут записана информация о зависимостях. Если опция -MF не указана, то препроцессор посылает правила туда же, куда отправляет вывод препроцессора.

При использовании опций драйвера -MD или -MMD, опция -MF переназначает выходной файл зависимостей по умолчанию.

Если file это -, то зависимости записываются в stdout.

-MG

Вместе с опцией, такой как -M, запрашивающей генерацию зависимостей, -MG подразумевает не найденные файлы заголовка как генерируемые файлы, и добавляет их к списку зависимостей без выдачи ошибки. Файл зависимостей берется напрямую из директивы #include без любых предшествующих путей. -MG также подавляет вывод препроцессора, поскольку отсутствующий файл заголовка делает его бесполезным.

Эта функция используется в автоматическом обновлении файлов makefile.

-Mno-modules

Отключает создание зависимостей для скомпилированных интерфейсов модулей.

-MP

Эта опция инструктирует CPP добавить phony target для каждой зависимости, кроме главного файла, в результате каждая из них не зависит ни от чего. Эти пустые работают вокруг ошибок make, если вы удалите файлы заголовка без обновления Makefile для проверки совпадения.

Типовой вывод с этой опцией:

test.o: test.c test.h
 
test.h:

-MT target

Меняет target правила, выпущенного генерацией зависимости. По умолчанию CPP берет имя главного входного файла, удаляет любые составляющие директорий и любой суффикс наподобие ‘.c’, и добавляет обычный суффикс объекта платформы. Результатом является target.

Опция -MT установит target точно в указанную вами строку. Если вы хотите несколько target, то можете указать их как один аргумент для -MT, или можете использовать несколько опций -MT.

Например, -MT '$(objpfx)foo.o' может дать:

$(objpfx)foo.o: foo.c

-MQ target

То же самое, что и -MT, но обрамляет кавычками любые символы, являющиеся для make специальными. Указание -MQ '$(objpfx)foo.o' дает:

$$(objpfx)foo.o: foo.c

Target по умолчанию автоматически обрамляется кавычками, как если бы она была предоставлена с -MQ.

-MD

Опция -MD это эквивалент -M -MF file, за исключением того, что -E не подразумевается. Драйвер определяет file, основываясь на том, указана ли опция -o. Если указан, то драйвер использует её аргумент, но с суффиксом .d, иначе берет имя входного файла, удаляет любые компоненты директорий и удаляет суффикс, и добавляет суффикс .d.

Если -MD используется вместе с -E, то любая опция -o принимается для указания выходного файла зависимости (см. -MF), но если -MD используется без -E, то каждая -o принимается для указания выходного целевого файла.

Поскольку -E не подразумевается, -MD может использоваться для генерации выходного файла зависимости как побочный эффект процесса компиляции.

-MMD

Работает наподобие -MD, за исключением указания только файлов заголовка пользователя, но не системных файлов заголовка.

-fpreprocessed

Показывает препроцессору, что входной файл уже подвергся обработке препроцессора. Это подавляет такие вещи, как расширение макроса, преобразование триграфа, склеивание строк по esc-символу новой строки и обработку большинства директив. Препроцессор все еще распознает и удаляет комментарии, так что вы можете без проблем передать компилятору файл, обработанный с помощью -C. В этом режиме интегрированный препроцессор это токенизатор для фронтэндов.

Опция -fpreprocessed неявно подразумевается, если входной файл имеет одно из расширений ‘.i’, ‘.ii’ или ‘.mi’. Это расширения, которые GCC использует для обработанных препроцессором файлов, созданных через -save-temps.

-fdirectives-only

В препроцессинге задает обрабатывать директивы, но не разворачивать макросы.

Поведение этой опции зависит от опций -E и -fpreprocessed.

С опцией -E препроцессинг ограничен обработкой таких директив, как #define, #ifdef и #error. Другие операции препроцессора, такие как расширение макросов и преобразование триграфа, не выполняются. Дополнительно неявно разрешена опция -dD.

С опцией -fpreprocessed определения командной строки и большинство встроенных макросов запрещены. Такие макросы, как __LINE__, которые зависят от контекста, обрабатываются нормальным образом. Это разрешает компиляцию файлов, ранее прошедших препроцессор с опциями -E -fdirectives-only.

Когда указаны обе опции -E и -fpreprocessed, получают преимущества правила для -fpreprocessedtake. Это разрешает полный препроцессинг файлов, ранее прошедших препроцессор с опциями -E -fdirectives-only.

-fdollars-in-identifiers

Принимает ‘$’ в идентификаторах.

-fextended-identifiers

Принимает универсальные символьные имена с расширенными символами в идентификаторах. Эта опция разрешена по умолчанию для C99 (и более поздних версий стандарта C) и C++.

-fno-canonical-system-headers

Во время препроцессинга не выполняется сокращение путей системных заголовков с помощью канонизации.

-fmax-include-depth=depth

Устанавливает максимальную глубину вложенных #include. По умолчанию глубина вложенности 200.

-ftabstop=width

Устанавливает интервал табуляции. Это помогает препроцессору корректно сообщать о номерах столбцов с сообщениях предупреждений или ошибок, даже если в строке встречаются символы табуляции. Если значение меньше 1 или больше 100, то опция игнорируется. По умолчанию размер табуляции 8.

-ftrack-macro-expansion[=level]

Отслеживает расположение токенов (маркеров) в макросах. Это позволяет компилятору выдавать диагностические сообщения о текущем стеке расширения макросов, когда при расширении макроса возникает ошибка. Использование этой опции приводит к увеличенному расходу памяти препроцессором и компилятором. Параметр level может использоваться для выбора уровня точности отслеживания расположения токена, так что с помощью этого параметра можно уменьшить потребление памяти. Значение ‘0’ для level деактивирует эту опцию. Значение ‘1’ грубо отслеживает места токенов (degraded mode) с минимальным расходом памяти. В этом режиме все токены, являющиеся результатом расширения аргумента макроса, оформленного в виде функции, имеют одно и то же расположение. Значение ‘2’ полностью отслеживает места расположения токенов. Это значение максимально расходует память. Когда эта опция указана без аргумента, используется значение параметра по умолчанию ‘2’.

Имейте в виду, что -ftrack-macro-expansion=2 активируется по умолчанию.

-fmacro-prefix-map=old=new

Когда файлы препроцессора находятся в директории old, макросы __FILE__ и __BASE_FILE__ расширяются как если бы файлы вместо этого находились в директории new. Это может использоваться для изменения абсолютного пути на относительный путь с использованием '.' для new что может дать результат более продуктивной сборки, не зависящей от текущего места на диске. Эта опция во время компиляции также влияет на __builtin_FILE(). См. также -ffile-prefix-map и -fcanon-prefix-map.

-fexec-charset=charset

Установит набор символов выполнения (execution character set), используемый для строковых и символьных констант. По умолчанию используется кодировка UTF-8. Значение charset может быть только из поддерживаемых кодировок в библиотечной функции iconv системы.

-fwide-exec-charset=charset

Устанавливает широкий набор символов выполнения, используемых в "широких" (wide) строковых и символьных константах. По умолчанию используется одна из кодировок UTF-32BE, UTF-32LE, UTF-16BE или UTF-16LE, в зависимости от того, какая из них соответствует ширине wchar_t, и порядка следования байт big-endian или little-endian, используемого для генерации кода. Также как и для опции -fexec-charset, набор символов должен быть из поддерживаемых в библиотечной функции iconv системы; однако у вас будут проблемы с кодировками, которые не укладываются полностью в wchar_t.

-finput-charset=charset

Установит входной набор символов, используемый для трансляции из набора символов входного файла в набор символов, который использует GCC. Если локаль не указана, или GCC не может получить эту информацию из локали, то по умолчанию используется UTF-8. Это может быть переназначено либо с помощью локали, или с помощью этой опции командной строки. В настоящее время опция командной строки имеет приоритет, если имеет место конфликт. Значение charset может быть только из поддерживаемых кодировок в библиотечной функции iconv системы.

-fpch-deps

Когда используются предварительно скомпилированные заголовки (precompiled headers, см. [5]), эта опция заставляет флаги вывода зависимостей также перечислять файлы из зависимостей precompiled header’s . Если эта опция не указана, то перечисляются только precompiled header, а не файлы, которые использовались для их создания, потому что к ним не было обращения при использовании precompiled header.

-fpch-preprocess

Эта опция позволяет использовать precompiled header (см. [5]) совместно с -E. Это вставит в вывод специальные #pragma, #pragma GCC pch_preprocess "filename", чтобы пометить место, где был найден precompiled header, и его имя файла. Когда используется -fpreprocessed, GCC распознает эти #pragma, и загружает PCH.

Эта опция по умолчанию выключена, потому что результирующий вывод препроцессинга действительно пригоден только для ввода в GCC. Это включается опцией -save-temps.

Вы не должны записывать #pragma в своем коде, однако можно безопасно редактировать имя файла, если файл PCH доступен в другом месте. Имя файла может быть абсолютным, или относительным для текущей директории GCC.

-fworking-directory

Разрешает генерацию маркеров строки в выводе препроцессора, который позволит компилятору знать текущую рабочую директорию во время препроцессинга. Когда эта опция разрешена, препроцессор выдает после начального маркера строки второй маркер строки с текущей рабочей директорией, за которой идут 2 слешаs. GCC использует эту директорию, когда она присутствует во вводе результата препроцессора, как текущий рабочий каталог в некоторых форматах вывода отладочной информации. Эта опция неявно разрешена, если разрешена отладочная информация, однако это может быть запрещено негативной формой опции -fno-working-directory. Если в командной строке присутствует флаг -P, то эта опция не дает эффекта, поскольку никакие директивы #line вообще не выпускаются.

-A predicate=answer

Делает утверждение (assertion) с предикатом predicate и ответом answer. Эта форма предпочитается старой форме -A predicate(answer), которая все еще поддерживатся, потому что она не использует специальные символы шелла.

-A -predicate=answer

Отменяет утверждение с предикатом predicate и ответом answer.

-C

Не отбрасывает комментарии. Все комментарии передаются в выходной файл за исключением тех комментариев, которые были обработаны директивами (#if/#ifdef и т. п.) и были удалены из-за этих директив.

Вы должны быть готовы к побочным эффектам при использовании -C, потому что она заставляет препроцессор рассматривать комментарии как токены. Например комментарии, начинающиеся в начале строки директивы, приводят к превращению этой строки в обычную строку исходного кода, поскольку первый маркер в строке больше не символ ‘#’.

-CC

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

В дополнение к побочным эффектам опции -C, опция -CC приводит к тому, что все комментарии в стиле C++ преобразуются в комментарии стиля C. Это необходимо для предотвращения непреднамеренного комментирования оставшейся части строки исходного кода при последующем использовании этого макроса.

Опция -CC в основном используется для поддержки комментариев lint [6].

-P

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

-traditional
-traditional-cpp

Пытается иммитировать поведение препроцессоров pre-standard C preprocessors, в отличие от стандарта препроцессоров ISO C. Подробности см. в руководстве GNU CPP.

Обратите внимание, что GCC иначе не пытается эмулировать pre-standard C компилятор, и эти опции поддерживаются только вместе с опцией -E, или при явном вызове CPP.

-trigraphs

Поддерживает триграфы ISO C. Это трехсимвольные последовательности, которые всегда начинаются на ‘??’. Они определены стандартом ISO C для обозначение одиночных символов. Например ‘??/’ обозначает ‘\’, так что ‘'??/n'’ это символьная константа для управляющего кода новой строки.

Вот 9 триграфов, и что они означают:

Trigraph:         ??(  ??)  ??<  ??>  ??=  ??/  ??'  ??!  ??-
Заменяется на:      [    ]    {    }    #    \    ^    |    ~

По умолчанию GCC игнорирует триграфы, но в режимах, удовлетворяющих стандарту, преобразует их. См. описание опций -std и -ansi.

-remap

Разрешает специальный код, чтобы работать с файловыми системами, которые разрешают только очень короткие имена файлов (такие как MS-DOS).

-H

В дополнение к другим нормальным активным действиям печатает имя каждого используемого заголовочного файла. Каждое имя имеет отступы, показывающие, какг глубоко было погружение в стек вложений #include. Также печатаются precompiled-заголовочные файлы, даже если они были обнаружены как некорректные; некорректные precompiled header файлы печатаются с ‘...x’, а корректные с ‘...!’.

-dletters

Говорит делать дампы отладки во время компиляции, как указано буквами. Документированные здесь флаги относятся к препроцессору. Другие буквы интерпретируются самим компилятором, или зарезервированы для будущих версий GCC, так что молча игнорируются. Если вы укажете буквы, у которых конфликтное поведение, то получится неопределенный результат. Для дополнительной информации см. описание опций разработчика GCC [7].

-dD
Работает наподобие -dM, за исключением двух аспектов: не подключаются предопределенные макросы, и выводятс как директивы ‘#define’, так и результат препроцессинга. Оба вида вывода попадают в стандартный выходной файл.

-dN
Работает наподобие -dD, но выдает только имена макросов, а не их расширение.

-dI
Выводит директивы ‘#include’ в дополнение к результату препроцессинга.

-dU
Работает наподобие -dD, за исключением того, что выводятся только макросы, которые развернуты или определение которых проверено директивами препроцессора. Вывод откладывается до использования или проверки макроса; и директивы ‘#undef’ также выведут проверенные, но не определенные в настоящее время макросы.

-fdebug-cpp

Эта опция полезна только для отладки GCC. Когда используется из CPP или вместе с -E, она приводит в дампу отладочной информации с картами размещения. Каждому токену в выводе предшествует дамп карты, к которой принадлежит его расположение.

Эта опция не дает никакого эффекта, когда используется из GCC без -E.

-Wp,option

Вы можете использовать -Wp,option для пропуска драйвера компилятора и передачи опции option напрямую препроцессору. Если строка в option содержит запятые, то она разделяется на несколько опций. Однако многие опции перед передачей препроцессору модифицируются, транслируются или интерпретируются драйвером компилятора, и -Wp принудительно пропускает эту фазу. Интерфейс прямой передачи опций препроцессору не документирован и может измениться, поэтому лучше избегать использования -Wp, и вместо этого предоставить драйверу обрабатывать опции.

-Xpreprocessor option

Передает опцию option как опцию для препроцессора. Вы можете это использовать, чтобы предоставить специфичные для системы опции препроцессора, которые не распознает GCC.

Если вы хотите передать опцию, которая принимает аргумент, то должны использовать -Xpreprocessor дважды, один раз для опции, и один раз для аргумента.

-no-integrated-cpp

Выполняет препроцессинг как отдельный проход перед компиляцией. По умолчанию GCC выполняет препроцессинг как инегрированную часть токенизации ввода и парсинга. Если предоставлена эта опция, то вместо этого дважды запускается front end подходящего языка (cc1, cc1plus или cc1obj для C, C++ и Objective-C соответственно), один раз для препроцессинга, и еще один раз для реальной компиляции прошедшего препроцессинг ввода. Эта опция может быть полезна вместе с опциями -B или -wrapper, чтобы указать альтернативный препроцессор, или выполнить дополнительную обработку исходного кода программы между нормальными препроцессингом и комиляцией.

-flarge-source-files

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

В частности, GCC обычно отслеживает и номера столбцов (позиции в строке), и номера строк в исходных файлах, и нормально печатает их оба в диагностических сообщениях. Однако после обработки определенного количества строк исходного кода он прекращает отслеживание номеров столбцов, отслеживая только номера строк. Это означает, что диагностика последующих строк не будет включать номера позиций в строке. Это также означает, что опции наподобие -Wmisleading-indentation в этом месте перестают работать, хотя компилятор печатает замечание об этом, когда подобное происходит. Передача опции -flarge-source-files значительно увеличивает количество строк исходного кода, которое GCC может обработать без остановки отслеживания столбцов.

[Ссылки]

1. Options Controlling the Preprocessor site:gcc.gnu.org.
2. Options for Directory Search site:gcc.gnu.org.
3. Options to Request or Suppress Warnings site:gcc.gnu.org.
4. Environment Variables Affecting GCC site:gcc.gnu.org.
5. Using Precompiled Headers site:gcc.gnu.org.
6. Lint (software) site:wikipedia.org.
7. GCC Developer Options site:gcc.gnu.org.

 

Добавить комментарий


Защитный код
Обновить

Top of Page