Linker error with libPocoNet.a, std::__debug::vector, and debug build of ofxMaps example?

Hi all,

After compiling ofxMaps for the Mac ( Problem compiling ofxMaps on OS X ), I tried to do the same on Linux. I’m using:

$ uname -a
Linux mypc 3.19.0-28-generic #30~14.04.1-Ubuntu SMP Tue Sep 1 09:33:32 UTC 2015 i686 i686 i686 GNU/Linux
$ cat /etc/issue
Ubuntu 14.04.3 LTS \n \l

… and I’m using the openFrameworks (and the addons) from git, with the following versions:

openFrameworks:
commit da00a82d5a0f312d595a914583b6b2ce4a00a3ca (HEAD, origin/master, origin/HEAD, master)
Date:   Wed Sep 16 18:41:19 2015 +0200

ofxGeo:
commit a642135750c5d3f3c01b37a0d4ee35c7ca7d888b (HEAD, origin/master, origin/HEAD, master)
Date:   Thu Aug 6 10:18:18 2015 -0500

ofxHTTP:
commit 2fb2e76402ef3c1f500aebe646d5affb12b3a9fc (HEAD, origin/develop, develop)
Date:   Fri Aug 7 16:31:12 2015 -0500

ofxIO:
commit c4ac7bc6cc546b8ab12058bf5a2ffb73d0c400f6 (HEAD, origin/develop, develop)
Date:   Wed Aug 26 22:05:33 2015 -0500

ofxMaps:
commit 8a743b6073e35e9e512056552239f586c66cf8ec (HEAD, origin/develop, develop)
Date:   Wed Jun 24 15:13:33 2015 -0500

ofxMediaType:
commit 1a58a770bc20b078659c937a76870e1ca1e27995 (HEAD, origin/master, origin/HEAD, master)
Date:   Tue Aug 4 22:04:35 2015 -0500

ofxNetworkUtils:
commit 661eb3ed1c382b48df3b56cce94602458f5de0d6 (HEAD, origin/develop, develop)
Date:   Tue Aug 4 22:05:33 2015 -0500

ofxSpatialHash:
commit a136258885e144cbce3dffca44b8afb818c6cfba (HEAD, origin/master, origin/HEAD, master)
Date:   Fri Aug 7 14:12:11 2015 -0500

ofxSSLManager:
commit 0acbc4bea436b63748781df971f88a3c9a2d4875 (HEAD, origin/master, origin/HEAD, master)
Date:   Tue Aug 4 23:45:35 2015 -0500

ofxTaskQueue:
commit ccd6e5698a6086a1fcbf94582abbf6c7ff352cfc (HEAD, origin/develop, develop)
Date:   Tue Aug 4 22:06:17 2015 -0500

The addon folders are in openFrameworks/addons/ - while the ofxMapsexample folder is in openFrameworks/examples/addons/, named as ofxMaps_example.

First, when I try to use:

make Release

… from within the ofxMaps_example, all the addon object files get compiled, and linking passes well - and I can confirm the resulting executable works just as well as in the Mac case. So, no problem here.

However, if I try to build a debug version, using:

make Debug

… then, everything compiles fine, but there is a problem in the linker step; here is a small snippet (I’ve inserted \ to ease the reading of what is a single line, on multiple lines):

...
Linking bin/ofxMaps_example_debug for linux
g++ -o bin/ofxMaps_example_debug  obj/linux/Debug/src/main.o \
obj/linux/Debug/src/ofApp.o \
../../../addons/obj/linux/Debug/ofxMaps/libs/ofxMaps/src/BaseURLTileProvider.o \
... \
../../../libs/poco/lib/linux/libPocoZip.a \
../../../libs/poco/lib/linux/libPocoNet.a \
../../../libs/tess2/lib/linux/libtess2.a \
... \
-ldl -lpthread -lfreeimage -lrtaudio -lboost_filesystem -lboost_system

../../../addons/obj/linux/Debug/ofxMaps/libs/ofxMaps/src/BaseURITileProvider.o: In function `ofx::Maps::BaseURITileProvider::BaseURITileProvider(std::string const&, std::string const&, int, int, int, int, ofx::Maps::BaseProjection const&)':
/.../openFrameworks/examples/addons/ofxMaps_example/../../../addons/ofxMaps/libs/ofxMaps/src/BaseURITileProvider.cpp:80: undefined reference to `Poco::DigestEngine::digestToHex(std::__debug::vector<unsigned char, std::allocator<unsigned char> > const&)'
collect2: error: ld returned 1 exit status
make[1]: *** [bin/ofxMaps_example_debug] Error 1
make[1]: Leaving directory `/.../openFrameworks/examples/addons/ofxMaps_example'
make: *** [Debug] Error 2

Now, here is the interesting thing: the symbol, as such, exists - unfortunately with a different signature.

So for the libPocoNet.a library, which clearly is included in the linker command, we can see that it has the following digestToHex symbol:

$ grep digestToHex ../../../libs/poco/lib/linux/libPocoNet.a
Binary file ../../../libs/poco/lib/linux/libPocoNet.a matches

$ nm -C ../../../libs/poco/lib/linux/libPocoNet.a | grep digestToHex
 U Poco::DigestEngine::digestToHex(std::vector<unsigned char, std::allocator<unsigned char> > const&)
 U Poco::DigestEngine::digestToHex(std::vector<unsigned char, std::allocator<unsigned char> > const&)

Note that libPocoNet.a library is "pre-compiled’, in the sense of it being included in the openFrameworks git ( see: https://github.com/openframeworks/openFrameworks/tree/master/libs/poco/lib/linux ); thus it apparently doesn’t compile during the ./compileOF.sh step of building openFrameworks.

On the other hand, here is the digestToHex symbol in the BaseURITileProvider.o, which gets built during the make command of the example:

$ nm -C ../../../addons/obj/linux/Debug/ofxMaps/libs/ofxMaps/src/BaseURITileProvider.o | grep digestToHex
 U Poco::DigestEngine::digestToHex(std::__debug::vector<unsigned char, std::allocator<unsigned char> > const&)

So, the difference is:

  • std::vector<unsigned char, std::allocator<unsigned char> > in .a
  • std::__debug::vector<unsigned char, std::allocator<unsigned char> > in .o

So the error message is actually correct ( see also http://codeyarns.com/2015/02/10/how-to-enable-debug-mode-for-c-containers/, http://stackoverflow.com/questions/19729036/boost-program-options-wont-work-with-glibcxx-debug/19731336#19731336 ), as there is indeed a difference between the symbol signatures.

However, my question is - what would be the right way to go about, so as to also be able to obtain a debug build of (in this case) the ofxMaps example, under Linux (also, I’m only doing 32-bit builds at the moment)?