[Linux] Asutosh5941:
!!!! WARNING !!!!

-> This Article is for "Gentoo" or Gentoo-based linux users only..

-> Follow this article carefully otherwise u may break ur system completely, resulting in reinstallation of Gentoo

NOTE!! >>>

->This article will be updated always

-> Using clang instead of gcc isn't recommended but u can use clang if u follow this guide fully

-> Some packages fail with gcc and need clang to compile even if u don't need clang and vice versa (some packages even fail with clang)

Read Carefully -->>

Hello everyone !

First of all I apologize for any spelling mistakes made by me

This is a full guide to use clang as the default compiler for packages in ur pc with Gentoo linux installed

Make sure u read these manpages first >> make.conf , man make.conf and GCC Optimization

This articles says to use clang as the native compiler for ur system but not tells to completely replace gcc

Most of the linux distros use glibc which needs gcc and makes it impossible to use clang as the only compiler in the system i.e., u can't completely remove and replace gcc with clang

Some packages have gcc in their default config files which makes them break in using clang coz this makes the package to use clang with gcc (mixing compilers)

But..... There are still several packages which compile well with clang without any errors

Wait!! Why am I telling to use clang instead of gcc??

ans-> Clang is much faster than gcc and uses far less ram.. It has a special feature called thinlto which optimizes the package/app to provide more performance and uses much less ram than full lto or gcc lto..... gcc has no thinlto... Clang also uses lld as default linker which is much faster than gold/bfd..

For using clang we need to completely build our clang environment first and then properly setup

Below are the steps::

1) First of all, edit /etc/portage/make.conf file and set this :- USE="${USE} -clang -llvm"

2) Run "emerge -av clang llvm compiler-rt llvm-libunwind lld" to compile and install the clang toolchain with gcc first.. This isn't enough, don't use clang now in any case

3) Now make a dir named "env" in /etc/portage by running "mkdir -v /etc/portage/env"

4) Make a separate clang environment by running command "nano /etc/portage/env/compiler-clang" and add the following lines :

CC="clang"

CXX="clang++"

LD="ld.lld"

AR="llvm-ar"

NM="llvm-nm"

RANLIB="llvm-ranlib"

STRIP="llvm-strip"

OBJCOPY="llvm-objcopy"

OBJDUMP="llvm-objdump"

CFLAGS="-march=native -O2 -pipe"

CXXFLAGS="${CFLAGS} -stdlib=libstdc++"

LDFLAGS="-stdlib=libstdc++ -fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -Wl,-O2 -Wl,--as-needed"

or for thinlto

CC="clang"

CXX="clang++"

LD="ld.lld"

AR="llvm-ar"

NM="llvm-nm"

RANLIB="llvm-ranlib"

STRIP="llvm-strip"

OBJCOPY="llvm-objcopy"

OBJDUMP="llvm-objdump"

CFLAGS="-march=native -O2 -pipe -flto=thin"

CXXFLAGS="${CFLAGS} -stdlib=libstdc++ -flto=thin"

LDFLAGS="-stdlib=libstdc++ -fuse-ld=lld -rtlib=compiler-rt -unwindlib=libunwind -Wl,-O2 -Wl,--as-needed"

5) Edit /etc/portage/make.conf and add this -> USE="${USE} clang llvm default-compiler-rt default-lld llvm-libunwind -default-libcxx" ...

Note here we have added a few changes in USE flag: removed "-" present in-front of clang and llvm and also added "default-compiler-rt default-lld llvm-libunwind -default-libcxx"

Also here we putted a "-" in front of default-libcxx to prevent clang from using libc++ by default instead of libstdc++ as libc++ and libstdc++ aren't ABI compatible

Why dont use libc++??

ans-> As I previously said, most of linux distros use glibc and for which we can't remove gcc.. before installing clang u have gentoo installed on ur system with packages installed with gcc which uses libstdc++ by default

Here if u compile some packages with libc++, then they may not work untill u rebuild all gentoo linux packages with libc++ which is a lengthy and time consuming process.. So I don't recommend to use libc++.. Only use libstdc++

Let me give an example

Suppose u compiled package A with libstdc++ .. Now u are compiling package B which needs package A as dependency to work with libc++.. U will see that the installation may fail or be sucessful.. If sucessful, the package may not work properly as libc++ and libstdc++ aren't ABI compatible...

There are only two ways to fix this type of problem,

a) Compile package B with libstdc++ EASY

b) Compile package A and its dependencies with libc++ HARD

So use libstdc++

6) We have properly set our clang environment but the clang toolchain isn't completely built yet

If the clang toolchain is not properly bootstrapped then u may get lld linker errors

So its needed to build a proper clang toolchain

Make a file/edit /etc/portage/package.env and add these lines

sys-devel/llvm compiler-clang

sys-libs/libcxx compiler-clang

