32

We are building a Mac OSX application which is written mostly in Obj-C/Cocoa. The application then statically links with some 3rd party libraries, written in C/C++ and compiled by us (on a command line, using either MacPorts or the usual "./configure && make"; all are universal binaries).

The application is working perfectly, but ad compile time we are always getting these strange linker warnings:

ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZN5boost10scoped_ptrIN4i18n12phonenumbers15PhoneNumberUtilEED1Ev means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

This comes from a C/C++ library. We are linking with these libs:

  1. libphonenumber, which is the one causing 4 of the 5 warnings, apparently. Compiled by us via "cmake".
  2. boost (libboost_thread-mt), responsible of 1 warning. Compiled with MacPorts.
  3. ICU (libicudata, libicuuc, libicui18n), compiled with MacPorts.
  4. Protocol Buffers, compiled via "./configure && make".

Please note:

  1. The application is working perfectly despite the warnings, but we'd like to get rid of them as they are annoying.
  2. The solution proposed by xcode with boost : linker(Id) Warning about visibility settings doesn't work: "Symbols hidden by default" has always been "YES".
Community
  • 1
  • 1
ItalyPaleAle
  • 7,185
  • 6
  • 42
  • 69
  • you can make libphonenumber smaller by using the "re2" regex library instead of the full ICU one by using the C Flag `-DUSE_RE2=1` – Matt Connolly Nov 08 '12 at 11:42
  • @MattConnolly isn't ICU still required? It can use re2 for the regex, but it still requires ICU for other things... Eventually, I found a "solution". It's definitely a dirty one, but works: use the JS (yes, JavaScript) version and call it from Cocoa. It's also faster than what I expected it to be! – ItalyPaleAle Nov 09 '12 at 09:06
  • You can link to the iOS provided icucore library. Don't you need to set up a webview to run javascript? If it's using the v8 optimiser, it could be ok... I'll git it a look too. – Matt Connolly Nov 09 '12 at 22:02
  • @MattConnolly no you don't need to set up a web view to run JS code. You can use the JavaScriptCore framework, which is part of WebKit and bundled in the OS... The performances are not bad, actually! – ItalyPaleAle Dec 12 '12 at 23:40

4 Answers4

29

The solution proposed by xcode with boost : linker(Id) Warning about visibility settings doesn't work: "Symbols hidden by default" has always been "YES".

This has less to do with being set to "YES", and more to do with being set to the same value across all projects. Libs/projects that depend on other libs need to have a likewise setting for "Symbols hidden by default" in order to link properly and free of errors/warnings.

I've run into this before, and a simple change in Xcode for all projects to ensure the settings match typically resolves the problem. Since it sounds like you're compiling on the command line as well, the -fvisibility argument to gcc is what you need to look at.

inspector-g
  • 4,146
  • 2
  • 24
  • 33
  • Thanks for your answer. I'm not sure I've understood clearly, however: you mean I should add "fvisibility" to GCC when I compile boost, libphonenumbers etc? – ItalyPaleAle Mar 31 '12 at 08:59
  • 2
    Yes, if you're compiling those with gcc, that's where I would start. Adding `-fvisibility=default` will make all symbols "public". The ultimately proper choice for your project(s) depends on your needs, of course, so I would read the docs regarding `-fvisibility` by running `man gcc` in Terminal or Google searching for them. But, as I mentioned, making sure all projects use the same `-fvisibility` setting typically resolves this problem. Start with `default` (essentially "public"). – inspector-g Mar 31 '12 at 23:32
  • Thank you. I'm going to try that tomorrow and will report you the results! – ItalyPaleAle Apr 01 '12 at 00:25
  • 1
    FYI, I just checked my Xcode projects that use static libs, and most of them actually have "Symbols hidden by default" set to "NO". I'm not sure how Xcode translates this to a `-fvisibility` setting, as it only seems to include it in command line output when set to "YES" (in this case it does `-fvisibility=hidden` which is essentially the opposite of `-fvisibility=default`). Worst case, use `-fvisibility=default` in your makefile(s) and add it to the "Other C Flags" in your Xcode project(s). – inspector-g Apr 01 '12 at 07:19
  • 1
    Ok, so I recompiled libphonenumber with the switch, and nothing changed. However, after that I changed "Symbols hidden by default" to "NO" as you suggest, and now all warnings related to libphonenumber disappeared. Only the one related to boost is there (but recompiling boost takes 1 hour, so I'm doing that later :) ). Thanks! – ItalyPaleAle Apr 01 '12 at 10:48
  • -fvisibility=default was an excellent suggestion. Saved me a lot of time. Many thanks! – valvoline Feb 27 '13 at 21:56
  • Thank you, your answer was much appreciated! – AgnosticDev Aug 25 '15 at 16:19
9

tl:dr; use -fvisibility=hidden as a gcc and llvm compiler switch in everything you compile, including your dependent libraries, unless you have a reason not to.

A good introduction to the -fvisibility and -fvisibility-inline-hidden compilation flags is available on Apple's web site, as of this writing. The article also goes into some detail on the __attribute__((visibility("hidden"))) and __attribute__((visibility("default"))) declarations.

johnwbyrd
  • 3,432
  • 2
  • 29
  • 25
  • 1
    Yes. Sometimes if you use -fvisibility=hidden you have to expose some symbols with attributes (or push/pop, as explained in the link). – Yoav Aug 11 '16 at 12:20
6

I got the warning gone in Xcode by putting -fvisibility=hidden -fvisibility-inlines-hidden into OTHER C++ FLAGS.

Striezel
  • 3,693
  • 7
  • 23
  • 37
guest2016
  • 61
  • 1
  • 1
  • Kind of a lame addition, but put these in "other C flags" instead since C++ flags are usually set to inherit from C flags – Joel Teply Jan 03 '18 at 20:33
4

I also got this, for similar reasons, but I think the problem was inconsistency of the inlining visibility settings.

See http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-December/046505.html

I set all inlining hidden to no and the warning (finally) went away.

Nick
  • 27,566
  • 12
  • 60
  • 72
  • 1
    Tried inspector-g's answer and it didn't work but this one got rid of my warnings. Seems like it's the same concept, just different settings. – alk3ovation May 07 '13 at 21:32