Why does the Folly shared library refer to the wrong character from Boost? (GCC on OS X)

I am trying to create and run a small sample application that uses Folly on OS X Yosemite using GCC 4.9.3. Here is the source code:

#include <folly/AtomicHashMap.h> int main() { folly::AtomicHashMap<int, int> map(256); map.insert(std::make_pair(1, 1)); return 0; } 

I built and installed both Boost sources (1.59.0) and Folly (the last GitHub head) from sources, making sure GCC was used, and now their libraries and headers are available in /usr/local . GCC and other dependencies were installed using MacPorts. I can build the above selection using the following command line:

 $ g++-mp-4.9 main.cpp -std=c++11 -I/usr/local/include -L/opt/local/lib -lfolly -lglog 

However, when I try to start it, the following error appears:

 $ ./a.out dyld: Symbol not found: __ZNK5boost15program_options22error_with_option_name23substitute_placeholdersERKSs Referenced from: /usr/local/lib/libfolly.57.dylib Expected in: flat namespace in /usr/local/lib/libfolly.57.dylib Trace/BPT trap: 5 

From what I understand, the way this should work is that /usr/local/lib/libfolly.57.dylib automatically pulls libboost_program_options.dylib from the link at boot time. I see that it is listed as a dependency when I run otool -L :

 $ otool -L /usr/local/lib/libfolly.57.dylib /usr/local/lib/libfolly.57.dylib: /usr/local/lib/libfolly.57.dylib (compatibility version 58.0.0, current version 58.0.0) libboost_context.dylib (compatibility version 0.0.0, current version 0.0.0) libboost_program_options.dylib (compatibility version 0.0.0, current version 0.0.0) ... 

libboost_program_options.dylib is located in /usr/local/lib , and if I rename it to something else, running ./a.out causes the bootloader to complain that it cannot find it ("dyld: library not loaded: libboost_program_options .dylib "). It looks like the bootloader can find it, at least.

I checked the characters exported by this library using nm -gU :

 $ nm -gU /usr/local/lib/libboost_program_options.dylib | grep program_options ... 0000000000023560 T __ZNK5boost15program_options22error_with_option_name23substitute_placeholdersERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE ... 

So there is a character very similar to the one the bootloader complains about. The distorted name has a different suffix.

[ Edit: It is not very easy to see the names unless you scroll them to the right, so here they are again:

  • nm says the library contains __ZNK5boost15program_options22error_with_option_name23substitute_placeholdersERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE
  • "Missing character" at boot time __ZNK5boost15program_options22error_with_option_name23substitute_placeholdersERKSs .]

I found the corresponding declaration in /usr/local/include/boost/program_options/errors.hpp :

 namespace boost { namespace program_options { ... class BOOST_PROGRAM_OPTIONS_DECL error_with_option_name : public error { ... protected: ... virtual void substitute_placeholders(const std::string& error_template) const; 

I assume this is the header file that Folly used when I built it, because it is the only matching occurrence of substitute_placeholders in all /usr/include , /usr/local/include and /opt/local/include . (Note that Folly does not even call this function directly, but it is #include <boost/program_options.hpp> from folly/experimental/ProgramOptions.h and uses other boost::program_options members.)

It seems to me that the longer distorted name - the only one actually exported from libboost_program_options.dylib - is correct, since it includes the std::string argument.

So, what could cause libfolly.57.dylib refer to another (shorter) malformed name?

Other notes:

  • I originally installed Boost from MacPorts instead of creating it from sources, and this led to the same error.
  • If I build the sample using g++-mp-4.9 main.cpp -std=c++11 -I/usr/local/include -L/opt/local/lib /usr/local/lib/libfolly.a -lglog - in other words, just link to the Folly static library instead - the problem goes away and the sample starts.
+7
c ++ gcc boost macos
source share
1 answer

Using C ++ filt (or http://demangler.com ) to decouple two characters, the character in the boost library has the prefix std::__1::basic_string , while the one that is absent from stupidity has std::string . Some googling indicates that the __1 subset __1 used by libC ++ (the C ++ standard library clang) to avoid conflicts with libstdC ++ (GNU's). This indicates that boost was compiled using clang and lib ++, which is used by default for OS X, while stupidity was compiled using libstd ++ (either using g ++, or with different flags for clang )

Since the two libraries do not have a compatible ABI, simply correcting the symbol name will not help you, so your solution will have to include recompiling or sharing the same standard library.

+12
source share

All Articles