Spec-Zone.ru › GCC 5

3.15 Указание подпроцессов и переключателей, передаваемых им

gcc — это программа-драйвер. Она выполняет свою работу, вызывая последовательность других программ для выполнения задач компиляции, сборки и компоновки. GCC интерпретирует параметры командной строки и использует их для определения, какие программы вызывать и какие параметры командной строки следует передать им. Это поведение контролируется _строками спецификаций_. В большинстве случаев для каждой программы, которую может вызвать GCC, существует одна строка спецификаций, но некоторые программы имеют несколько строк спецификаций для управления их поведением. Встроенные в GCC строки спецификаций можно переопределить, используя переключатель командной строки -specs= для указания файла спецификаций.

Файлы спецификаций — это текстовые файлы, используемые для построения строк спецификаций. Они состоят из последовательности директив, разделенных пустыми строками. Тип директивы определяется первым символом, отличным от пробела, в строке, который может быть одним из следующих:

%command

Отправляет команду процессору файла спецификаций. Команды, которые могут здесь появляться, это:

%include <file>

Ищет файл и вставляет его текст в текущую точку файла спецификаций.

%include_noerr <file>

То же, что и ‘%include’, но не генерирует сообщение об ошибке, если файл включения не найден.

%rename old_name new_name

Переименовывает строку спецификаций old_name в new_name.

*[spec_name]:

Это сообщает компилятору создать, переопределить или удалить именованную строку спецификаций. Все строки после этой директивы до следующей директивы или пустой строки считаются текстом для строки спецификаций. Если это приводит к пустой строке, то спецификация удаляется. (Или, если спецификация не существовала, ничего не происходит.) В противном случае, если спецификация в данный момент не существует, создаётся новая спецификация. Если спецификация существует, её содержимое переопределяется текстом этой директивы, если первый символ этого текста не является символом ‘+’, в этом случае текст добавляется к спецификации.

[suffix]:

Создаёт новую пару «[суффикс] спецификация». Все строки после этой директивы и до следующей директивы или пустой строки считаются составляющими строку спецификации для указанного суффикса. Когда компилятор встречает входной файл с указанным суффиксом, он обрабатывает строку спецификации, чтобы выяснить, как скомпилировать этот файл. Например:

.ZZ:
z-compile -input %i

Это означает, что любой входной файл, имя которого оканчивается на ‘.ZZ’, должен передаваться программе ‘z-compile’, которая должна вызываться с переключателем командной строки -input и с результатом выполнения подстановки ‘%i’. (См. ниже.)

В качестве альтернативы предоставлению строки спецификации текст, следующий за директивой суффикса, может быть одним из следующих:

@language

Это означает, что суффикс является псевдонимом известного языка. Это аналогично использованию переключателя командной строки -x в GCC для явного указания языка. Например:

.ZZ:
@c++

Указывает, что файлы .ZZ, фактически, являются исходными файлами C++.

#name

Это приводит к сообщению об ошибке, гласящему:

name compiler not installed on this system.

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

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

asm          Options to pass to the assembler
asm_final    Options to pass to the assembler post-processor
cpp          Options to pass to the C preprocessor
cc1          Options to pass to the C compiler
cc1plus      Options to pass to the C++ compiler
endfile      Object files to include at the end of the link
link         Options to pass to the linker
lib          Libraries to include on the command line to the linker
libgcc       Decides which GCC support library to pass to the linker
linker       Sets the name of the linker
predefines   Defines to be passed to the C preprocessor
signed_char  Defines to pass to CPP to say whether char is signed
             by default
startfile    Object files to include at the start of the link

Вот небольшой пример файла спецификаций:

%rename lib                 old_lib

*lib:
--start-group -lgcc -lc -leval1 --end-group %(old_lib)

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

Строки спецификаций — это список параметров командной строки, которые будут переданы соответствующей программе. Кроме того, строки спецификаций могут содержать последовательности, начинающиеся с ‘%’, для подстановки текстовых переменных или условной вставки текста в командную строку. С помощью этих конструкций можно генерировать довольно сложные командные строки.

Вот таблица всех определённых последовательностей ‘%’ для строк спецификаций. Обратите внимание, что пробелы автоматически не генерируются вокруг результатов расширения этих последовательностей. Поэтому вы можете конкатенировать их или объединять с постоянным текстом в одном аргументе.

%%

Замещает одну ‘%’ в имени программы или аргументе.

%i

Замещает имя входного файла, который обрабатывается.

%b

Замещает имя базовой части входного файла, который обрабатывается. Это подстрока до (и не включая) последней точки и не включая каталог.

%B

Это то же самое, что ‘%b’, но включает суффикс файла (текст после последней точки).

%d

