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