Spec-Zone.ru › GCC 6

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 считает возможным содержать файлы инициализации. Если целевая платформа поддерживает многоязычные версии, текущая директория multilib добавляется к каждому из этих путей.

%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 принимает два аргумента: имя переменной среды и строку. Если переменная среды не определена, выдается ошибка fatal. В противном случае возвращаемое значение — это значение переменной среды, конкатенированное со строкой. Например, если 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, если для GCC задана опция -S.

%{!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. Вы можете иметь столько таких условий, сколько вам нужно. Это можно комбинировать с ., ,, !, |, и * по мере необходимости.

Условный текст 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-6.5.0/gcc/Spec-Files.html

Spec-Zone.ru

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