Помечает аргумент, содержащий или следующий за ‘%d’, как имя временного файла, так что этот файл будет удалён, если GCC завершится успешно. В отличие от ‘%g’, это не добавляет текста в аргумент.

%gsuffix

Замещает имя файла с суффиксом suffix, выбранное один раз за компиляцию, и помечает аргумент таким же образом, как ‘%d’. Для уменьшения уязвимости к атакам типа «отказ в обслуживании», имя файла теперь выбирается таким образом, что его сложно предсказать, даже зная ранее выбранные имена файлов. Например, ‘%g.s … %g.o … %g.s’ может превратиться в ‘ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s’. suffix соответствует регулярному выражению ‘[.A-Za-z]*’ или специальной строке ‘%O’, которая обрабатывается точно так же, как если бы ‘%O’ была предварительно обработана. Раньше ‘%g’ просто замещалась именем файла, выбранным один раз за компиляцию, без учёта добавленного суффикса (который поэтому обрабатывался как обычный текст), что делало такие атаки более вероятными.

%usuffix

Как ‘%g’, но генерирует новое временное имя файла каждый раз при появлении, вместо одного на компиляцию.

%Usuffix

Замещает последнее имя файла, сгенерированное с помощью ‘%usuffix’, генерируя новое, если такого последнего имени файла нет. В отсутствие ‘%usuffix’, это то же самое, что ‘%gsuffix’, за исключением того, что они не используют то же пространство суффиксов, так что ‘%g.s … %U.s … %g.s … %U.s’ включает в себя генерацию двух отдельных имён файлов, по одному для каждого ‘%g.s’ и другого для каждого ‘%U.s’. Раньше ‘%U’ просто замещалось именем файла, выбранным для предыдущего ‘%u’, без учёта добавленного суффикса.

%jsuffix

Замещает имя HOST_BIT_BUCKET, если оно есть, если оно доступно для записи и если не используется -save-temps; в противном случае замещает именем временного файла, как и ‘%u’. Этот временный файл не предназначен для межпроцессного обмена, а скорее как механизм удаления мусора.

%|suffix
%msuffix

Как ‘%g’, за исключением случаев, когда включена опция -pipe. В этом случае ‘%|’ замещает одиночным дефисом, а ‘%m’ — ничем. Это два наиболее распространённых способа указать программе, что она должна читать из стандартного ввода или записывать в стандартный вывод. Если вам нужно что-то более сложное, вы можете использовать конструкцию ‘%{pipe:X}’: см., например, f/lang-specs.h.

%.SUFFIX

Замещает .SUFFIX суффиксами аргументов соответствующего переключателя, когда он затем выводится с помощью ‘%*’. SUFFIX заканчивается следующим пробелом или символом %.

%w

Помечает аргумент, содержащий или следующий за ‘%w’, как назначенный выходной файл этой компиляции. Это помещает аргумент в последовательность аргументов, которые замещает ‘%o’.

%o

Замещает имена всех выходных файлов с автоматическим добавлением пробелов вокруг них. Вы должны также добавить пробелы вокруг ‘%o’, иначе результаты будут неопределёнными. ‘%o’ предназначен для использования в спецификациях для запуска компоновщика. Входные файлы, имена которых не имеют распознаваемого суффикса, не компилируются, но включаются среди выходных файлов, поэтому они подключаются.

%O

Замещает суффикс для файлов объектов. Обратите внимание, что это обрабатывается специально, когда он следует непосредственно за ‘%g, %u или %U’, из-за необходимости формирования полных имён файлов. Обработка такова, что ‘%O’ обрабатывается так, как будто он уже был заменён, за исключением того, что ‘%g, %u и %U’ в настоящее время не поддерживают дополнительные символы suffix, следующие за ‘%O’, как они следуют, например, за ‘.o’.

%p

Замещает стандартные макроопределения для текущей целевой машины. Используйте это при запуске cpp.

%P

Как ‘%p’, но помещает ‘__’ перед и после имени каждого предварительно определённого макроса, за исключением макросов, которые начинаются с ‘__’ или с ‘_L’, где L — заглавная буква. Это для ISO C.

%I

Замещает любые из -iprefix (составленный из GCC_EXEC_PREFIX), -isysroot (составленный из TARGET_SYSTEM_ROOT), -isystem (составленный из COMPILER_PATH и опций -B) и -imultilib при необходимости.

%s

Текущий аргумент — имя библиотеки или файла запуска. Ищем этот файл в стандартном списке каталогов и заменяем полным найденным именем. В список сканируемых каталогов включен текущий рабочий каталог.

%T

Текущий аргумент — имя файла сценария компоновщика. Ищем этот файл в текущем списке каталогов для сканирования библиотек. Если файл найден, в командную строку вставляется опция --script, за которой следует полный путь к найденному файлу. Если файл не найден, выводится сообщение об ошибке. Примечание: текущий рабочий каталог не проверяется.

