Yet another “ld: symbol(s) not found for architect

2019-03-15 10:37发布

问题:

I apologize for asking such a common question; I can't find any solution out there that works or is clear enough for me to implement. I am simply trying to install mgiza. Here is the INSTALL file:

cmake .
make
make install

If you want to install to a custom location, add the following flag when you run cmake:
-DCMAKE_INSTALL_PREFIX=/path/to/custom/location

NOTE: Boost Version 1.48 has problem with the code, you can use either 1.46 or 1.50+. Unfortunately 1.48 is shipped with Ubuntu 12.04 LTS, you can either download and compile libboost 1.50+ from their website, or just do this:
sudo apt-get install libboost1.46-all-dev

Looks easy, right? Typing in cmake . works without any apparent problems. Unfortunately, make runs into this dreaded error ("undefined symbols ...") with boost.

1 warning generated.
Linking CXX executable ../bin/d4norm
Undefined symbols for architecture x86_64:
  "std::string::_Rep::_M_destroy(std::allocator<char> const&)", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
  "std::string::_Rep::_S_empty_rep_storage", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
  "std::string::assign(char const*, unsigned long)", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()", referenced from:
      boost::system::(anonymous namespace)::generic_error_category::message(int) const in libboost_system-mt.a(error_code.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Based on other questions, it's a problem with Mavericks because it uses clang to compile c++ code, implying that the library is libc++, not libstdc++. For completeness, and so that others can reproduce my errors, I am using OS X 10.9.5, Xcode 6.1, and my boost version is 1.56 (boost was installed via homebrew).

Now, there has to be some fix out there, right? Let's go through some of them:

  1. Applying the -m32 flag: not applicable because the Makefile doesn't have any "g++" in it, and it also explicitly tells me NOT to edit it, because it's a "Cmake" generated file.
  2. Not defining something in a header file: not applicable because the code should be ready to compile.
  3. Adding -stdlib=libstdc++ to linker: I am not sure how to add this to a make command? I tried just doing make -stdlib=libstdc++ and while that seemed to avoid the errors above, it introduced some additional errors: make: *** [all] Error 2 (not sure what that means).
  4. Linking to proper boost libraries: There's a comment there that says "You just need to link to the proper boost libraries ... plenty of Q/As on how to do that". Unfortunately, I don't think any of the questions that commenter linked to address my problem.
  5. Linking Qt with boost: I don't think this is applicable because I'm not using Qt, and I don't know where I'd put in a LIBS += [...] boost line.
  6. Linking a missing file: That issue seems to be more about linking when running g++ but I'm using a Makefile that doesn't have g++ anywhere in it.
  7. Using g++ vs gcc: I don't know how I can change which of these I use, because I'm using cmake and make...
  8. Changing a link command: Again, I don't know how I can change the compilation from cmake/make to gcc. (Note: from this point on, I will ignore most questions that are answered by adding something to gcc or g++.)
  9. Changing the standard c++ library: the solution involves going into Xcode and changing the libraries there. I don't think this is the correct approach and in any case I'd probably screw up something if I changed a setting in Xcode (I also have no experience with Xcode's GUI).
  10. Linking libraries in Xcode: I think this is a similar case as #9 on this list. The answer here also recommends using homebrew instead of macports for installing boost, but I already said earlier that I used homebrew for installing boost.
  11. Compile with clang: A similar issue, but how do I get cmake or make to compile with clang?
  12. From a (popular) bitcoin issue: Now this looks interesting! A ton of people ran into my error. Unfortunately, there seems to be no consensus or easy solution. There are also a few solutions that I don't know to implement. For instance, one solution by "imbolo" there is to compile boost using a cxxflag flag, but what does that mean?

So I'm at a little bit of a loss on how to correctly install mgiza ... I mean, the whole point of mgiza giving me cmake and make is so that I don't have to worry about the messy details of compiling things, right? This isn't just an mgiza issue, though, since I've run into this problem when trying to do make elsewhere. I understand the high-level ideas of (C)Makefiles, but not the low-level details.

回答1:

To address some of the concerns by the commenters: the best way to deal with this problem is to try and clear your system as much as possible and start the process from scratch.

Also, since this was posted, OS X 10.10 Yosemite was released, which may have fixed this problem (IIRC this problem is mostly due to 10.9 and the clang/gcc complier changes).