sys-libs/libcxxabi compiler-clang

sys-libs/compiler-rt compiler-clang

sys-libs/compiler-rt-sanitizers compiler-clang

sys-libs/llvm-libunwind compiler-clang

sys-devel/lld compiler-clang

sys-devel/clang compiler-clang

With these lines we are forcing packages listed here to compile using the separate clang environment we created in /etc/portage/env/compiler-clang rather than using default gcc compiler set in make.conf....

This means we will now recompile the whole clang toolchain using the clang compiler itself, making a proper clang toolchain..

7) Finally rebuild the whole clang toolchain with the command "emerge clang llvm libcxx libcxxabi compiler-rt llvm-libunwind lld"

8) Make a gcc fallback environment for packages failing with clang or for those which compulsory eed gcc in /etc/portage/env/compiler-gcc by adding these lines

CC="gcc"

CXX="g++"

LD="ld.bfd"

NM="gcc-nm"

AR="gcc-ar"

RANLIB="gcc-ranlib"

STRIP="strip"

OBJCOPY="objcopy"

OBJDUMP="objdump"

CFLAGS="-march=native -O2 -pipe"

CXXFLAGS="${CFLAGS}"

LDFLAGS="-Wl,-fuse-ld=bfd -Wl,-O2 -Wl,--as-needed"

9) Now edit /etc/portage/package.env and add these lines to prevent packages that compulsory need gcc from using clang

# Compulsory gcc needed

app-admin/eselect compiler-gcc

app-arch/bzip2 compiler-gcc

app-arch/gzip compiler-gcc

app-arch/xz-utils compiler-gcc

app-arch/tar compiler-gcc

app-shells/bash compiler-gcc

net-misc/rsync compiler-gcc

net-misc/wget compiler-gcc

sys-devel/autoconf compiler-gcc

sys-devel/automake compiler-gcc

sys-devel/libtool compiler-gcc

sys-apps/baselayout compiler-gcc

sys-apps/makedev compiler-gcc

sys-apps/coreutils compiler-gcc

sys-apps/diffutils compiler-gcc

sys-apps/file compiler-gcc

sys-apps/findutils compiler-gcc

sys-apps/gawk compiler-gcc

sys-apps/grep compiler-gcc

sys-apps/less compiler-gcc

sys-apps/net-tools compiler-gcc

sys-apps/portage compiler-gcc

sys-apps/sed compiler-gcc

sys-apps/shadow compiler-gcc

sys-devel/binutils compiler-gcc

sys-devel/bison compiler-gcc

sys-devel/flex compiler-gcc

sys-devel/gcc compiler-gcc

sys-devel/gettext compiler-gcc

sys-devel/gnuconfig compiler-gcc

sys-devel/make compiler-gcc

sys-devel/patch compiler-gcc

virtual/editor compiler-gcc

virtual/libc compiler-gcc

virtual/os-headers compiler-gcc

virtual/pkgconfig compiler-gcc

sys-apps/which compiler-gcc

DONE !!

Now we have a clean and proper clang environment

If u want to use clang system-wide, replace the envs like CC="" CXX="" LDFLAGS="" LD="",etc from /etc/portage/env/compiler-clang in /etc/portage/make.conf, otherwise put "package/name compiler-clang" in /etc/portage/package.env for those packages u need clang (if not using clang system-wide), e.g. dev-qt/qtwebengine compiler-clang

If u are using clang system-wide then some packages may fail to compile.. To fix this, put "package-name compiler-gcc" in /etc/portage/package.env to use the gcc fallback environment..

We are good to go now..

Enjoy Clang's fast compilation speed and less ram usage

U may ask does clang really use less ram?

ans-> Yes, when compiling qtwebengine with make -j6 using gcc, the ram usage was above 8gb

but with clang, ram usage was less than 5gb

I Hope This Guide Helps :)

EDIT 1: All The places where I used -march=native in CFLAGS/CXXFLAGS should be updated by urself according to ur processor specs... Please read the gcc-optimization article I pasted in the starting and put -march=specificcpu to optimize all packages according to ur processor... Also some packages don't support -march=native and need -march=specificcpu to work

EDIT 2: Using -O3 instead of -O2 in CFLAGS/CXXFLAGS isn't recommended unless u have a high end pc with atleast 16gb ram because, clang's "-O3" is an alias of "-O2 -flto" ... -flto enables full link time optimizations which will consume a lot ram during compilation.... If u still want to optimize ur applications more than "-O2", then I recommend u to use "-O2 -flto=thin" which will activate clang's thinlto instead of full lto and thinlto uses a few more ram compared to "-O2" but hugely less than full lto

EDIT 3: Some packages also fail to compile with lto .. If u face any package failure due to lto , then disable full lto or thinlto by removing "-flto=thin / -flto / -flto=full" from CFLAGS and CXXFLAGS

to be continued::::