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-
Вывести накопленные опции компоновщика, определённые строкой спецификаций ‘%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, если для GCC задан переключатель -S. %{!S:X}-
Заменяет
X, если для GCC не задан переключатель -S. %{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, если для GCC заданы либо-S, либо-P. Это может быть сочетание с ‘!’, ‘.’, ‘,’ и*последовательностями, хотя они имеют более сильную привязку, чем ‘|’. Если%*появляется в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}-
Если для GCC задан
S, заменяетX; в противном случае, если для GCC заданT, заменяет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 определяют, какие переключатели принимают аргументы, а какие нет. (Вы можете подумать, что было бы полезно обобщить это, чтобы каждая спецификация компилятора указывала, какие переключатели принимают аргументы. Но это невозможно сделать последовательно. GCC не может даже определить, какие входные файлы были указаны, не зная, какие переключатели принимают аргументы, и он должен знать, какие входные файлы следует компилировать, чтобы сказать, какие компиляторы запускать).
GCC также неявно знает, что аргументы, начинающиеся с -l, должны обрабатываться как файлы вывода компилятора и передаваться компоновщику в их правильном положении среди других файлов вывода.
Далее: Переменные среды, Предыдущее: Опции подмодели, Вверх: Использование GCC [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/Spec-Files.html