【问题标题】:When enabling C++11 with stdlibc++ 4.7, clang error out, while gcc compiles fine使用 stdlibc++ 4.7 启用 C++11 时,clang 错误,而 gcc 编译正常
【发布时间】:2012-05-05 16:41:00
【问题描述】:

我一直在尝试让 C++11 工作,在浏览了不同的网站和 Q/A 之后,我仍然遇到问题。我想在 libstdc++ 中使用 clang。在 clang 状态中表明它受补丁支持 - http://clang.llvm.org/libstdc++4.7-clang11.patch。我从 macports 下载 gcc4.7 并在 gcc4.7 的标题中进行了相应的更改

我不使用 libc++ 的原因是因为 libc++ 和 libstdc++ 之间的 ABI 兼容性,由该线程指示:Why can't clang with libc++ in c++0x mode link this boost::program_options example?

好的,一切都完成后,我用以下代码测试了我的设置:

#include <mutex>
#include <thread>

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

我希望包含应该在 c++11 下工作。

所以这是我编译它的方法: 与 GCC

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

编译成功

使用 Clang

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

我收到此错误:

@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.

我使用的是 clang 版本:

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

我做错了吗?或者这是最新的 gcc 4.7 libstc++ 的问题?

【问题讨论】:

  • 您明确地将-I-ing gcc-4.7 内部标头转换为clang 编译;我不希望这会明智地工作。
  • 如果我这样做:我也会看到错误。 @work:boostTest$ clang++ -std=c++11 -L/opt/local/lib/gcc47 main.cpp -o main main.cpp:1:10: 致命错误: 'mutex' file not found #include 产生 1 个错误。
  • 你试过传递 -std=c++11 -stdlib=libstdc++
  • 刚试过,结果一样。
  • 您使用的是哪个操作系统?在大多数操作系统上,Clang 应该能够自动找到 GCC 头文件。如果它不适用于您的操作系统,则应调整驱动程序逻辑。

标签: c++ macos gcc c++11 clang


【解决方案1】:

你为什么说-I/opt/local/include/gcc47/c++

这对于 GCC 或 Clang 都不是必需的,并且不会起作用。并非所有的 libstdc++ 头文件都在该路径下,其他地方有一些基本的头文件定义了 _GLIBCXX_BEGIN_NAMESPACE_VERSION

GCC 不会失败,因为 GCC 已经知道如何找到其他标头,因此显式使用 -I-L 选项是多余的。它不适用于 Clang,因为您只是告诉它如何找到它需要的一些标头,而不告诉它如何找到其余部分。

停止尝试覆盖编译器的标准库路径,让它使用它已经知道的内置路径。

【讨论】:

  • 我也有同样的问题。我们的问题是 Clang 使用系统的 GCC 作为其库和头文件。我们希望使用 GCC(来自 MacPorts 的)的独立安装作为 Clang 的基础。我们如何告诉 Clang 在别处寻找 GCC,它用于“标准库路径”的编译器是错误?! (对类似查询的响应,例如“安装 libc++”或“硬编码新路径并重新编译 clang”在这里将毫无用处。)
  • @CTMacUser,您需要重建 clang,使用 --with-gcc-toolchain 告诉它在哪里可以找到 GCC 头文件和库。您可能能够通过非常小心地使用大量-I-L 选项来覆盖现有安装的路径,但您需要覆盖所有相关路径.使用 gcc -v 编译以查看 GCC 使用的所有标准搜索目录,您还需要告诉 Clang 使用这些目录。即使那样它也可能不起作用(clang 在安装时设置了一些硬编码路径,我不知道它们是否可以被覆盖)
  • @JonathanWakely 设置环境变量CPLUS_INCLUDE_PATH(和CPATH)不起作用(而不是重建clang)?
  • @Walter,除非您还覆盖其库路径,否则不会。它也会有与使用-I/opt/local/include/gcc47/c++ 相同的问题,即并非所有标题都在该目录中,因此您必须了解所有相关目录并确保以正确的顺序提供它们。
  • @JonathanWakely 是的,但我会使用gcc -v -x c++ /dev/null -fsyntax-only 的输出来获取所需的所有包含路径。
【解决方案2】:

我在 FreeBSD 9.0/AMD64 上使用 clang-3.1 和 gcc4.6 libstdc++。它适用于以下选项:

-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/opt/local/include/gcc47/c++ \
-I/opt/local/include/gcc47/c++/x86_64-apple-darwin11.3.0 \
-L/opt/local/lib/gcc47

【讨论】:

    【解决方案3】:

    可以使用special option -gcc-toolchain,在编译clang时由--with-gcc-toolchain隐式设置。当你想使用另一个 GCC 库时,它比重新编译 clang 容易一点:)

    这样:

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

    或者,在你的情况下(我知道它已经 4 岁了:))它似乎是

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

    “toolchain”文件夹应包含“include”和“lib”文件夹。编译器和链接器都使用此选项。请注意:--gcc-toolchain 不是一个有效选项,请使用一个破折号作为前缀(尽管 llvm wiki 另有说明——我在 clang 3.8 主干上检查过)。

    【讨论】:

    • 复活一个旧线程告诉你这对我有多大帮助。我构建了每个 llvm 组件,却忘记添加 --gcc-toolchain 标志。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2018-12-06
    相关资源
    最近更新 更多