Processing "dyld: lazy symbol binding failed failed: Symbol not found" error when nm does not find the symbol

I have a bold (32-bit and 64-bit) Intel binary drive called myBinary that does not start on another workstation running Mac OS X 10.8.2:

 $ myBinary dyld: lazy symbol binding failed: Symbol not found: __ZNSt8__detail15_List_node_base7_M_hookEPS0_ Referenced from: /usr/local/bin/myBinary Expected in: /usr/lib/libstdc++.6.dylib dyld: Symbol not found: __ZNSt8__detail15_List_node_base7_M_hookEPS0_ Referenced from: /usr/local/bin/myBinary Expected in: /usr/lib/libstdc++.6.dylib Trace/BPT trap: 5 

I compiled it from a Mac OS X 10.8.2 workstation using GCC 4.7.2:

 $ gcc --version gcc (MacPorts gcc47 4.7.2_2+universal) 4.7.2 

I ran nm and the character is undefined:

 $ nm /usr/local/bin/myBinary | grep __ZNSt8__detail15_List_node_base7_M_hookEPS0_ U __ZNSt8__detail15_List_node_base7_M_hookEPS0_ 

What did I miss or do wrong when compiling myBinary ? I'm not sure what I can do with the missing character in /usr/lib/libstdc++.6.dylib - should I statically compile the C ++ library in myBinary ?

+8
gcc osx-mountain-lion libstdc ++ dylib macos
source share
3 answers

You have 2 options, or do not use libraries that the client will not have ... (you can provide them as dyld or framework.)

or just statically link the library ... in fact it will be less in memory and on disk if your package is only one process, because you can strip characters that you are not using.

+2
source share

Each C ++ compiler has its own implementation of the standard C ++ library. Since you are using an external compiler (GCC 4.7), its library is not available among standard Mac OS X installations.

Your only options are to either link the library in your application, or statically link it.

To associate a library with an application:

  • Update library installation name with install_name_tool

  • Make sure your application finds it if necessary

eg. you can put dylib in .app / Contents / Frameworks, set its name to install @rpath and compile the application with -rpath @executable_path/../Frameworks .

+1
source share

I ran into the same problem when compiling on 10.6 using MacPorts GCC 4.8, and then tried to run my application on the new version 10.9 without MacPorts. Fortunately, I found your question, and Kentzo's answer answered me in the right direction as to why the problem arose ... but it really did not provide the solution I was looking for.

First, I’ll explain why it works correctly on your system: MacPorts provided your system with a version of libstdc ++, which GCC 4.7 provides characters for / under / opt / local / lib, not / usr / lib. Here's what seems to me (with GCC 4.8 universal):

 $ find /opt/local/lib -name 'libstdc++.*' /opt/local/lib/gcc48/i386/libstdc++.6.dylib /opt/local/lib/gcc48/i386/libstdc++.a /opt/local/lib/gcc48/i386/libstdc++.a-gdb.py /opt/local/lib/gcc48/i386/libstdc++.dylib /opt/local/lib/gcc48/i386/libstdc++.la /opt/local/lib/gcc48/libstdc++.6.dylib /opt/local/lib/gcc48/libstdc++.a /opt/local/lib/gcc48/libstdc++.a-gdb.py /opt/local/lib/gcc48/libstdc++.dylib /opt/local/lib/gcc48/libstdc++.la /opt/local/lib/libgcc/libstdc++.6.dylib /opt/local/lib/libstdc++.6.dylib 

And you can see what your application is related to otool -L :

 $ otool -L myBinary myBinary: /opt/local/lib/libgcc/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.18.0) /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 832.0.0) /opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11) 

The easiest way to improve portability is -static-libstdc++ -static-libgcc in your last step in building gcc (the one that the linker invokes). You need both because the dynamic libgcc will bring the dynamic libstdC ++ binding with it, so this is not enough to just request the static libstdC ++. For a simple application, here is what your gcc line might look like:

 g++ -static-libstdc++ -static-libgcc myBinary.cpp -o myBinary 

However, according to the gcc man page on linker options , static libgcc binding can cause problems when handling exceptions between libraries. I did not run into problems, but you could.

So, to do this with the Kentzo method, you must first get the latest install_name_tool from MacPorts so that it is not confused by unknown boot commands:

 sudo port install cctools +universal 

Now change the path so that it searches the executable directory:

 /opt/local/bin/install_name_tool -change /opt/local/lib/libgcc/libstdc++.6.dylib '@executable_path/libstdc++.6.dylib' /opt/local/bin/install_name_tool -change /opt/local/lib/libgcc/libgcc_s.1.dylib '@executable_path/libgcc_s.1.dylib' 

Now you just need to distribute these dylib with the application. If you are doing .app, copy dylibs to myBinary.app/Contents/MacOS/.

One final note: if you have problems creating universal binary code, you can build architectures separately (with different compilers and parameters), and then combine them using lipo :

 /usr/bin/g++ -arch i686 -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk myBinary.cpp -o myBinary_32 /opt/local/bin/g++ -arch x86_64 -static-libstdc++ -static-libgcc myBinary.cpp -o myBinary_64 lipo myBinary_32 myBinary_64 -create -output myBinary 
0
source share

All Articles