Why am I getting the following linker error when using clang with libc++:
$ clang++ -stdlib=libc++ po.cxx -lpoppler
/tmp/po-QqlXGY.o: In function `main':
po.cxx:(.text+0x33): undefined reference to `Dict::lookup(char*, Object*, std::__1::set<int, std::__1::less<int>, std::__1::allocator<int> >*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Where:
$ nm -D /usr/lib/x86_64-linux-gnu/libpoppler.so | grep lookup | c++filt| grep \ Dict::lookup\(
00000000000c1870 T Dict::lookup(char*, Object*, std::set<int, std::less<int>, std::allocator<int> >*)
Code is simply:
#include <poppler/PDFDoc.h>
int main()
{
Dict *infoDict;
Object obj;
infoDict->lookup((char*)"key", &obj);
return 0;
}
The error: undefined reference to function show() has appeared on the terminal shell as predicted. To solve this error, simply open the file and make the name of a function the same in its function definition and function call.
The Clang tool is a front end compiler that is used to compile programming languages such as C++, C, Objective C++ and Objective C into machine code. Clang is also used as a compiler for frameworks like OpenMP, OpenCL, RenderScript, CUDA and HIP.
So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.
If you want to use clang instead of GCC, you can add -DCMAKE_C_COMPILER=/path/to/clang -DCMAKE_CXX_COMPILER=/path/to/clang++ . You can also use ccmake , which provides a curses interface to configure CMake variables in an interactive manner.
According you error, it should be like you're trying to link a libc++ with stdlibc++, the libc++ and stdlibc++ is different, stdlibc++ is gcc's c++ standard library, it will not compatible with each other.
For your issue, it's like your libpoppler.so is using stdlibc++, but in your clang command line, you're trying use libc++ as standard lib, they have different name in linking stage, see link at the end of this answer for detail why.
So, maybe your solution is just change the compile command to
clang++ -stdlib=libstdc++ po.cxx -lpoppler
Please see this question for detail why std:__1::set and std::set.
Why can't clang with libc++ in c++0x mode link this boost::program_options example?
Because libpoppler.so
is linked against GNU stdlibc++. All parts of a single executable have to be linked against the same standard C and the same standard C++ libraries.
The easiest option is to just go with the default standard library. Both are now mostly C++11-complete.
Alternatively you can build version of libpoppler.so
against libc++
, but you'd have to give it different name so the dynamic linker finds the right one.
In the link error you can see that libpoppler.so
refers to std::set
and std::less
etc., but your objects want to refer to std::__1::set
and std::__1::less
etc. That is because GNU stdlibc++ and Clang libc++ approach versioning differently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With