Undefined symbol _G4cerr, after linking against G4MT on MacOS

There isn’t a good category for this issue, so I’m going with “Persisting.” This is a problem I’ve run into in the past with older versions of G4, but I thought it had gone away.

  1. All this is on MacOSX 10.13.6, with LLVM Apple version 10.0.0.
  2. I have Geant4 10.06.p01 build for MT.
  3. I have an external library, G4CMP, which is built against that G4. Today, I rebuilt it with “-fno-omit-frame-pointer -fsanitize=thread” to do some thread-safety checking.
  4. I have an external appliation package, SuperSim, which is built against G4CMP and G4.

Today, after the “sanitize” mod, I relinked my executable. I am now getting an error at run time:

dyld: Symbol not found: _G4cerr
  Referenced from: /Users/kelsey/cdms/G4CMP/CMakeInstall/lib/libG4cmp.dylib
  Expected in: /Applications/GEANT4/geant4.10.06.p01/lib/libG4global.dylib
 in /Users/kelsey/cdms/G4CMP/CMakeInstall/lib/libG4cmp.dylib

I used to get this error in the past trying to build against G4 MT on my Mac, but it “went away” (and I’ve been working hard to make my application fully MT capable). I really don’t understand where it’s coming from.

In libG4cmp.dylib, I see the undefined symbol (using nm -C|grep _G4cerr). But in libG4global.dylib, all I see are _G4cerr_p() and _G4cerrbuf_p().

In the G4 source code (.hh, .cc and .icc) I don’t see _G4cerr anywhere, so I don’t understand how it’s coming into my G4CMP library.

Is this something anyone else has encountered?

Hi Mike
Not sure I can help, but there’s some really fancy code in G4ios.cc.
Also there’s an outstanding bug 2231 that might be related. It appeared with 10.6 I think.

#define G4coutbuf (*_G4coutbuf_p()) 67
#define G4cerrbuf (*_G4cerrbuf_p()) 68
#define G4cout (*_G4cout_p()) 69
#define G4cerr (*_G4cerr_p())

Thanks, John! Yeah, I saw those. Those show up in the libraries as well, but in my executable they show as resolved from libG4global.dylib. It’s only this weird _G4cerr, without the “_p()” part of the name, that is reporting as unresolved.

As for 2231, that’s interesting. I have my own troubles with the worker threads’ output :slight_smile:

One more thought, Mike. The fancy __G4cerr is only used #ifdef MULTITHREADING, so if, perhaps in your G4CMP library, you compile without, it might compile but look for G4cerr.

@mkelsey Check your CMake cache and use otool -L on any libraries you find. Verify you are actually linking to the libraries you think you are. When I re-wrote the MT to use the STL thread instead of pthreads, I had to rewrite a lot of the static thread_local variables initialized in the implementation files to function calls which returned a reference to a static thread_local value bc of some weird Windows stuff. That G4cout_p symbol was one of the things that was affected

On macOS, I usually find it is best to set -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON when building/installing Geant4 bc their runtime linking is a bit strange compared to Linux.

Thank you! A new build option :slight_smile: I dislike the DYLD_LIBRARY_PATH stuff, but I’ve never been able to get RPATH to do the right thing for me (especially in my Make-based projects).

Yep, that was my first step. The problem I ran into this time was switching from a Make-based build of an “intermediate” library (a package layered on top of G4, which my application uses), to a CMake build of the same package. I confirmed with otool -L that I was picking up the CMake-built libraries, and those were the ones which had this symbol error; with the Make-based version, all is well.