Важны ли повторяемость и порядок флагов gcc? - PullRequest
0 голосов
/ 18 октября 2018

Я вижу некоторые из gcc флагов, повторяющихся при сборке расширения C для python.Когда я запускаю:

python setup.py build_ext

Команда запущенной сборки выглядит следующим образом:

gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong -fno-plt -fPIC -I/usr/include/python3.7m -c /tmp/src/source.c -o build/temp.linux-x86_64-3.7/tmp/src/source.o
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=4 -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.7/tmp/src/source.o -L/usr/lib -lpython3.7m -o build/lib.linux-x86_64-3.7/source.cpython-37m-x86_64-linux-gnu.so

Хорошо, это длинная команда.Но, как видите, некоторые флаги повторяются.Вот повторение первой команды:

  • -O3 повторяется 4 раза.
  • -fno-plt повторяется 3 раза.
  • -fstack-protector-strong повторяется 3 раза.
  • -march=x86-64 повторяется 3 раза.
  • -mtune=generic повторяется 3 раза.
  • -pipe повторяется 3 раза.

Рядом-Wl,... флаги, которые передаются компоновщику, имеют ли эти флаги повторение и порядок какие-либо значения?

1 Ответ

0 голосов
/ 19 октября 2018

Нередко встречаются повторения опций в командных строках GCC, которые были сгенерированы каким-либо стеком инструментов (часто IDE), с человеческим вводом «вверху».

Ни одно из повторений у вас нетspotted имеет значение для значения командной строки.Обычно такие повторения равносильны безобидной избыточности, и они могут иметь рациональный мотив.Инструмент, который добавляет что-то постепенно в командную строку GCC, может захотеть убедиться, что определенный параметр включен в тот момент, даже если он мог быть каким-то образом отключен параметром, добавленным с момента последнего вхождения, который его включил.Повторение опции с избыточностью может быть дешевле, чем проверка, является ли она избыточной.

Но повторение не обязательно безобидно ...

Если в какой-то момент в командной строке появляется опция OPT:

 ... OPT ...

тогда замена одного вхождения на 2 или более не будет иметь значения.

Однако, если командная строка имеет вид:

 ... OPT1 ... OPT2 ...

Затем добавьте еще одно вхождение OPT1 в любом месте послеOPT2 вполне может изменить ситуацию.Аналогично добавление еще одного вхождения OPT2 в любом месте до OPT1.

Это связано с тем, что порядок , в котором параметры встречаются очень часто, имеет значение.

Параметробычно состоит из flag и value , например

 -O3             -> Flag = -O, value = 3
 -I./inc         -> Flag = -I, value = ../inc

Некоторые флаги, такие как -O, могут принимать любое из набора взаимоисключающих значений.Назовите эти флаги мьютекса , для краткости.Когда флаг мьютекса встречается многократно с компенсирующими значениями, last в командной строке имеет преимущественную силу:

 -O1 -O2 -O3 = -O3
 -O3 -O2 -O1 = -O1

Другие флаги, такие как -I, могут последовательно принимать произвольные неисключительные значения, которые являютсянакапливаются в порядке их появления, чтобы сформировать последовательность, которая является одним из параметров компиляции или связи.Например,

 -I./foo -I./bar

добавляет ./foo, а затем ./bar к указанному пользователем порядку поиска в каталоге для компиляции.Назовите эти кумулятивные флаги .

Другие флаги являются логическими и имеют форму включения и форму отключения, например, -fstack-protector, -fno-stack-protector.Их можно приравнять к опциям мьютекса с исключительными возможными значениями True и False.

И еще один тип флага, например -l, последовательно принимает произвольные неисключительные значения, которые не накоплены, но каждый из них просто становится значением флага в этой точке в командной строке.Насколько я могу вспомнить, -l - единственный флаг такого типа, который является аномальным: -lfoo на самом деле не опция , а позиционный аргумент к которому флаг прикрепляет метод интерпретации.В нем говорится, что файл libfoo.{so|a} должен быть введен в связку в этой точке , чей абсолютный путь компоновщик должен найти алгоритмически (со ссылкой на опции -L).Давайте назовем такие флаги позиционные флаги .

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

 -fno-stack-protector -O1 -O3 -fstack-protector

уже выглядит так, как будто слишком много поваров испортили бульон, и эквивалентно:

 -O3 -fstack-protector

Но если мы добавим некоторое повторение:

 -fno-stack-protector -O1 -O3 -fstack-protector -fno-stack-protector -O1

становится эквивалентным:

 -O1 -fno-stack-protector

Для кумулятивных флагов легче предусмотреть смешивание со значением командной строки, повторяя параметр до в некоторых случаях, чем после:

 -I./foo -I./bar

означает то, что говорит.Принимая во внимание, что

 -I./bar -I./foo -I./bar

означает то же самое, что и:

 -I./bar -I./foo

Но такого рода путаница практически не происходит на практике, потому что повторения опций почти всегда генерируются добавлением повторение командной строки во время инкрементного построения.

Позиционные флаги по определению чувствительны к order , как между собой, так и по отношению к другим опциям и позиционным аргументам.Каждая перестановка

 ... -lfoo -lbar main.o ...

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

... -lfoo main.o ... 

вполне может привести к сбою связи, который

    ... -lfoo main.o -lfoo

исправит.

Так что решительно, да, повторение и упорядочение флагов может бытьважно.

...