花了一些时间尝试让 clang 在没有 GCC 的情况下与 libc++ 和 libc++abi 一起工作,我发现这确实是可能的,即使考虑到 LLVM/clang 的当前状态有点问题。除了小型测试程序之外,我还能够在未安装 GCC 的情况下构建 CMake 和其他一些用 C++ 编写的软件包,并且生成的二进制文件独立于 libstdc++;根据 ldd 输出,它们仅依赖于 libc++/libc++abi。不幸的是,我无法使用使用 GCC 构建的 clang 来构建 clang 本身。我一直在不同的 Linux 平台上进行实验(Fedora 21 32 位、Amazon Linux 版本 2015.3(基于 RPM)64 位、CentOS 7.1 64 位和 Ubuntu 14.04 64 位)。
尽管可以使用 libc++/libc++abi 通过 clang 构建软件,而不依赖于 libstdc++ 并且不存在 GCC 编译器,但典型的 Linux 安装与 libgcc 和 libstdc++ 紧密相关,以至于摆脱它们是不切实际的。尝试删除这两个包,您将看到系统有多少依赖于它们。即使在 FreeBSD 10.1 上,clang 是默认编译器且未安装 GCC,在构建程序时也会使用 libgcc.a、libgcc_s.so 和一些 crt*.o 文件,如 -v 选项所示。另外,在 FreeBSD 10.1 上,根据 ldd,生成的二进制文件依赖于 libgcc。在 Ubuntu 上,它使用 dpkg 作为包管理器,这些文件
libgcc.a
libgcc_s.so
crtbegin.o
crtbeginT.o
crtbeginS.o
crtendS.o
crtend.o
位于 libgcc-devel 软件包中,而在基于 RPM 的系统(例如 Fedora)上,它们位于 gcc 软件包中。此外,您可能需要这些文件,即使我尝试构建的代码不需要它们:
crtfastmath.o
crtprec32.o
crtprec80.o
crtprec64.o
因此,有人可能会争辩说,上述文件最好属于 libgcc,而不是 gcc。据我所知,在删除 gcc 软件包之前,需要在基于 RPM 的系统上完成以下操作:
1)创建符号链接
libgcc_s.so -> libgcc_s.so.1
在 libgcc_s.so.1 所在的任何目录中。
2) 将上面列出的 crt*.o 文件复制到该目录。
3) 在同一目录中创建符号链接(libstdc++.so.x 应该已经存在;x 是一个数字):
libstdc++.so -> libstdc++.so.x
仅当您要使用 libstdc++ 时才需要这个;如果您只打算使用 libc++,则不需要这样做。一些
系统 libstdc++.so 是属于 libstdc++ 软件包的 libstdc++.so.x 的符号链接,由 libstdc++-devel 软件包放置到 GCC 库目录中,因此您可以在卸载 GCC 后删除该目录,然后在中创建符号链接libstdc++.so.x 所在的同一目录。
现在您应该能够执行以下操作:
1)构建C程序:
clang progname.c
2) 使用 libstdc++ 头文件/库构建 C++ 程序:
clang++ -I<location of headers> progname.cpp
在我看过的基于 RPM 的系统上,libstdc++ 标头是 libstdc++-devel 包的一部分,可以从包上的 rpm -ql 找到它们的位置。
3) 使用 libc++ 头文件/库构建 C++ 程序:
clang++ -I/<location of headers> progname.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc -lgcc_s
标头的位置是您构建 LLVM+clang 等时安装的位置。
请参见http://libcxx.llvm.org/ http://libcxx.llvm.org/获取更多信息。当使用 libc++/libc++abi 构建 C++ 代码时,您可以使用 -stdlib=libc++ 而不是 -I 标志,但在我的测试中,它仅适用于从源代码构建的 clang,不适用于从存储库安装的 clang(您可以安装从 repo 中下载 clang 并使用它来构建 libc++/libc++abi;或者您可以使用 gcc 来构建 libc++(abi),然后删除 gcc 并将库与 repo 提供的 clang 一起使用)。
当配置软件包以使用 clang + libc++ 构建它时,您可能需要设置以下内容:
LIBS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
CXX=clang++
CXXFLAGS="-stdlib=libc++"
CC=clang
请注意,要配置 CMake 源以构建它,我必须使用如下包装脚本:
#!/bin/bash
MYLFLAGS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
# Catch the case when we only want to compile; this helps us avoid some warnings:
if echo "$@" | egrep "(^-c | -c | -c$)" >/dev/null 2>&1; then
MYLFLAGS=""
fi
/usr/local/bin/clang++ -stdlib=libc++ "$@" $MYLFLAGS
它也可能对其他目的有用。
欲了解更多信息,请参阅我的文章:http://www.omniprog.info/clang_no_gcc.html http://www.omniprog.info/clang_no_gcc.html