Link errors with curlpp

The problem is that linkage of ccurlcpp::UnsetOption::UnsetOption is partially defective in the lipcurlcpp.so binary.

The linker's complaint with:

g++ -o example00 example00.cpp -lm -lcurl -lcurlpp

is:

undefined reference to `curlpp::UnsetOption::UnsetOption(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

But if I demangle the constructor signatures in libcurlpp.so:

nm -D -C libcurlpp.so | grep UnsetOption::UnsetOption

I see:

0000000000021776 T curlpp::UnsetOption::UnsetOption(char const*)
000000000002173e T curlpp::UnsetOption::UnsetOption(std::string const&)

The std::string hasn't been properly de-typedefed for some reason. If I get the source file in which this constructor is defined from the curlpp 0.7.3 source package, Exception.cpp, compile it:

curlpp-0.7.3/src/curlpp$ g++ -I../../include -I. -c Exception.cpp

and then demangle the constructor signatures from the object file:

nm -C Exception.o | grep UnsetOption::UnsetOption

I get:

00000000000003f4 T curlpp::UnsetOption::UnsetOption(char const*)
00000000000003c2 T curlpp::UnsetOption::UnsetOption(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

So:

curlpp::UnsetOption::UnsetOption(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

is the signature the compiler is telling the linker to look for, but that is not the signature in the library. The short explanation of the error is: the library is broken.

However, we see that no such inconsistency affects the other overload of the constructor:

curlpp::UnsetOption::UnsetOption(char const*)

nor could it, since the char const * is a builtin type.

This enables a hack fix. The file in which the undefined-reference call is compiled is (as installed) /usr/include/curlpp/Option.inl, at the line:

throw UnsetOption(std::string("You are trying to set an unset option to a handle"));

Edit this file, as root, and you see that it (inconsistently) contains two instances of:

throw UnsetOption(std::string("blah blah"));

and one instance of:

throw UnsetOption("blah blah");

Change the occurrences of UnsetOption(std::string("blah blah")) to UnsetOption("blah blah"). Then only the good constructor is called in this file and example00, at least, will compile and link.

If you dislike the hack, or find that the problem re-surfaces elsewhere, then you may download the ubuntu source package curlpp_0.7.3.orig.tar.gz and build and install it yourself. That is the right remedy.


You can try to compile your project using old ABI:
g++ -o example00 example00.cpp -D_GLIBCXX_USE_CXX11_ABI=0 -lm -lcurl -lcurlpp