Spec-Zone.ru › GCC 11

Далее: Переменные окружения, влияющие на GCC, Предыдущее: Зависимые от машины параметры, Вверх: Параметры командной строки GCC [Оглавление][Индекс]

3.20 Указание подпроцессов и параметров, передаваемых им ¶

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

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

%command

Отправляет команду процессору файлов спецификаций. Команды, которые могут здесь появиться:

%include <file>

Искать файл и вставить его текст в текущую точку файла спецификаций.

%include_noerr <file>

Точно так же, как ‘%include’, но не генерировать сообщение об ошибке, если файл включения не найден.

%rename 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

Замените базовым именем вывода, связанным с обрабатываемым входным файлом. Часто это подстрока до (и не включая) последней точки и не включая каталог, но, если %w активен, он расширяется до базового имени вспомогательных выводов, которые могут быть повлияны явным именем вывода и различными другими параметрами, которые управляют тем, как называются вспомогательные выводы.

%B

Это то же самое, что и ‘%b’, но включает суффикс файла (текст после последней точки). Без %w он расширяется до базового имени вывода дампов.

%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}’: см., например, gcc/fortran/lang-specs.h.

%.SUFFIX

Заменяет .SUFFIX суффиксами аргументов совпавшего ключа, когда он впоследствии выводится с помощью ‘%*’. SUFFIX завершается следующим пробелом или символом %.

%w

Помечает аргумент, содержащий или следующий за ‘%w’, как назначенный выходной файл этой компиляции. Это помещает аргумент в последовательность аргументов, которые заменяет ‘%o’.

%V

Указывает, что эта компиляция не создаёт выходной файл.

%o

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

%O

Заменяет суффикс для файлов объектов. Обратите внимание, что это обрабатывается особым образом, когда оно непосредственно следует за ‘%g, %u или %U’ из-за необходимости этих файлов формировать полные имена файлов. Обработка такова, что ‘%O’ обрабатывается точно так же, как если бы оно уже было заменено, за исключением того, что ‘%g, %u и %U’ в настоящее время не поддерживают дополнительные символы suffix после ‘%O’, как они поддерживают, например, после ‘.o’.

%I

Замените любые из -iprefix (сгенерировано из GCC_EXEC_PREFIX), -isysroot (сгенерировано из TARGET_SYSTEM_ROOT), -isystem (сгенерировано из COMPILER_PATH) и опций -B и -imultilib по необходимости.

%s

Текущий аргумент — имя библиотеки или файла запуска. Ищем этот файл в стандартном списке каталогов и подставляем полное найденное имя. Текущий рабочий каталог включён в список просматриваемых каталогов.

%T

Текущий аргумент — имя скрипта компоновщика. Ищем этот файл в текущем списке каталогов для поиска библиотек. Если файл найден, в командную строку добавляется опция --script с полным найденным путём. Если файл не найден, выводится сообщение об ошибке. Примечание: текущий рабочий каталог не просматривается.

%estr

Вывести str как сообщение об ошибке. str завершается символом новой строки. Используйте это при обнаружении несовместимых опций.

%nstr

Вывести str как сообщение. str завершается символом новой строки.

%(name)

Подставить содержимое строки спецификации name на этом этапе.

%x{option}

Накопить опцию для ‘%X’.

%X

Вывести накопленные опции компоновщика, определённые строкой спецификации ‘%x’.

%Y

Вывести накопленные опции ассемблера, определённые -Wa.

%Z

Вывести накопленные опции препроцессора, определённые -Wp.

%M

Вывести multilib_os_dir.

%R

Вывести конкатенацию target_system_root и target_sysroot_suffix.

%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, команды ‘%’ в строке спецификации после этой команды — нет.

%<S*

Аналогично ‘%<S’, но сопоставить все ключи, начинающиеся с -S.

%>S

Аналогично ‘%<S’, но сохранить -S в командной строке GCC.

%: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)
if-exists-then-else

Функция спецификации if-exists-then-else принимает как минимум два аргумента и необязательный третий. Первый аргумент — абсолютный путь к файлу. Если файл существует, функция возвращает второй аргумент. Если файла не существует, функция возвращает третий аргумент, если он есть, или NULL в противном случае. Это можно использовать для расширения одного текста или, по желанию, другого, на основе существования файла. Вот небольшой пример её использования:

