Fedora 21 with clang, no gcc

Can you (reasonably) get Fedora 21 out there where it only has llvm / clang / libc ++ / libc ++ abi? (I found some things that don't indicate, but they were only 3 years old and llvm / clang has come a long way since then.)

With a fresh install, I tried

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

      

I was happy with everyone, then I went to build something, and I got:

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

      

clang -v includes

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

      

ldconfig && ldconfig -p | grep libgcc shows

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

      

And / lib64 is a symlink to / usr / lib 64. And, / usr / lib64 / libgcc_s.so.1 is a symlink to / usr / lib 64 / libgcc_s-4.9.2-20150212.so.1, which exists as real file (92,816 bytes.)

So, I don't understand what the problem is with ld on -lgcc_s. crtbegin was not found anywhere, and gcc (no _s) was not found anywhere.

yum install libgcc says it is already installed and the most recent version, nothing to do.

Since I have the clang source build installed, can I rebuild clang, this time using clang and not gcc, to get rid of the dependency? (Perhaps the "install GCC candidate" bit is gone.)

Can I force -stdlib = C ++ and -lC ++ abi by default, or at least install libc ++ and libc ++ abi without gcc?

+3


source to share


1 answer


After spending some time trying to get clang to work with libc ++ and libc ++ abi without GCC, I found that it is indeed possible, even if it is a bit problematic given the current state of LLVM / clang. In addition to some small test programs, I was able to create CMake and some other software packages written in C ++ without installing GCC, and with libstdC ++ independent binaries; they only depend on libc ++ / libc ++ abi according to the ldd output. Unfortunately I was unable to build clang with clang which was built using GCC. I have experimented on different Linux platforms (Fedora 21 32-bit, Amazon Linux 2015.3 (RPM) 64-bit, CentOS 7.1 64-bit and Ubuntu 14.04 64-bit).

Although it is possible to build software with clang using libC ++ / libC ++ abi without reliance on libstdC ++ and without the GCC compiler, a typical Linux installation is tied to libgcc and libstdC ++, so getting rid of them is impractical. Try to remove these two packages and you will see which part of the system depends on them. Even on FreeBSD 10.1, when clang is the default compiler and GCC is not installed, libgcc.a, libgcc_s.so, and a few crt * .o files are used when building the program, as shown by the -v option. Also, on FreeBSD 10.1, the resulting binaries depend on libgcc according to ldd. On Ubuntu, which has dpkg as its package manager, the files

   libgcc.a
   libgcc_s.so
   crtbegin.o
   crtbeginT.o
   crtbeginS.o
   crtendS.o
   crtend.o

      

are in the libgcc-devel package, while on an RPM based system like Fedora they are in the gcc package. Also, you might need these files, although I didn't need them for the code I was trying to create:

   crtfastmath.o
   crtprec32.o
   crtprec80.o
   crtprec64.o

      

So it could be argued that the above files are better owned by libgcc rather than gcc. As far as I can tell, the following must be done on an RPM based system before uninstalling the gcc package:

1) Create a symbolic link

libgcc_s.so -> libgcc_s.so.1

      

in any libgcc_s.so.1 directory.

2) Copy the crt * .o files listed above to this directory.

3) In the same directory create a symbolic link (libstdc ++. So.x should already be there, x is a number):

libstdc++.so -> libstdc++.so.x

      

You only need this if you are going to use libstdc ++; it is not necessary if you plan on using libc ++. On some systems libstdc ++, so it is a symbolic link to libstdc ++. so.x, owned by libstdc ++, is placed by the libstdc ++ - devel package in the GCC library directory, so you can delete that directory after uninstalling GCC and just create a symlink in the same directory as libstdc ++. so.x lives.

You should now be able to do the following:

1) Create a C program:



clang progname.c

      

2) Build a C ++ program using the libstdc ++ headers / libraries:

clang++ -I<location of headers> progname.cpp

      

On RPM based systems I've looked at, the libstdc ++ headers are part of the libstdc ++ - devel package, and their location can be found from rpm -ql in the package.

3) Build a C ++ program using libc ++ headers / libs:

clang++ -I/<location of headers> progname.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc -lgcc_s

      

The location of the headers is where they were set when LLVM + clang was created, etc.

See http://libcxx.llvm.org/ for more information . When building C ++ code using libc ++ / libc ++ abi you can use -stdlib = libc ++ instead of the -I flag, but in my testing that only works with clang built from source, not clang installed from repository (you can install clang from repo and use it to build libc ++ / libc ++ abi or you can use gcc to build libc ++ (abi) then uninstall gcc and use libraries with provided repo-clang ).

When configuring a software package to build it with clang + libc ++, you may need to install the following:

LIBS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
CXX=clang++
CXXFLAGS="-stdlib=libc++"
CC=clang

      

Note that in order to configure the CMake source to build it, I had to use a wrapper script like this:

#!/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

      

This can be useful for other purposes as well.

For more information see my article at http://www.omniprog.info/clang_no_gcc.html

+2


source







All Articles