Reputation: 422
I am having a linker problem that I can't fix (using MacOS and xcode).
First off, when I compile with -fvisibility=hidden all is fine. If I omit that flag, I get
"XYZ::IPlugView::iid", referenced from:
__ZN9XYZ9IPlugView3iidE$non_lazy_ptr in pluginview.o
(maybe you meant: __ZN9XYZ9IPlugView3iidE$non_lazy_ptr)
I don't know if this is related, but before that are a couple warnings like
ld: warning: non-virtual thunk to XYZ...::release()has different visibility (hidden) in xyz/foo.o and (default) in xyz/bar.o
Any Ideas would be greatly appreciated.... Thanks!
Upvotes: 0
Views: 2042
Reputation: 132869
The warnings might in fact be related. What these warnings are trying to tell you is that there is a symbol named XYZ...::release()
and this symbol is defined twice, once in the file xyz/foo.o
(probably compiled from xyz/foo.cc
) and one in the file xyz/bar.o
(probably compiled from xyz/bar.cc
), however, the symbol is not twice defined with the same visibility, one symbol is default (visible outside the current binary/library you are compiling) and one is hidden (only visible within the current binary/library you are compiling). The same symbol cannot have two different visibilities, of course.
By using -fvisibility=hidden
you tell the compiler: Whenever there is no code annotation that would otherwise define the visibility of a symbol, make this symbol hidden. This probably solves your problem as the duplicate symbols that used to be once hidden and once default are now twice hidden, because the definition that used to be default was probably implicitly made default and now its implicitly made hidden, which means the symbol is twice hidden and this resolves the conflict, since the two symbols are probably treated like a single one by the linker.
Within your source code, there are two ways to set the visibility of a symbol, either by attribute or by pragma. To make a symbol hidden, you can either append __attribute__ ((visibility ("hidden")))
in front of its definition or you can place a pragma #pragma GCC visibility push(visibility)
somewhere in your source file, causing all symbol definitions below it to be set hidden until you either use the pragma #pragma GCC visibility pop
to return to the previous visibility state (or back to the default one if there wasn't a previous one), use another pragma to change the visibility to something else or to the end of the file, whatever comes first.
I think in your case the symbol in question is once defined in foo.cc with an explicit visibility (which is hidden) and once in bar.cc with no explicit visibility, so it's either default or hidden, depending on your -fvisibility
flag.
Upvotes: 3