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

纵然是瞬间 提交于 2019-11-29 18:41:17

问题


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;
}

回答1:


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?




回答2:


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.




回答3:


Because libc++ uses a different namespace from the GNU C++ standard library. This linker error is a good thing because the layout of the two libraries' types are certainly going to be different for some types.

So what this means is that your 'poppler' library built against the GNU C++ std library, which has one set of names -- whereas and the compiler used the declarations in libc++ for the function calls in your program's translation. Thus, the linker looks for symbols in the objects (e.g. the poppler library) which have the libc++ naming for std library declarations, but it does not find them because they were not emitted with the same name -- they probably exist in the poppler library with the GNU names.

Of course, you probably just care how this can be fixed: build both your program and the poppler library using the same standard library. If you cannot build the poppler library, you will have to wait for them to push out a binary which is built against libc++.



来源:https://stackoverflow.com/questions/18459894/clang-stdlib-libc-leads-to-undefined-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!