Spec-Zone.ru › GCC 7

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]:

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

.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’ переопределяется новым. Новое определение добавляет дополнительные параметры командной строки перед включением текста старого определения.

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

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

END_OF_DOCUMENT_MARKER
%%

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

%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-7.5.0/gcc/Spec-Files.html

Spec-Zone.ru

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