2

I am trying to link a compiled research experiment project, built in C/C++. The project is dependant on HyperNEAT and robot simulation software WeBots. I have cloned and built the HyperNEAT project successfully (in that project there are other dependancies such as Boost, TinyXML, JGTL (custom library) and other unrelated subprojects).

I have made a makefile including all neccesary header search paths and library paths, and compiling the two main .cpp files:

/ModHyperNEAT/mod_ctrler7.cpp 
/ModSupervisor/mod_supervisor.cpp

works, giving me 2 .o files.

However, in the make link step, when I want to create (separate) executables of both files, I am getting the 'undefined symbols for architecture x86_64' error (see pastebin here: http://pastebin.com/kiwwCcUf). It seems that C++ standard datatypes and functions such as std::string::end() const cannot be found.

I have googled and searched SO for answers regarding this, and it seems that either libraries are missing or binary incompatible if i understand correctly, but the libraries are there and both projects have been compiled with the -lstdc++ flag.

This is the make link step (and the used macro's from the makefile) :

CC = gcc
CFLAGS = -v -g -lstdc++ -Wall -Wno-error -ferror-limit=100 -fmessage-length=0
DEFINES = -DHCUBE_NOGUI -DTIXML_USE_STL
FLAGS = $(CFLAGS) $(DEFINES)

LIB_TINYXML = -L/Users/michahell/Documents/projects_c++/HyperNEAT/tinyxmldll/out
LIB_HYPERNEAT = -L/Users/michahell/Documents/projects_c++/HyperNEAT/NE/HyperNEAT/out
LIB_BOOST = -L/usr/local/Cellar/boost/1.57.0/lib
LIB_WEBOTS = -I/Applications/Webots/lib

LIBS = $(LIB_TINYXML) $(LIB_HYPERNEAT) $(LIB_BOOST) $(LIB_WEBOTS)
LIBFLAGS = -ltinyxmlpluslib -lboost_filesystem-mt -lboost_random-mt -lboost_system-mt -lNEATLib_d -lHypercube_NEAT_Base_d
WEBOTS_DYLIB = -dylib_file /Applications/Webots/lib/libController.dylib:/Applications/Webots/lib/libController.dylib

$(CC) $(FLAGS) $(LIBS) ./mod_ctrler7.o $(WEBOTS_DYLIB) $(LIBFLAGS)

I found out that to link to .dylib's I had to use a specific flag and specify the full path, hence the $(WEBOTS_DYLIB) macro. I am using the -lstdc++ flag because in the HyperNEAT project that flag was also used for building that library. If i exclude this flag, i get a lot of errors during compilation (libc++ and libstdc++ incompatibility as I now understand). All of the library paths check out, and .a and/or .dylib files are present.

My knowledge of C/C++ and GCC tooling is very limited, as I have never had to use it before. I think it might have to do with the fact that the HyperNEAT project contains a Boost 1.57.0 distribution which is used for their build, and that i have a separate (using homebrew) Boost version installed on my system, which is the same version:

$ brew info boost
boost: stable 1.57.0 (bottled), HEAD
http://www.boost.org
/usr/local/Cellar/boost/1.57.0 (10572 files, 439M) *

What could be the cause of this error failing my link step? Anyone should be able to reproduce my linker errors if both HyperNEAT and my project are cloned and put their root dirs in the same location. WeBots should be downloaded but only for the header includes and libraries. And of course my makefile paths should be modified.

If anyone can give me tips on how to solve this problem, i would GREATLY appreciate it!

Michahell
  • 4,905
  • 5
  • 29
  • 45
  • Instead of manually linking with `stdc++`, why not simply build your C++ code with `g++` which handles that automatically? – Some programmer dude Jan 12 '15 at 16:14
  • I have no good answer to that since i'm not familiar with C/C++ build tool intricacies, i will try to do that now and see if anything changes. – Michahell Jan 12 '15 at 16:15
  • I have substituted GCC for G++ and removed the lstdc++ flag. For the link step at least, nothing changes and the errors persist unfortunately :/ – Michahell Jan 12 '15 at 16:17
  • It could be duplicated to http://stackoverflow.com/questions/25020140/undefined-symbols-for-architecture-x86-64-mavericks . I suspect that boost and other libraries mixed libc++ and libstdc++ on Mac. Try rebuild boost as suggested with explicit stdlib selection. – Sergei Nikulov Jan 13 '15 at 07:53

1 Answers1

0

It turns out that, for some reason, I had to include the lstdc++ flag to the library link flags and not as a compiler flag, AND the stdlib=libstdc++ as compiler flag.

Michahell
  • 4,905
  • 5
  • 29
  • 45