Clang
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.
Contents
- 1Before using
- 1.1Common notes
- 1.2Common issues
- 1.2.1Use of GNU extensions without proper -std=
- 2Using clang in Gentoo
- 2.1Using clang with portage
- 2.2Enabling link-time optimizations
- 2.3Using clang with distcc
- 2.4Using clang with ccache
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 butfail 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 viaFEATURES=tests. Note that many developers don't actually care about their own tests, and as a result you are likely to get many false positives. Because of this, you may 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 throughCC 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:
CC=clang CXX=clang++
Then you can enable use of clang for packages using /etc/portage/package.env file:
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, thegold 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:
#!/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:
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++
Using clang with ccache
Automatic with `>=ccache-3.9-r3`, when `clang` is already installed at emerge time.
- Core system