1

I'm working on multiple VST3 audio plugin projects for macOS. Technically, an audio plugin is a shared library (.dylib) loaded by a host application at runtime via dlopen. I'm linking both plugins against a self-built static version of protobuf 3.20.0 and I'm building my plugins using CMake.

I now had a bug where both plugins defined a protobuf message with the same name, so both plugins defined symbols with the same name but different content and as soon as I loaded the second one crashes occurred. The call stacks revealed that both protobuf messages interfered with each other, as e.g. destructors invoked in plugin a ended up calling the destructor symbol in plugin b.

Specifying CXX_VISIBILITY_PRESET hidden on my CMake target that encapsulates the protobuf library dependency and the plugin-specific protobuf messages, solves the problem, but leaves me with linker warnings like

ld: warning: direct access in function 'google::protobuf::internal::InternalMetadata::Container<google::protobuf::UnknownFieldSet>* google::protobuf::Arena::Create<google::protobuf::internal::InternalMetadata::Container<google::protobuf::UnknownFieldSet> >(google::protobuf::Arena*)' from file 'plugin_artefacts/Debug/libplugin_SharedCode.a(Message.pb.cc.o)' to global weak symbol 'typeinfo for google::protobuf::internal::InternalMetadata::Container<google::protobuf::UnknownFieldSet>' from file '/path/to/lib/libprotobuf.a(descriptor.pb.o)' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

I found a lot of posts that simply suggest to build everything with -fvisibility=hidden but none that actually has an in-depth explanation about the actual problem that this warning is about.

What I got so far is that libprotobuf.a defines the symbol in question as a weak symbol, that means a symbol that can be overridden at runtime. Right? This aligns with the output of

objdump --syms --demangle libprotobuf.a

which reveals something like

0000000000010470  w    O __DATA,__const typeinfo for google::protobuf::internal::InternalMetadata::Container<google::protobuf::UnknownFieldSet>

so, yes there is a weak symbol in there.

However, I don't quite get if and why this is problematic? As far as I get it, this symbol should only be relevant internally to my plugin and does not need to be exposed public anyway, so is there any need/benefit in it being declared weak? And why is it a weak symbol at all? If I get it right, this is a compiler generated symbol. Can I even alter the visibility of it? Should I?

I tried re-compiling libprotobuf.a with -fvisibility=hidden as additional entry in the CXXFLAGS environment variable before running the protobuf configure script, but inspecting the output still revealed the symbol being declared weak. Now I'm not sure if this is just because I passed the flag in a wrong way to the configure script (other flags handled the same way seem to have an effect though) or if this is just not the right thing to do.

In any case, after experiencing the bug described above, I would prefer to gain a deep understanding of the issue and then pick the right solution based on that understanding rather than just applying some compiler option to make it work without knowing what happened and what other unexpected side effects that could employ.

Links to blog posts etc. which discuss this topic in depth are also highly welcome – I rarely found anything like that during my own research.

PluginPenguin
  • 1,576
  • 11
  • 25
  • I'm encountering the same link warning, albeit under different circumstances. Did you ever figure out what causes this, or what it even means? I can't for the life of me resolve this warning, and building with `-fvisibility=hidden` doesn't seem to make any difference. – Bri Bri Nov 28 '22 at 07:54
  • Unfortunately not, we've been living with linker warnings since then and got no user report of any error so far, but that's actually not how I prefer it to be – PluginPenguin Nov 29 '22 at 13:38
  • Not sure if this will fix it for you, but what just finally got it for me was consistently using `-fvisibility-inlines-hidden` across everything I was compiling. – Bri Bri Dec 01 '22 at 01:19

0 Answers0