%estr

Выводит str как сообщение об ошибке. str завершается новой строкой. Используйте это при обнаружении несовместимых опций.

%(name)

В данном месте подставляется содержимое строки спецификации name.

%x{option}

Накапливает опцию для ‘%X’.

%X

Выводит накопленные опции компоновщика, указанные с помощью -Wl или строки спецификации ‘%x’.

%Y

Выводит накопленные опции ассемблера, указанные с помощью -Wa.

%Z

Выводит накопленные опции препроцессора, указанные с помощью -Wp.

%a

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

%A

Обрабатывает спецификацию asm_final. Это строка спецификации для передачи переключателей в постпроцессор ассемблера, если такой программа необходима.

%l

Обрабатывает спецификацию link. Это спецификация для вычисления командной строки, передаваемой компоновщику. Обычно она использует последовательности ‘%L %G %S %D и %E’.

%D

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

%L

Обрабатывает спецификацию lib. Это строка спецификации для определения того, какие библиотеки включаются в командную строку для компоновщика.

%G

Обрабатывает спецификацию libgcc. Это строка спецификации для определения того, какая библиотека поддержки GCC включается в командную строку для компоновщика.

%S

Обрабатывает спецификацию startfile. Это спецификация для определения тех файлов объектов, которые передаются в компоновщик в первую очередь. Обычно это может быть файл с именем crt0.o.

%E

Обрабатывает спецификацию endfile. Это строка спецификации, которая определяет последние файлы объектов, передаваемые компоновщику.

%C

Обрабатывает спецификацию cpp. Это используется для построения аргументов, которые будут переданы препроцессору C.

%1

Обрабатывает спецификацию cc1. Это используется для построения опций, которые будут переданы фактическому компилятору C (cc1).

%2

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

%*

Заменяет переменную часть соответствующей опции. Смотрите ниже. Обратите внимание, что каждая запятая в подставленной строке заменяется одним пробелом.

%<S

Удаляет все вхождения -S из командной строки. Примечание — эта команда зависит от позиции. Команды ‘%’ в строке спецификации перед этой командой видят -S, команды ‘%’ в строке спецификации после этой команды — нет.

%:function(args)

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

Ниже приведены встроенные функции спецификатора:

getenv

Функция спецификатора getenv принимает два аргумента: имя переменной среды и строку. Если переменная среды не определена, выдаётся ошибка. В противном случае возвращаемое значение — это значение переменной среды, конкатенированное со строкой. Например, если TOPDIR определена как /path/to/top, то:

%:getenv(TOPDIR /include)

расширяется до /path/to/top/include.

if-exists

Функция спецификатора if-exists принимает один аргумент — абсолютный путь к файлу. Если файл существует, if-exists возвращает путь. Вот небольшой пример её использования:

*startfile:
crt0%O%s %:if-exists(crti%O%s) crtbegin%O%s
if-exists-else

Функция спецификатора if-exists-else похожа на функцию спецификатора if-exists, за исключением того, что она принимает два аргумента. Первый аргумент — абсолютный путь к файлу. Если файл существует, if-exists-else возвращает путь. Если он не существует, она возвращает второй аргумент. Таким образом, if-exists-else можно использовать для выбора одного файла или другого на основе существования первого. Вот небольшой пример её использования:

*startfile:
crt0%O%s %:if-exists(crti%O%s) \
%:if-exists-else(crtbeginT%O%s crtbegin%O%s)
replace-outfile

Функция спецификатора replace-outfile принимает два аргумента. Она ищет первый аргумент в массиве outfiles и заменяет его вторым аргументом. Вот небольшой пример её использования:

%{fgnu-runtime:%:replace-outfile(-lobjc -lobjc-gnu)}
remove-outfile

Функция спецификатора remove-outfile принимает один аргумент. Она ищет первый аргумент в массиве outfiles и удаляет его. Вот небольшой пример её использования:

%:remove-outfile(-lm)
pass-through-libs

Функция спецификатора pass-through-libs принимает любое количество аргументов. Она находит все опции -l и все неоптиональные аргументы, заканчивающиеся на .a (которые она предполагает именами архивных файлов входных библиотек линкера) и возвращает результат, содержащий все найденные аргументы, каждый из которых предваряется -plugin-opt=-pass-through= и объединены пробелами. Этот список предназначен для передачи плагину LTO линкера.

%:pass-through-libs(%G %L %G)
print-asm-header

Функция print-asm-header не принимает аргументов и просто печатает баннер, например:

Assembler options
=================

Use "-Wa,OPTION" to pass "OPTION" to the assembler.

Она используется для разделения опций компилятора от опций ассемблера в выводе --target-help.

