Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang++ -stdlib=libc++ leads to undefined reference

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;
}
like image 522
malat Avatar asked Aug 27 '13 07:08

malat


People also ask

How do you fix a undefined reference?

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.

Does Clang work for C++?

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.

How do I fix undefined reference error in C++?

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.

Can I use Clang instead of GCC?

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.


2 Answers

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?

like image 178
Jiejing Zhang Avatar answered Oct 22 '22 23:10

Jiejing Zhang


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.

like image 45
Jan Hudec Avatar answered Oct 22 '22 21:10

Jan Hudec