0xc0dec
0xc0dec

Reputation: 11

XCode: "undefined symbols" for one specific method from library (iOS)

I have a test project that is linked against a game engine static library. I managed to successfully build it for OS X and iOS, and then, during my experiments, added a new usage of library method to my application code (having some other usages already):

std::vector<Node*> allNodes;
_scene->findNodes("", allNodes, true, false);

After that iOS build started to produce linker errors (while OS X build still works fine):

Undefined symbols for architecture armv7:
  "gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const", referenced from:
      App::initialize() in App.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Undefined symbols for architecture armv7s:
  "gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const", referenced from:
      App::initialize() in App.o
ld: symbol(s) not found for architecture armv7s
clang: error: linker command failed with exit code 1 (use -v to see invocation)

At the same time other functions (from even the same class Scene) are linked and work fine. This method has the following signature:

unsigned int findNodes(const char* id, std::vector<Node*>& nodes, bool recursive = true, bool exactMatch = true) const;

In .cpp file its implementation has matching signature:

unsigned int Scene::findNodes(const char* id, std::vector<Node*>& nodes, bool recursive, bool exactMatch) const

Still it doesn't link. What could be wrong with this particular method?

XCode version is 5.0.2

EDIT 1: The library was built from sources for armv7/armv7s architecture, so as the app itself.

Upvotes: 1

Views: 2427

Answers (3)

0xc0dec
0xc0dec

Reputation: 11

The problem came from C++11. My app uses it, but the engine library doesn't. In library settings the options "C++ Language Dialect" and "C++ Standard Library" are set to "Compiler Default". In app settings they were set to "C++11 [-std=c++11]" and "Compiler Default" respectively. With these options I once had many linker errors for std functions, so I also specified libc++.dylib manually in "Link Binary With Libraries" section, and everything worked fine for a while. However, this combination of options resulted in such odd behavior.

I fixed the problem by removing libc++.dylib from the list and setting "C++ Standard Library" to "libc++". Library options remained unchanged. I began looking in this direction after comparing the nm output for the library and my object file:

$ nm -arch armv7 -A Products/Debug-iphoneos/libgameplay.a | grep findNodes
...
Products/Debug-iphoneos/libgameplay.a:Scene.o: 00000ea0 T __ZNK8gameplay5Scene9findNodesEPKcRNSt3__16vectorIPNS_4NodeENS3_9allocatorIS6_EEEEbb
...
$ c++filt __ZNK8gameplay5Scene9findNodesEPKcRNSt3__16vectorIPNS_4NodeENS3_9allocatorIS6_EEEEbb
gameplay::Scene::findNodes(char const*, std::__1::vector<gameplay::Node*, std::__1::allocator<gameplay::Node*> >&, bool, bool) const

$ nm -arch armv7 -A Intermediates/Rebus.build/Debug-iphoneos/Rebus-ios.build/Objects-normal/armv7/App.o | grep findNodes
<long_path>App.o: U __ZNK8gameplay5Scene9findNodesEPKcRSt6vectorIPNS_4NodeESaIS5_EEbb
$ c++filt __ZNK8gameplay5Scene9findNodesEPKcRSt6vectorIPNS_4NodeESaIS5_EEbb
gameplay::Scene::findNodes(char const*, std::vector<gameplay::Node*, std::allocator<gameplay::Node*> >&, bool, bool) const

(notice the "__1" difference in std::vector).

Thanks @sergio for clues.

Upvotes: 0

sergio
sergio

Reputation: 69027

You say that you have added a new method and that this method is not found by the linker.

One possible explanation is that you are linking against an older version of the library which does not contain the latest method you added to it. Either you recompile the library manually, or you specify a dependency between the test binary and the library.

It could help cleaning the project (you could even delete the "build" directory altogether) and recompiling from scratch.

Upvotes: 0

Daij-Djan
Daij-Djan

Reputation: 50089

symbol(s) not found for architecture armv7

the method gameplay::Scene::findNodes wasn't build for armv7 (the 'binary code' for older IOS devices and as of yet standard)

solution?

a) don't consider old devices and only build for armv7s [maybe the lib you use works there]

xcode > project settings / target settings
VALID_ARCHS=armv7s

b) complain to the maker


check with lipo if you don't trust the error:

example with gmaps

lipo -info /Users/dominik/Documents/work-sapient/project-myAudi/svn/myAudi-IntApp/Vendor/GoogleMaps/GoogleMaps.framework/GoogleMaps

Architectures in the fat file: /Users/dominik/Documents/work-sapient/project-myAudi/svn/myAudi-IntApp/Vendor/GoogleMaps/GoogleMaps.framework/GoogleMaps are: armv7 armv7s i386

Upvotes: 0

Related Questions