Что делает опция GNU ld --undefined?

Может кто-нибудь объяснить, что делает опция GNU ld --undefined?

Работа над проектом LiteOS. Приложение связано со многими -u опциями. Например -utask_shellcmd.

руководство по компоновщику GNU for --undefined=symbol просто говорит:

Принудительно вводить символ в выходной файл как неопределенный символ. Это может, например, вызвать связывание дополнительных модулей из стандартных библиотек.

Таким образом, символ будет включен в выходной файл как неопределенный. Что делать, если символ уже определен в одном из связанных файлов obj? Если он действительно не определен, когда произойдет связывание дополнительных модулей и как это произойдет?


person minghua    schedule 03.03.2017    source источник
comment
Компилятор просматривает вашу единицу перевода и создает скомпилированный объектный файл. Часть того, что имеет этот файл, - это таблица символов, в которой указаны внешние символы, на которые ссылается объектный файл, которые не являются частью этого объекта. Это неопределенные символы.   -  person jxh    schedule 04.03.2017
comment
В обычной размещенной среде main() вызывается из-за того, что код запуска (crt0.o или аналогичный) вызывает функцию, но не определяет ее, поэтому компоновщик ищет определение в ваших объектных файлах. Параметр --undefined=symbol сообщает компоновщику, что symbol следует искать среди сканируемых объектных файлов и библиотек. Я не проверял, имеет ли значение его позиция в командной строке компоновщика. Если символ уже определен, это не имеет значения (и больше не будет привязано). Если в конце связывания он все еще не определен, связывание может завершиться неудачно.   -  person Jonathan Leffler    schedule 04.03.2017


Ответы (1)


Параметр -u актуален только тогда, когда задействованы архивные (.a) библиотеки (возможно, также .so библиотеки с действующим --as-needed).

В отличие от отдельных объектных файлов (.o) в связывающей командной строке, которые все связаны в том порядке, в котором они появляются, объектные файлы из архивной библиотеки связываются только тогда, когда они удовлетворяют одной или нескольким неопределенным ссылкам на символы в той точке, в которой они появляются в ссылка в командной строке. Как только .o файл из архива втягивается в ссылку, процесс повторяется рекурсивно, так что, если он вводит больше неопределенных ссылок на символы, другие объектные файлы из того же (или более поздних) архивов будут втянуты, чтобы удовлетворить их.

Использование -u позволяет вам включить в ссылку определенный символ (и, косвенно, все зависимости объектного файла, в котором он был определен). Конечно, вы можете просто поместить все .o файлы в командную строку напрямую, без использования каких-либо архивных библиотек, но с помощью библиотек вы можете избежать связывания неиспользуемых объектных файлов (это особенно полезно, если большие части кода могут не использоваться в зависимости от параметров, настраиваемых во время сборки в других файлах!) при получении нужных вам.

person R.. GitHub STOP HELPING ICE    schedule 03.03.2017
comment
По сути, это может привести к тому, что неиспользуемый символ будет связан с результирующим двоичным файлом. Верный? Тогда зачем это нужно? - person minghua; 05.03.2017
comment
@minghua: Действительно, для обычных размещенных приложений дерева зависимостей неопределенных символов с корнем main (через crt1.o) достаточно, чтобы получить все, что вам нужно. Но для автономного проекта, такого как ядро, вам может потребоваться определить свой собственный корень (и). Кроме того, в любом случае - но это чаще встречается при программировании на голом железе / ядре, где допустимо делать предположения о вашем компоновщике - объектные файлы, которые не являются частью основного дерева зависимостей символов, могут играть роль в окончательном выводе через специальные разделы, которые вставляются в таблицы скриптом компоновщика и т. д. - person R.. GitHub STOP HELPING ICE; 05.03.2017
comment
Одним из особых случаев, когда является переносимым, являются конструкторы для статических объектов (в C ++ или через атрибуты GNU C, чтобы сделать функцию ctor, которая запускается при запуске). Вытягивание объектного файла, который в противном случае не использовался, может изменить поведение программы, заставляя статические ctors в этом файле связываться и запускаться при запуске. - person R.. GitHub STOP HELPING ICE; 05.03.2017