Неопределенные символы: для -fvisibility = скрыто - PullRequest
0 голосов
/ 13 февраля 2012

У меня проблема с компоновщиком, которую я не могу исправить (используя MacOS и xcode).

Прежде всего, когда я компилирую с -fvisibility = hidden все в порядке.Если я пропущу этот флаг, я получу

"XYZ::IPlugView::iid", referenced from:
     __ZN9XYZ9IPlugView3iidE$non_lazy_ptr in pluginview.o
     (maybe you meant: __ZN9XYZ9IPlugView3iidE$non_lazy_ptr)

Я не знаю, связано ли это, но перед этим есть пара предупреждений, таких как

ld: warning: non-Виртуальный Thunk для XYZ ... :: release () имеет различную видимость (скрыто) в xyz / foo.o и (по умолчанию) в xyz / bar.o

Любые идеи будут с благодарностью.... Спасибо!

1 Ответ

2 голосов
/ 06 марта 2012

Предупреждения могут быть связаны между собой. Эти предупреждения пытаются вам сказать, что существует символ с именем XYZ...::release(), и этот символ определяется дважды: один раз в файле xyz/foo.o (вероятно, скомпилирован из xyz/foo.cc) и один в файле xyz/bar.o (возможно, скомпилировано из xyz/bar.cc), однако символ не дважды определяется с одинаковой видимостью, один символ используется по умолчанию (видимый вне текущего двоичного файла / библиотеки, которую вы компилируете), а другой скрытый (видимый только в текущем двоичном файле / библиотеке, который вы компилируем). Конечно, один и тот же символ не может иметь две разные видимости.

Используя -fvisibility=hidden, вы сообщаете компилятору: всякий раз, когда нет аннотации кода, которая в противном случае определяла бы видимость символа, сделайте этот символ скрытым. Это, вероятно, решает вашу проблему, поскольку повторяющиеся символы, которые когда-то были скрыты и когда-то по умолчанию, теперь дважды скрыты, потому что определение, которое раньше использовалось по умолчанию, вероятно, было неявно установлено по умолчанию, а теперь его неявно сделано скрытым, что означает, что символ скрыт дважды и это разрешает конфликт, так как два символа, вероятно, обрабатываются компоновщиком как один.

В вашем исходном коде есть два способа установить видимость символа, либо по атрибуту, либо по прагме. Чтобы сделать символ скрытым, вы можете либо добавить __attribute__ ((visibility ("hidden"))) перед его определением, либо поместить прагму #pragma GCC visibility push(visibility) где-нибудь в исходном файле, в результате чего все определения символов под ним будут скрыты, пока вы не используете прагму #pragma GCC visibility pop чтобы вернуться к предыдущему состоянию видимости (или вернуться к состоянию по умолчанию, если предыдущего не было), используйте другую прагму, чтобы изменить видимость на что-то другое или на конец файла, что бы ни наступило раньше.

Я думаю, что в вашем случае рассматриваемый символ когда-то определен в foo.cc с явной видимостью (которая скрыта) и один раз в bar.cc без явной видимости, поэтому он либо скрывается по умолчанию, либо в зависимости от вашего -fvisibility флаг.

...