Spec-Zone.ru › GCC 4

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

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

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

%команда
Выполняет команду для процессора файлов спецификаций. Команды, которые могут здесь появиться:
%include <файл>
Ищет файл и вставляет его текст в текущую точку файла спецификаций.
%include_noerr <файл>
Точно так же, как ‘%include’, но не генерирует сообщение об ошибке, если файл включения не найден.
%rename старое_имя новое_имя
Переименовывает строку спецификации старое_имя в новое_имя.
*[имя_спецификации]:
Это сообщает компилятору создать, переопределить или удалить строку спецификации с указанным именем. Все строки после этой директивы до следующей директивы или пустой строки считаются текстом для строки спецификации. Если это приводит к пустой строке, то спецификация удаляется. (Или, если спецификация не существовала, ничего не происходит.) В противном случае, если спецификация в настоящее время не существует, создается новая спецификация. Если спецификация существует, ее содержимое переопределяется текстом этой директивы, если только первый символ этого текста не является символом ‘+’, в этом случае текст добавляется к спецификации.
[суффикс]:
Создает новую пару «[суффикс] спецификация». Все строки после этой директивы до следующей директивы или пустой строки составляют строку спецификации для указанного суффикса. При обнаружении компилятором входного файла с указанным суффиксом, он обрабатывает строку спецификации, чтобы выяснить, как скомпилировать этот файл. Например:
.ZZ:
z-compile -input %i

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

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

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

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

#имя
Это вызывает сообщение об ошибке, гласящее:
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, or %U’, из-за необходимости формировать полные имена файлов. Обработка такая, что ‘%O’ обрабатывается точно так же, как если бы оно уже было заменено, за исключением того, что ‘%g, %u, and %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 and %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. Может быть любое количество пунктов. Это можно комбинировать с ., ,, !, |, и * по мере необходимости.

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

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

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

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

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

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

Spec-Zone.ru

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