Spec-Zone.ru › GCC 15

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

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

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

%command

Передаёт процессору файла спецификаций команду command. Здесь могут встречаться следующие команды:

%include <file>

Найти file и вставить его текст в текущую позицию файла спецификаций.

%include_noerr <file>

Работает так же, как «%include», но не выводит сообщение об ошибке, если включаемый файл не найден.

%rename old_name new_name

Переименовать строку спецификации old_name в new_name.

*[spec_name]:

Указывает компилятору создать, переопределить или удалить указанную строку спецификации. Все строки после этой директивы до следующей директивы или пустой строки считаются текстом строки спецификации. Если в результате получается пустая строка, спецификация удаляется. (Если спецификации не существовало, ничего не происходит.) В противном случае, если спецификация ещё не существует, создаётся новая. Если спецификация уже существует, её содержимое заменяется текстом этой директивы, за исключением случая, когда первый символ этого текста — «+»: тогда текст добавляется к спецификации.

[suffix]:

Создаёт новую пару «[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
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, or %U», поскольку они должны образовывать полные имена файлов. При такой обработке «%O» рассматривается так, как если бы оно уже было подставлено, за исключением того, что «%g, %u, and %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 and %E».

%D

Вывести параметр -L для каждого каталога, в котором, по мнению GCC, могут находиться стартовые файлы. Если целевая платформа поддерживает multilib, текущий каталог 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, а команды «%» после неё — нет.

%<S*

Похоже на «%<S», но соответствует всем параметрам, начинающимся с -S.

%>S

Похоже на «%<S», но оставляет -S в командной строке GCC.

%: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)
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, но её преимущество в том, что её можно вложить в спецификацию и тем самым сделать условной. Она принимает один аргумент — имя файла — и ищет его в пути стартовых файлов. Она всегда возвращает 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, если 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
%{%:function(args):X}

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

%{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, следует считать выходными файлами компилятора и передавать компоновщику в надлежащем порядке среди остальных выходных файлов.

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

Spec-Zone.ru

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