Clang, AppleClang and hidden visibility issues in C++ libraries


I keep running into and hearing about issues where Qt/KDE projects fail to build because of symbols not being found during linking. This is in libraries provided by the project itself. These projects all set symbol visibility to hidden by default and when I run `nm` on the library supposed to provide the symbol I see it's there but labelled 't' instead of 'T'.

It seems that most of the time this occurs when using Apple's clang version from Xcode and that using a recent (>= 4) "stock" clang from MacPorts solves the issue, without changing anything else. I've been writing this off to the fact that my own AppleClang (from Xcode 6.2) is getting old but I just heard that the one from Mac OS 10.13 is affected too. I'm not sure exactly what stock clang version that corresponds to, but I'm hoping it should be at least 5.0 .

Any idea what can cause this, and more importantly, how to fix it?
The project mentioned above is libkcddb ( and I have to suppose the relevant compiler options are set in the extra-cmake-modules (; I'm not seeing anything suspicious in there though).

The way to catch stock clang or Apple's clang in cmake is still `CMAKE_CXX_COMPILER_ID MATCHES "Clang"`, right?


Do you have any more concrete details, such as the exact error messages, and maybe a self-contained test case?


I'm planning to have another look at the logs from failed and successful builds, but I strongly doubt I could make a self-contained test case of something that simply doesn't make sense to me. Most projects do build with AppleClang after all. Maybe looking at the changelog for the problem symbols in libkcddb will yield something because that project used to build with AppleClang (if I'm not mistaken!)
I do plan to file an issue against KDE's build system, will link to that here.

As to the exact error messages: they're what you'd expect when the linker cannot find a number of required symbols. Not really helpful I fear.


Hope this helps:


From the bug report you filed, it is the correct behavior. This is exactly what hidden visibility suppose to do.
For example, the symbol you point out in the bug report:
000000000001bdc0 T __ZN5KCDDB5Sites8siteListEv
000000000001bc80 t __ZN5KCDDB5Sites8siteListEv

This symbol is from sites.cpp. When you link libKF5Cddb.dylib, linker will hide the symbol so it is no longer an interface available from the dylib (aka. hidden). One easy workaround will be using static library and generate only one dylib. You can also carefully audit all the interface needs to be shared between dylibs with __attribute__((visibility("default"))).


I'd hope so, yet one of (Clang and GCC) or AppleClang gets something wrong...


Fortunately this is not a compiler bug, see my last post on the BKO ticket.

(KF5 can auto-generate export headers, and something goes wrong there when AppleClang is being used.)