3

你能(合理地)把 Fedora 21 带到它只有 llvm/clang/libc++/libc++abi 的地方吗?(我发现一些东西表明没有,但它们都大约 3 岁,从那时起 llvm/clang 已经走了很长一段路。)

通过全新安装,我尝试了

yum install gcc gcc-c++
(downloaded, built, installed llvm/cfe(clang)/compiler-rt/libcxx/libcxxabi from svn)
yum remove gcc gcc-c++
added to /etc/profile: export CC=/usr/local/bin/clang \ export CXX=/usr/local/bin/clang++
(in case of hard wiring)
ln -s /usr/local/bin/clang /usr/local/bin/gcc
ln -s /usr/local/bin/clang /usr/local/bin/cc
ln -s /usr/local/bin/clang++ /usr/local/bin/g++
ln -s /usr/local/bin/clang++ /usr/local/bin/c++
ldconfig

我很高兴,然后去建造一些东西,我得到了:

ld: cannot find crtbegin.o
ld: cannot find -lgcc
ld: cannot find -lgcc_s

clang -v 包括

Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2

ldconfig && ldconfig -p | grep libgcc 确实显示

libgcc_s.so.1 (libc6,x86-64) => /lib64/libgcc_s.so.1

/lib64 是 /usr/lib64 的符号链接。而且,/usr/lib64/libgcc_s.so.1 是 /usr/lib64/libgcc_s-4.9.2-20150212.so.1 的符号链接,它作为真实文件存在(92816 字节。)

所以,我不明白 ld 在 -lgcc_s 上的问题是什么。crtbegin 无处可寻,gcc (no _s) 无处可寻。

yum install libgcc 说它已经安装并且是最新版本,无事可做。

由于我已经安装了 clang 源构建,我可以重新构建 clang,这次使用 clang 而不是 gcc,以摆脱依赖关系?(也许然后“候选 GCC 安装”位就消失了。)

我可以强制 -stdlib=c++ 和 -lc++abi 为默认值,或者至少在没有 gcc 的情况下安装 libc++ 和 libc++abi 吗?

4

1 回答 1

2

花了一些时间试图让 clang 在没有 GCC 的情况下使用 libc++ 和 libc++abi,我发现这确实是可能的,即使考虑到 LLVM/clang 的当前状态有点问题。除了小型测试程序之外,我还能够构建 CMake 和其他一些用 C++ 编写的软件包,而无需安装 GCC,并且生成的二进制文件独立于 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 选项所示。此外,根据 ldd,在 FreeBSD 10.1 上,生成的二进制文件依赖于 libgcc。在以 dpkg 作为包管理器的 Ubuntu 上,文件

   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/了解更多信息。使用 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上的文章

于 2015-08-06T03:02:34.877 回答