3.15 Параметры для компоновки ¶
Эти параметры используются при компоновке компилятором объектных файлов в исполняемый выходной файл. Они не имеют смысла, если компилятор не выполняет этап компоновки.
-
object-file-name¶ -
Имя файла, не заканчивающееся на специальный распознаваемый суффикс, считается именем файла объекта или библиотеки. (Файлы объектов отличаются от библиотек линковщиком в соответствии с содержимым файла.) При выполнении линковки эти файлы объектов используются как входные данные для линковщика.
-c-S-E-
Если используется любой из этих параметров, линковщик не запускается, и имена файлов объектов не следует использовать в качестве аргументов. См. Параметры, управляющие видом выходных данных.
-flinker-output=type-
Этот параметр управляет генерацией кода оптимизатором на этапе линковки. По умолчанию выходные данные линковщика автоматически определяются плагином линковщика. Для отладки компилятора и если требуется инкрементная линковка с файлом объекта без LTO, может быть полезно вручную управлять типом.
Если type равен ‘exec’, генерация кода создаёт статический бинарный файл. В этом случае -fpic и -fpie оба отключены.
Если type равен ‘dyn’, генерация кода создаёт общую библиотеку. В этом случае -fpic или -fPIC сохраняются, но не включаются автоматически. Это позволяет создавать общие библиотеки без позиционно-независимого кода на архитектурах, где это возможно, например, на x86.
Если type равен ‘pie’, генерация кода создаёт исполняемый файл с -fpie. Это приводит к аналогичным оптимизациям, как в случае ‘exec’, за исключением того, что -fpie не отключается, если он указан во время компиляции.
Если type равен ‘rel’, компилятор предполагает, что выполняется инкрементная линковка. Разделы, содержащие промежуточный код для оптимизации на этапе линковки, объединяются, предварительно оптимизируются и выводятся в результирующий файл объекта. Кроме того, если указан -ffat-lto-objects, генерируется бинарный код для будущей линковки без LTO. Файл объекта, полученный при инкрементной линковке, меньше, чем статическая библиотека, созданная из тех же файлов объектов. Во время линковки результат инкрементной линковки также загружается быстрее, чем статическая библиотека, предполагая, что большая часть объектов в библиотеке используется.
Наконец, ‘nolto-rel’ настраивает компилятор для инкрементной линковки, где генерация кода принудительна, создаётся конечный бинарный файл, а промежуточный код для последующей оптимизации на этапе линковки удаляется. При объединении нескольких файлов объектов результирующий код оптимизируется лучше, чем при отключённой оптимизации на этапе линковки (например, происходит встраивание кода между модулями), но большинство преимуществ оптимизаций для всего приложения теряются.
Во время инкрементной линковки (с помощью -r) плагин линковщика по умолчанию использует rel. Однако с текущими интерфейсами GNU Binutils нельзя инкрементно связать LTO-объекты и объекты без LTO в один смешанный файл объекта. Если какой-либо из файлов объектов в инкрементной линковке не может быть использован для оптимизации на этапе линковки, плагин линковщика выводит предупреждение и использует ‘nolto-rel’. Для сохранения оптимизации всего приложения рекомендуется связывать такие объекты в статическую библиотеку вместо этого. В качестве альтернативы можно использовать binutils от H.J. Lu с поддержкой смешанных объектов.
-fuse-ld=bfd-
Использовать линковщик
bfd, а не стандартный линковщик. -fuse-ld=gold-
Использовать линковщик
gold, а не стандартный линковщик. -fuse-ld=lld-
Использовать линковщик LLVM
lld, а не стандартный линковщик. -
-llibrary¶ -l library-
Произвести поиск библиотеки с именем library при линковке. (Вторая альтернатива с библиотекой как отдельным аргументом предназначена только для соответствия POSIX и не рекомендуется.)
Параметр -l передаётся непосредственно линковщику GCC. Обратитесь к документации вашего линковщика для получения точных деталей. Общее описание ниже относится к GNU линковщику.
Линковщик ищет библиотеку в стандартном списке каталогов. Включаются несколько стандартных системных каталогов плюс любые, которые вы укажете с помощью -L.
Статические библиотеки являются архивами файлов объектов и имеют имена, подобные liblibrary.a. Некоторые целевые платформы также поддерживают общие библиотеки, которые обычно имеют имена, подобные liblibrary.so. Если найдены как статическая, так и общая библиотеки, линковщик отдает предпочтение линковке с общей библиотекой, если не используется параметр -static.
Важен порядок указания параметров в командной строке; линковщик обрабатывает библиотеки и файлы объектов в порядке их указания. Таким образом, ‘foo.o -lz bar.o’ ищет библиотеку ‘z’ после файла foo.o, но перед bar.o. Если bar.o ссылается на функции в ‘z’, эти функции могут не загрузиться.
-lobjc-
Этот специальный случай параметра -l необходим для линковки программы на Objective-C или Objective-C++.
-nostartfiles-
Не использовать стандартные файлы загрузки системы при линковке. Стандартные системные библиотеки используются обычно, если не используется -nostdlib, -nolibc или -nodefaultlibs.
-nodefaultlibs-
Не использовать стандартные системные библиотеки при линковке. Только указанные вами библиотеки передаются линковщику, и параметры, задающие линковку системных библиотек, такие как -static-libgcc или -shared-libgcc, игнорируются. Стандартные файлы загрузки используются обычно, если не используется -nostartfiles.
Компилятор может генерировать вызовы
memcmp,memset,memcpyиmemmove. Эти записи обычно разрешаются записями в libc. Эти точки входа должны быть предоставлены каким-либо другим способом, когда этот параметр указан. -nolibc-
Не использовать стандартную библиотеку C или тесно связанные с ней системные библиотеки при линковке. Тем не менее, линковаться со стартовыми файлами, libgcc или предоставленными инструментом среды разработки библиотеками языковой поддержки, такими как libgnat, libgfortran или libstdc++, если не указаны параметры, препятствующие их включению. Обычно это удаляет -lc из командной строки линковщика, а также системные библиотеки, которые обычно используются вместе с ней и теряют смысл при отсутствии библиотеки C, например, -lpthread или -lm в некоторых конфигурациях. Это предназначено для целевых платформ без операционной системы, когда действительно отсутствует библиотека C.
-nostdlib-
Не использовать стандартные системные файлы загрузки или библиотеки при линковке. Не используются файлы загрузки и только указанные вами библиотеки передаются линковщику, а параметры, задающие линковку системных библиотек, такие как -static-libgcc или -shared-libgcc, игнорируются.
Компилятор может генерировать вызовы
memcmp,memset,memcpyиmemmove. Эти записи обычно разрешаются записями в libc. Эти точки входа должны быть предоставлены каким-либо другим способом, когда этот параметр указан.Одна из стандартных библиотек, обойденных -nostdlib и -nodefaultlibs, — libgcc.a, библиотека внутренних подпрограмм, которую GCC использует для преодоления недостатков конкретных машин или особых потребностей некоторых языков. (См. Интерфейс с GCC Output в документации «Внутреннее устройство GNU Compiler Collection (GCC)» для получения более подробной информации о libgcc.a.) В большинстве случаев вам нужна libgcc.a, даже если вы хотите избежать использования других стандартных библиотек. Другими словами, когда вы используете -nostdlib или -nodefaultlibs, вам обычно следует указать также -lgcc. Это гарантирует отсутствие неразрешенных ссылок на внутренние подпрограммы библиотеки GCC. (Пример такой внутренней подпрограммы —
__main, используемой для обеспечения вызова конструкторов C++; см.collect2в «Внутреннее устройство GNU Compiler Collection (GCC)».) -e entry--entry=entry-
Указать, что точкой входа программы является entry. Аргумент интерпретируется линковщиком; GNU линковщик принимает либо имя символа, либо адрес.
-pie-
Создать исполняемый файл с динамической линковкой и позиционной независимостью на платформах, которые её поддерживают. Для предсказуемых результатов необходимо также указать тот же набор параметров, используемых для компиляции (-fpie, -fPIE или параметры модели), при указании этого параметра линковщика.
-no-pie-
Не создавать исполняемый файл с динамической линковкой и позиционной независимостью.
-static-pie-
Создать статический исполняемый файл с позиционной независимостью на платформах, которые её поддерживают. Статический исполняемый файл с позиционной независимостью похож на статический исполняемый файл, но может загружаться по любому адресу без динамического линковщика. Для предсказуемых результатов необходимо также указать тот же набор параметров, используемых для компиляции (-fpie, -fPIE или параметры модели), при указании этого параметра линковщика.
-pthread-
Связать с библиотекой POSIX потоков. Этот параметр поддерживается на платформах GNU/Linux, большинстве других Unix-подобных системах, а также на x86 Cygwin и MinGW. На некоторых платформах этот параметр также задает флаги для препроцессора, поэтому его следует использовать последовательно для компиляции и линковки.
-r-
Создать перемещаемый объект в качестве выходных данных. Это также известно как частичная линковка.
-rdynamic-
Передать флаг -export-dynamic линковщику ELF на платформах, которые его поддерживают. Это указывает линковщику добавить все символы, а не только используемые, в динамическую таблицу символов. Этот параметр необходим для некоторых применений
dlopenили для возможности получения трассировок изнутри программы. -s-
Удалить всю информацию о таблице символов и перемещениях из исполняемого файла.
-static
-
В системах, поддерживающих динамическую компоновку, это переопределяет -pie и предотвращает компоновку с разделяемыми библиотеками. В других системах этот параметр не имеет эффекта.
-shared-
Создаёт разделяемый объект, который затем можно связать с другими объектами для формирования исполняемого файла. Не все системы поддерживают этот параметр. Для предсказуемых результатов необходимо также указать тот же набор параметров, используемых для компиляции (-fpic, -fPIC или подпараметры модели), когда вы указываете этот параметр компоновщика.1
-shared-libgcc-static-libgcc-
В системах, предоставляющих libgcc как разделяемую библиотеку, эти параметры принуждают использовать либо разделяемую, либо статическую версию соответственно. Если при конфигурации компилятора не была построена разделяемая версия libgcc, эти параметры не имеют эффекта.
Существует несколько ситуаций, в которых приложение должно использовать разделяемую libgcc вместо статической версии. Наиболее распространённым из них является случай, когда приложение хочет выбрасывать и перехватывать исключения через разные разделяемые библиотеки. В этом случае каждая из библиотек, а также само приложение должны использовать разделяемую libgcc.
Поэтому драйвер G++ автоматически добавляет -shared-libgcc всякий раз, когда вы создаёте разделяемую библиотеку или главный исполняемый файл, так как программы на C++ обычно используют исключения, поэтому это правильное решение.
Если же вы используете драйвер GCC для создания разделяемых библиотек, вы можете обнаружить, что они не всегда связаны с разделяемой libgcc. Если GCC обнаружит во время своей конфигурации, что у вас компоновщик не-GNU или компоновщик GNU, который не поддерживает параметр --eh-frame-hdr, он по умолчанию связывает разделяемую версию libgcc в разделяемые библиотеки. В противном случае он использует компоновщик и оптимизирует связывание с разделяемой версией libgcc, связывая по умолчанию с статической версией libgcc. Это позволяет исключениям распространяться через такие разделяемые библиотеки без затрат на перебазирование во время загрузки библиотеки.
Однако, если библиотека или главный исполняемый файл должны выбрасывать или перехватывать исключения, вы должны связать их с помощью драйвера G++, или с помощью параметра -shared-libgcc, чтобы они были связаны с разделяемой libgcc.
-static-libasan-
Когда используется параметр -fsanitize=address для компоновки программы, драйвер GCC автоматически связывается с libasan. Если libasan доступна как разделяемая библиотека, и параметр -static не используется, то это связывает с разделяемой версией libasan. Параметр -static-libasan указывает драйверу GCC на статическую компоновку libasan, не обязательно выполняя статическую компоновку других библиотек.
-static-libtsan-
Когда для компоновки программы используется параметр -fsanitize=thread, драйвер GCC автоматически связывается с libtsan. Если libtsan доступна как разделяемая библиотека, и параметр -static не используется, то это связывается с разделяемой версией libtsan. Параметр -static-libtsan указывает драйверу GCC на статическую компоновку libtsan, не обязательно выполняя статическую компоновку других библиотек.
-static-liblsan-
Когда для компоновки программы используется параметр -fsanitize=leak, драйвер GCC автоматически связывается с liblsan. Если liblsan доступна как разделяемая библиотека, и параметр -static не используется, то это связывается с разделяемой версией liblsan. Параметр -static-liblsan указывает драйверу GCC на статическую компоновку liblsan, не обязательно выполняя статическую компоновку других библиотек.
-static-libubsan-
Когда для компоновки программы используется параметр -fsanitize=undefined, драйвер GCC автоматически связывается с libubsan. Если libubsan доступна как разделяемая библиотека, и параметр -static не используется, то это связывается с разделяемой версией libubsan. Параметр -static-libubsan указывает драйверу GCC на статическую компоновку libubsan, не обязательно выполняя статическую компоновку других библиотек.
-static-libstdc++-
При компоновке программы на C++, драйвер обычно автоматически связывается с libstdc++. Если libstdc++ доступна как разделяемая библиотека, и параметр -static не используется, то это связывается с разделяемой версией libstdc++. Обычно это нормально. Однако иногда полезно зафиксировать используемую версию libstdc++ без полной статической компоновки. Параметр -static-libstdc++ указывает драйверу
g++на статическую компоновку libstdc++, не обязательно выполняя статическую компоновку других библиотек. -symbolic-
Связывает ссылки на глобальные символы при построении разделяемого объекта. Предупреждает о неразрешённых ссылках (если не переопределено параметром компоновщика -Xlinker -z -Xlinker defs). Несколько систем поддерживают этот параметр.
-T script-
Использует script в качестве скрипта компоновщика. Этот параметр поддерживается большинством систем, использующих компоновщик GNU. На некоторых целевых платформах, таких как целевые платформы без операционной системы, параметр -T может быть необходим при компоновке, чтобы избежать ссылок на неопределённые символы.
-Xlinker option-
Передаёт option в качестве параметра компоновщику. Вы можете использовать это для передачи системных параметров компоновщика, которые GCC не распознаёт.
Если вы хотите передать параметр, который принимает отдельный аргумент, вы должны использовать -Xlinker дважды, один раз для параметра и один раз для аргумента. Например, чтобы передать -assert definitions, необходимо написать -Xlinker -assert -Xlinker definitions. Не работает запись -Xlinker "-assert definitions", так как это передаёт всю строку как один аргумент, чего компоновщик не ожидает.
При использовании компоновщика GNU обычно удобнее передавать аргументы к параметрам компоновщика с помощью синтаксиса option=value, чем в виде отдельных аргументов. Например, вы можете указать -Xlinker -Map=output.map вместо -Xlinker -Map -Xlinker output.map. Другие компоновщики могут не поддерживать этот синтаксис для параметров командной строки.
-Wl,option-
Передаёт option в качестве параметра компоновщику. Если option содержит запятые, он разбивается на несколько параметров в местах запятых. Вы можете использовать этот синтаксис для передачи аргумента к параметру. Например, -Wl,-Map,output.map передаёт -Map output.map компоновщику. При использовании компоновщика GNU вы также можете получить тот же эффект с помощью -Wl,-Map=output.map.
-u symbol-
Предполагает, что символ symbol неопределён, чтобы принудительно связать модули библиотеки для его определения. Вы можете использовать -u несколько раз с различными символами, чтобы принудительно загрузить дополнительные модули библиотек.
-z keyword-
-z передаётся непосредственно компоновщику вместе с ключевым словом keyword. Смотрите раздел в документации вашего компоновщика для разрешённых значений и их значений.
Примечания
(1)
В некоторых системах ‘gcc -shared’ необходимо построить дополнительные фрагменты кода для конструкторов, чтобы они работали. В системах с несколькими версиями библиотек ‘gcc -shared’ должен выбрать правильные вспомогательные библиотеки для связывания. Неуказание правильных флагов может привести к скрытым ошибкам. Указание их в случаях, когда они не нужны, не опасно.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/gcc/Link-Options.html