%{S}

Заменяет переключатель -S, если этот переключатель задан GCC. Если этот переключатель не указан, это ничего не заменяет. Обратите внимание, что ведущий дефис опускается при указании этой опции, и он автоматически вставляется, если выполняется замена. Таким образом, строка спецификатора ‘%{foo}’ соответствует опции командной строки -foo и выводит опцию командной строки -foo.

%W{S}

Как %{S}, но отмечает последний переданный аргумент как файл, который будет удалён при ошибке.

%{S*}

Заменяет все указанные в GCC переключатели, имена которых начинаются с -S, но которые также принимают аргумент. Это используется для переключателей, таких как -o, -D, -I и т. д. GCC рассматривает -o foo как один переключатель, имя которого начинается с ‘o’. %{o*} заменяет этот текст, включая пробел. Таким образом, генерируются два аргумента.

%{S*&T*}

Как %{S*}, но сохраняет порядок опций S и T (порядок S и T в спецификаторе не важен). Может быть любое количество переменных, разделённых амперсандом; для каждой дикий символ необязателен. Полезно для CPP как ‘%{D*&U*&A*}’.

%{S:X}

Заменяет X, если опция -S задана GCC.

%{!S:X}

Заменяет X, если опция -S не задана GCC.

%{S*:X}

Заменяет X, если одна или несколько опций, имена которых начинаются с -S, заданы GCC. Обычно X заменяется только один раз, независимо от того, сколько таких опций появилось. Однако, если %* появляется где-то в X, то X заменяется один раз для каждой соответствующей опции, с заменой %* на часть этой опции, соответствующей *.

Если %* появляется в качестве последней части последовательности спецификатора, то после окончания последней замены добавляется пробел. Однако, если в последовательности есть ещё текст, то пробел не генерируется. Это позволяет использовать замену %* в качестве части большей строки. Например, строка спецификатора:

%{mcu=*:--script=%*/memory.ld}

при сопоставлении с такой опцией, как -mcu=newchip, производит:

--script=newchip/memory.ld
%{.S:X}

Заменяет X, если обрабатывается файл с расширением S.

%{!.S:X}

Заменяет X, если не обрабатывается файл с расширением S.

%{,S:X}

Заменяет X, если обрабатывается файл для языка S.

%{!,S:X}

Заменяет X, если не обрабатывается файл для языка S.

%{S|P:X}

Заменяет X, если опция -S или -P задана GCC. Это можно комбинировать с последовательностями ‘!’, ‘.’, ‘,’, и *, хотя у них более сильная привязка, чем ‘|’. Если %* появляется в X, все альтернативы должны быть помечены звёздочкой, и только первая совпадающая альтернатива будет заменена.

Например, строка спецификатора:

%{.c:-foo} %{!.c:-bar} %{.c|d:-baz} %{!.c|d:-boggle}

выводит следующие опции командной строки из следующих опций командной строки:

fred.c        -foo -baz
jim.d         -bar -boggle
-d fred.c     -foo -baz -boggle
-d jim.d      -bar -baz -boggle
%{S:X; T:Y; :D}

Если S задана GCC, заменяет X; в противном случае, если T задана GCC, заменяет Y; в противном случае, заменяет D. Может быть любое количество предложений. Это можно комбинировать с ., ,, !, |, и * по мере необходимости.

Условный текст X в конструкции %{S:X} или подобной может содержать другие вложенные конструкции ‘%’, пробелы или даже новые строки. Они обрабатываются как обычно, как описано выше. Приводящие пробелы в X игнорируются. Пробелы также могут появляться где угодно слева от двоеточия в этих конструкциях, кроме места между . или * и соответствующим словом.

Переключатели -O, -f, -m и -W обрабатываются специально в этих конструкциях. Если другое значение -O или отрицаемая форма переключателя -f, -m или -W найдена позже в командной строке, более раннее значение переключателя игнорируется, за исключением {S*} где S — просто одна буква, которая пропускает все соответствующие опции.

Символ ‘|’ в начале текста предиката используется для указания того, что команда должна быть передана в следующую команду, но только если указана -pipe.

Встроен в GCC, какие переключатели принимают аргументы, а какие нет. (Вы можете подумать, что это полезно для обобщения, чтобы каждый спецификатор компилятора говорил, какие переключатели принимают аргументы. Но этого нельзя сделать последовательным образом. GCC даже не может определить, какие файлы ввода были указаны, не зная, какие переключатели принимают аргументы, и он должен знать, какие файлы ввода нужно скомпилировать, чтобы определить, какие компиляторы нужно запускать).

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

Далее: Опции целевой системы, Предыдущее: Опции каталога, Вверх: Вызов GCC [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Spec-Files.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API