Spec-Zone.ru › GCC 8

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

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, если для GCC указан один или несколько переключателей, имена которых начинаются с -S. Обычно 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. Может быть любое количество пунктов. Это можно комбинировать с ., ,, !, |, и * по мере необходимости.

Текст сопоставления S в конструкциях ‘%{S}’, ‘%{S:X}’ или подобных может использовать обратную косую черту для игнорирования специального значения следующего за ней символа, позволяя таким образом выполнять литеральное сопоставление символа, который в противном случае обрабатывается особым образом. Например, ‘%{std=iso9899\:1999:X}’ заменяет X если задана опция -std=iso9899:1999.

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

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

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

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

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

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

Spec-Zone.ru

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