-l%:if-exists-then-else(%:getenv(VSB_DIR rtnet.h) rtnet net)
sanitize

Функция спецификации sanitize не принимает аргументов. Она возвращает не-NULL, если активны какие-либо санитайзеры адресов, потоков или неопределённого поведения.

%{%:sanitize(address):-funwind-tables}
replace-outfile

Функция спецификации replace-outfile принимает два аргумента. Она ищет первый аргумент в массиве outfiles и заменяет его вторым аргументом. Вот небольшой пример её использования:

%{fgnu-runtime:%:replace-outfile(-lobjc -lobjc-gnu)}
remove-outfile

Функция спецификации remove-outfile принимает один аргумент. Она ищет первый аргумент в массиве outfiles и удаляет его. Вот небольшой пример её использования:

%:remove-outfile(-lm)
version-compare

Функция спецификации version-compare принимает четыре или пять аргументов следующего вида:

<comparison-op> <arg1> [<arg2>] <switch> <result>

Она возвращает result , если сравнение истинно, и NULL, если ложно. Поддерживаемые значения comparison-op:

>=

Истина, если switch — более поздняя (или такая же) версия, чем arg1

!>

Обратное значение >=

<

Истина, если switch — более ранняя версия, чем arg1

!<

Обратное значение <

><

Истина, если switch — arg1 или более поздняя, и более ранняя, чем arg2

<>

Истина, если switch — более ранняя, чем arg1, или arg2 или более поздняя

Если switch отсутствует, условие ложно, если только первый символ comparison-op не !.

%:version-compare(>= 10.3 mmacosx-version-min= -lmx)

В приведённом выше примере будет добавлено -lmx, если было передано -mmacosx-version-min=10.3.9.

include

Функция спецификации include очень похожа на %include, с преимуществом, что она может быть вложена в спецификацию и, следовательно, условна. Она принимает один аргумент — имя файла и ищет его в пути startfile. Она всегда возвращает NULL.

%{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}
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.

gt

Функция спецификации gt принимает два или более аргументов. Она возвращает "" (пустую строку), если предпоследний аргумент больше последнего, и NULL в противном случае. Следующий пример вставляет спецификацию link_gomp, если последняя опция -ftree-parallelize-loops=, заданная в командной строке, больше 1:

%{%:gt(%{ftree-parallelize-loops=*:%*} 1):%:include(libgomp.spec)%(link_gomp)}
debug-level-gt

Функция спецификации debug-level-gt принимает один аргумент и возвращает "" (пустую строку), если debug_info_level больше заданного числа, и NULL в противном случае.

%{%:debug-level-gt(0):%{gdwarf*:--gdwarf2}}
%{S}

Заменяет переключатель -S, если этот переключатель задан для GCC. Если этот переключатель не задан, ничего не заменяется. Обратите внимание, что ведущий дефис опускается при задании этой опции, и он автоматически вставляется, если замена выполняется. Таким образом, строка спецификации ‘%{foo}’ соответствует опции командной строки -foo и выводит опцию командной строки -foo.

%W{S}

Как %{S}, но помечает последний переданный аргумент как файл, который нужно удалить при ошибке.

%@{S}

Как %{S}, но помещает результат в FILE и заменяет @FILE, если был передан аргумент @file.

%{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
%{%:function(args):X}

Вызовите функцию с именем function с аргументами args. Если функция возвращает не-NULL, то X заменяется, если возвращает NULL — не заменяется.

%{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 встроен механизм, определяющий, какие переключатели принимают аргументы, а какие нет. (Можно подумать, что было бы полезно обобщить это, разрешив каждому спецификации компилятора указывать, какие переключатели принимают аргументы. Но это невозможно сделать согласованным образом. GCC даже не может определить, какие входные файлы были указаны, не зная, какие переключатели принимают аргументы, и он должен знать, какие входные файлы компилировать, чтобы определить, какие компиляторы запускать).

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

Далее: Переменные среды, влияющие на GCC, Предыдущее: Зависимые от машины параметры, Вверх: Параметры командной строки GCC [Содержание][Индекс]

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

Spec-Zone.ru

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