When enabling C++11 with stdlibc++ 4.7, clang erro

2019-01-18 13:35发布

问题:

I have been trying to get C++11 to work, after browsing different websites and Q/A, i am still having trouble with. I want to use clang with libstdc++. It is indicated in the clang status that it's supported with patch - http://clang.llvm.org/libstdc++4.7-clang11.patch. I download the gcc4.7 from macports and made corresponding changes in the headers for gcc4.7

The reason that i don't uses libc++ is because ABI compatibilities between libc++ and libstdc++, indicated by this thread: Why can't clang with libc++ in c++0x mode link this boost::program_options example?

OK, after everything is done, i tested my setup with the following code:

#include <mutex>
#include <thread>

int main ( ) {
    std::mutex myMutext;
    return 0;
}

I am expecting that include should work under c++11.

So here is how I compile it with: with GCC

g++ -std=c++11 -I/opt/local/include/gcc47/c++ -L/opt/local/lib/gcc47 main.cpp -o main

Compile successfully

with Clang

clang++ -std=c++11 -I/opt/local/include/gcc47/c++ -L/opt/local/lib/gcc47 main.cpp -o main

I am getting this error:

@work:boostTest$ clang++ -std=c++11 -I/opt/local/include/gcc47/c++ -L/opt/local/lib/gcc47 main.cpp -o main
In file included from main.cpp:1:
In file included from /opt/local/include/gcc47/c++/mutex:38:
In file included from /opt/local/include/gcc47/c++/tuple:37:
In file included from /opt/local/include/gcc47/c++/utility:70:
/opt/local/include/gcc47/c++/bits/stl_relops.h:72:3: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_VERSION'
  _GLIBCXX_BEGIN_NAMESPACE_VERSION
  ^
/opt/local/include/gcc47/c++/bits/stl_relops.h:86:5: error: expected unqualified-id
    template <class _Tp>
    ^
In file included from main.cpp:1:
In file included from /opt/local/include/gcc47/c++/mutex:38:
In file included from /opt/local/include/gcc47/c++/tuple:37:
In file included from /opt/local/include/gcc47/c++/utility:71:
In file included from /opt/local/include/gcc47/c++/bits/stl_pair.h:61:
/opt/local/include/gcc47/c++/bits/move.h:38:1: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_VERSION'
_GLIBCXX_BEGIN_NAMESPACE_VERSION
^
/opt/local/include/gcc47/c++/bits/move.h:45:3: error: expected unqualified-id
  template<typename _Tp>
  ^
In file included from main.cpp:1:
In file included from /opt/local/include/gcc47/c++/mutex:38:
In file included from /opt/local/include/gcc47/c++/tuple:37:
In file included from /opt/local/include/gcc47/c++/utility:71:
In file included from /opt/local/include/gcc47/c++/bits/stl_pair.h:61:
In file included from /opt/local/include/gcc47/c++/bits/move.h:57:
/opt/local/include/gcc47/c++/type_traits:41:1: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_VERSION'
_GLIBCXX_BEGIN_NAMESPACE_VERSION
^
/opt/local/include/gcc47/c++/type_traits:55:3: error: expected unqualified-id
  template<typename _Tp, _Tp __v>
  ^
/opt/local/include/gcc47/c++/type_traits:65:11: error: unknown type name 'integral_constant'
  typedef integral_constant<bool, true>     true_type;
          ^
/opt/local/include/gcc47/c++/type_traits:65:28: error: expected unqualified-id
  typedef integral_constant<bool, true>     true_type;
                           ^
/opt/local/include/gcc47/c++/type_traits:68:11: error: unknown type name 'integral_constant'
  typedef integral_constant<bool, false>    false_type;
          ^
/opt/local/include/gcc47/c++/type_traits:68:28: error: expected unqualified-id
  typedef integral_constant<bool, false>    false_type;
                           ^
/opt/local/include/gcc47/c++/type_traits:71:36: error: expected ';' after top level declarator
    constexpr _Tp integral_constant<_Tp, __v>::value;
                                   ^
/opt/local/include/gcc47/c++/type_traits:83:14: error: expected class name
    : public false_type
             ^
/opt/local/include/gcc47/c++/type_traits:106:14: error: expected class name
    : public true_type
             ^
/opt/local/include/gcc47/c++/type_traits:126:14: error: unknown template name 'integral_constant'
    : public integral_constant<bool, !_Pp::value>
             ^
/opt/local/include/gcc47/c++/type_traits:126:38: error: expected class name
    : public integral_constant<bool, !_Pp::value>
                                     ^
/opt/local/include/gcc47/c++/type_traits:142:14: error: expected class name
    : public false_type { };
             ^
/opt/local/include/gcc47/c++/type_traits:146:14: error: expected class name
    : public true_type { };
             ^
/opt/local/include/gcc47/c++/type_traits:151:14: error: unknown template name 'integral_constant'
    : public integral_constant<bool, (__is_void_helper<typename
             ^
/opt/local/include/gcc47/c++/type_traits:151:38: error: expected class name
    : public integral_constant<bool, (__is_void_helper<typename
                                     ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

I am using clang version:

Apple clang version 4.0 (tags/Apple/clang-418.2.41) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix

Am I doing something wrong? or is this a clang problem with latest gcc 4.7 libstc++?

回答1:

Why are you saying -I/opt/local/include/gcc47/c++ ?

That should not be necessary with either GCC or Clang, and will not work. Not all libstdc++ headers are under that path, there are some essential headers elsewhere that define things like _GLIBCXX_BEGIN_NAMESPACE_VERSION

It doesn't fail with GCC because GCC already knows how to find the other headers, so it's redundant to explicitly use -I and -L options. It doesn't work with Clang because you are only telling it how to find some of the headers it needs, but not telling it how to find the rest.

Stop trying to override the compiler's standard library paths, let it use the built-in paths it already knows about.



回答2:

I'm using clang-3.1 with gcc4.6 libstdc++ on FreeBSD 9.0/AMD64. It works with these options:

-I/usr/local/lib/gcc46/include/c++ \
-I/usr/local/lib/gcc46/include/c++/x86_64-portbld-freebsd9.0 \
-L/usr/local/lib/gcc46

I guess your problem may be solved to use these options:

-I/opt/local/include/gcc47/c++ \
-I/opt/local/include/gcc47/c++/x86_64-apple-darwin11.3.0 \
-L/opt/local/lib/gcc47


回答3:

You can use the special option -gcc-toolchain, which is implicitly set by --with-gcc-toolchain when you compile clang. It's a bit easier than recompile clang when you want to use another GCC libraries :)

Like that:

~/clang/trunk/bin/clang++ main.cc -gcc-toolchain ~/gcc/trunk -o main

Or, in your case (I know it's 4 years old :)) it seems to be

clang++ main.cpp -o main -gcc-toolchain /opt/local

The 'toolchain' folder should contain 'include' and 'lib' folders. Both compiler and linker use this option. Be careful: --gcc-toolchain is not a valid option, use one dash as the prefix (even though the llvm wiki states otherwise — I checked it on clang 3.8 trunk).