Important: You are required to change your passwords used for Gentoo services and set an email address for your Wiki account if you haven't done so. See the full announcement and Wiki email policy change for more information.

Clang

From Gentoo Wiki
Jump to: navigation, search

sys-devel/clang is a compiler for C family of languages using LLVM as a backend and optimizer. It aims to be GCC compatible yet stricter.

Before using

Common notes

Please note that although clang tries to be compatible with gcc, not all packages build correctly with it. Although some of them simply fail to build, there are also cases when packages build fine but fail horribly when run.

The main place for looking up known failures with clang is bug #408963. If you hit one not reported on our Bugzilla already, please open a new bug report and make it block 408963.

If you'd like to try to build parts of your system with clang, the first good thing to do would be enabling tests via FEATURES=tests. Note that many developers actually don't care about their own tests, and thus you'll likely to get many false positives. Thus, you will probably need to compare the results with a gcc build.

Common issues

Use of GNU extensions without proper -std=

Some packages tend to use GNU extensions in their code without specifying -std= appropriately. GCC allows that usage, yet clang disables some of more specific GNU extensions by default.

If a particular package relies on such extensions being available, you will need to append the correct -std= flag to it:

  • -std=gnu89 for C89/C90 with GNU extensions,
  • -std=gnu99 for C99 with GNU extensions,
  • -std=gnu++98 for C++:1998 with GNU extensions.

A common symptom of this problem are multiple definitions of inline functions like this:

   /usr/bin/x86_64-pc-linux-gnu-ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add'
   /usr/bin/x86_64-pc-linux-gnu-ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
   /usr/bin/x86_64-pc-linux-gnu-ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add_1'
   /usr/bin/x86_64-pc-linux-gnu-ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
   /usr/bin/x86_64-pc-linux-gnu-ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_cmp'
   /usr/bin/x86_64-pc-linux-gnu-ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
   /usr/bin/x86_64-pc-linux-gnu-ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_sub'
   /usr/bin/x86_64-pc-linux-gnu-ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here

This is because clang uses C99 inline rules by default which do not work with gnu89 code. To work around it, you most likely have to pass -std=gnu89.

Using clang in Gentoo

Using clang with portage

Although Gentoo package tree is not designed to be used with compiler other than GCC, clang can be enforced on most of the packages through CC and CXX variables.

Please note, however, that many of Gentoo packages still don't build with clang and a few don't work correctly after being built. That's why we suggest using /etc/portage/env file to enable the use of clang per-package.

In order to do that, first create a new environment override to use:

File/etc/portage/env/clangEnvironment override named clang

CC=clang
CXX=clang++

Then you can enable use of clang for packages using /etc/portage/package.env file:

File/etc/portage/package.envEnabling clang for app-foo/bar and app-bar/baz

app-foo/bar clang
app-bar/baz clang

If you have app-portage/flaggie installed, the /etc/portage/package.env file could be modified using:

root # flaggie app-foo/bar app-bar/baz +clang

Enabling link-time optimizations

The link-time optimization feature defers optimizing the resulting executables to linking phase. This can result in better optimization of packages but is unsupported in Gentoo yet, and many packages simply fail to build.

When using LTO, clang compiles units into LLVM byte-code rather than machine code. In order to support linking such object files, the gold linker must be installed and set as the default linker, as it does support plugins.

Similarly, ar needs plugin support as well. Sadly, binutils ar doesn't support passing --plugin option before the actual command. Thus, we need to create a wrapper for it:

File/usr/local/bin/clang-arar wrapper for LLVM plugin

#!/bin/sh
firstarg=${1}
shift

exec /usr/bin/ar "${firstarg}" --plugin /usr/lib/llvm/LLVMgold.so "${@}"

If that's done, you can create a new environment override profile for LTO-enabled clang:

File/etc/portage/env/clang-ltoEnvironment override named clang-lto

CC='clang'
CXX='clang++'
CFLAGS="${CFLAGS} -O4"
CXXFLAGS="${CXXFLAGS} -O4"
LDFLAGS="${LDFLAGS} -O4 -Wl,-plugin,/usr/lib/llvm/LLVMgold.so"
AR='/usr/local/bin/clang-ar'
RANLIB=':'
NM='nm --plugin /usr/lib64/llvm/LLVMgold.so'

Note that the link-time optimizations were indirectly enabled here via -O4. If you don't want to enable other optimizations enforced by -O3, please use -flto instead. You need to also pass optimization flags when linking because that's where clang needs them.

You may also need to adjust the libdir path to plugin. Newer (live) versions of clang add `-plugin` when linking automatically, so `-Wl,-plugin`… is no longer necessary.

Using clang with distcc

In order to use clang on distcc client, additional symlinks have to be created in /usr/lib*/distcc/bin:

root # ln -s /usr/bin/distcc /usr/lib/distcc/bin/clang
root #
ln -s /usr/bin/distcc /usr/lib/distcc/bin/clang++