g ++ связывание зависимости порядка при связывании кода c с кодом c ++ - PullRequest
30 голосов
/ 29 июля 2010

До сегодняшнего дня я всегда считал, что порядок передачи объектов и библиотек в g ++ на этапе компоновки не имеет значения.Затем сегодня я попытался связать код на С ++ с кодом на С.Я завернул все заголовки C во внешний блок "C", но компоновщику все еще не удалось найти символы, которые, как я знал, были в архивах объектов C.

Озадачен, я создал относительно простой пример, чтобы изолировать ошибку компоновкино, к моему большому удивлению, более простой пример связался без каких-либо проблем.

После небольшой проб и ошибок я обнаружил, что, эмулировав шаблон связывания, использованный в простом примере, я мог получить основной код для ссылки ОК,Сначала это был объектный код, затем объектный архив, например:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Может кто-нибудь пролить свет на то, почему это может быть так?Я никогда не видел этой проблемы при связывании обычного кода C ++.

Ответы [ 4 ]

40 голосов
/ 29 июля 2010

Порядок, в котором вы указываете объектные файлы и библиотеки, ОЧЕНЬ важен в GCC - если вы не были укушены этим до того, как вели очаровательную жизнь. Компоновщик ищет символы в том порядке, в котором они появляются, поэтому, если у вас есть исходный файл, содержащий вызов библиотечной функции, вам нужно поместить его перед библиотекой, иначе компоновщик не узнает, что он должен его разрешить. Сложное использование библиотек может означать, что вы должны указывать библиотеку более одного раза, что является огромной болью, чтобы получить право.

19 голосов
/ 29 июля 2010

Передача порядка библиотек в gcc / g ++ действительно имеет значение.Если A зависит от B, A должен быть указан первым.Причина в том, что он оптимизирует символы, на которые нет ссылок, поэтому, если он сначала видит библиотеку B, и никто не ссылался на нее в этот момент, он вообще не будет ссылаться на нее.

6 голосов
/ 29 июля 2010

Статическая библиотека - это коллекция объектных файлов, сгруппированных в архив. При связывании с ним компоновщик выбирает только те объекты, которые ему необходимы для разрешения любых неопределенных в данный момент символов. Поскольку объекты связаны в порядке, указанном в командной строке, объекты из библиотеки будут включены только в том случае, если библиотека идет после всех объектов, которые от нее зависят.

Так что порядок ссылок очень важен; если вы собираетесь использовать статические библиотеки, то вам нужно следить за зависимостями и не вводить циклические зависимости между библиотеками.

0 голосов
/ 30 января 2018

Вы можете использовать - архивы стартовой группы --end-group и напишите 2 зависимые библиотеки вместо архивов

gcc main.o -L. -Wl, - начальная группа -lobj_A -lobj_b -Wl, - конечная группа

...