
Using Alternative Compilers in Gentoo with Intel Compiler Suite as an Example
In this article I want to talk about how to use a different compiler from gcc in Gentoo and other portage-based distributions for building packages.
The choice of alternative compilers is extensive: Intel Compiler Suite, Sun Studio Express Compilers, TenDRA C / C ++ Compiler, Tiny C Compiler and other lightweight compilers.
I will consider switching to the most popular (AFAIK) of alternative compilers - icc.
You may ask: why is this even necessary? The fact is that icc optimizes code for execution on Intel processors better than gcc.
Compare for yourself:
Agree, very good results.
Configuration of the computer on which the test was performed: Intel Core 2 Duo T7250 @ 2.00 GHz; linux 2.6.31-gentoo-r7 x86; gcc-4.4.2; icc-11.1.056; all tests were performed in the tmpfs section so as not to sin on the speed of i / o.
If you are ready, proceed with the installation.
icc requires a license for its work, we will use the free non-commercial option, which can be obtained here . When you get the .lic file, put it in / opt / intel / licenses.
I’ll immediately warn you that some applications are not built by icc, and some are built, but do not work, although icc developers are trying to make it as compatible with gcc as possible. Therefore, it cannot be said that the change of the compiler will be complete - something can be built only by gcc, and we will not refuse it. We have two options: compile all icc, and separate applications - gcc, or vice versa, leave the main gcc compiler, and icc only collect some programs. It is up to you to decide which one to choose - if you cannot afford to poke around the system for a long time, or simply do not want unnecessary problems, then for you, most likely, the second option is more acceptable; if you have enough free time and / or desire to try something new, then your option is the first.
We assume that the flags for icc in make.conf are defined as ICCCFLAGS and ICCCXXFLAGS (as CFLAGS and CXXFLAGS for gcc); The list of packages that gcc needs to build is in /etc/portage/package.gcc; special flags for individual packages are in /etc/portage/package.gcc-cflags and /etc/portage/package.icc-cflags.
The current compiler is defined in the OCC and OCXX environment variables - here we will change them.
To do this, create the script / etc / portage / bashrc with the following contents:
Similar to the previous case, only here is the list of packages collected by icc in /etc/portage/package.icc That's it! Your system is ready to collect packages with the new compiler.
One but bold. Noticeable acceleration of processor-intensive processes - (de) encoding audio / video, (de) encryption, etc.
1. Incomplete compatibility with gcc. Some programs are not built by icc, some are built, but do not work. For example, programs using the LZMA algorithm (xz-utils, p7zip) are collected, but they do not decompress the archives - they say they are beaten. I am sure that this is not the only example.
2. icc links executable files with its own libraries, and if for some reason you decide to remove it, then you will have to rebuild all the packages that it compiled.
3. icc is closed. For some, this is not a minus, but you must admit that the discovery of its source code would have done no harm (except Intel, of course).
I want to say that the transition to other compilers is no different in essence - in the script you just need to change icc to the selected compiler.
I hope you find this article useful.
PS Thanks gribozavr for invite!
The choice of alternative compilers is extensive: Intel Compiler Suite, Sun Studio Express Compilers, TenDRA C / C ++ Compiler, Tiny C Compiler and other lightweight compilers.
I will consider switching to the most popular (AFAIK) of alternative compilers - icc.
You may ask: why is this even necessary? The fact is that icc optimizes code for execution on Intel processors better than gcc.
Compare for yourself:
test program | bunzip2 linux-2.6.32.tar.bz2 | bzip2 linux-2.6.32.tar | oggenc -q5 testfile.wav | lame -V4 testfile.wav |
---|---|---|---|---|
average lead time (gcc) | 22.118 | 91.452 | 108.554 | 98.438 |
average lead time (icc) | 20.373 | 68.284 | 88.581 | 84.626 |
speed increase | 8.5% | 33.9% | 22.5% | 16.3% |
Agree, very good results.
Configuration of the computer on which the test was performed: Intel Core 2 Duo T7250 @ 2.00 GHz; linux 2.6.31-gentoo-r7 x86; gcc-4.4.2; icc-11.1.056; all tests were performed in the tmpfs section so as not to sin on the speed of i / o.
Installation
If you are ready, proceed with the installation.
# emerge icc
icc requires a license for its work, we will use the free non-commercial option, which can be obtained here . When you get the .lic file, put it in / opt / intel / licenses.
Portage setup
I’ll immediately warn you that some applications are not built by icc, and some are built, but do not work, although icc developers are trying to make it as compatible with gcc as possible. Therefore, it cannot be said that the change of the compiler will be complete - something can be built only by gcc, and we will not refuse it. We have two options: compile all icc, and separate applications - gcc, or vice versa, leave the main gcc compiler, and icc only collect some programs. It is up to you to decide which one to choose - if you cannot afford to poke around the system for a long time, or simply do not want unnecessary problems, then for you, most likely, the second option is more acceptable; if you have enough free time and / or desire to try something new, then your option is the first.
First option: main compiler - icc, additional - gcc
We assume that the flags for icc in make.conf are defined as ICCCFLAGS and ICCCXXFLAGS (as CFLAGS and CXXFLAGS for gcc); The list of packages that gcc needs to build is in /etc/portage/package.gcc; special flags for individual packages are in /etc/portage/package.gcc-cflags and /etc/portage/package.icc-cflags.
The current compiler is defined in the OCC and OCXX environment variables - here we will change them.
To do this, create the script / etc / portage / bashrc with the following contents:
export GCC=${OCC} # сохраним старое значение переменных
export GCXX=${OCXX}
export OCC="icc" # меняем компилятор
export OCXX="icpc"
export GCCCFLAGS=${CFLAGS} # сохраним старые флаги
export GCCCXXFLAGS=${CXXFLAGS}
export CFLAGS=${ICCCFLAGS} # меняем флаги
export CXXFLAGS=${ICCCXXFLAGS}
[ -r ${ROOT}/etc/portage/package.gcc ] || return 0
while read -a target; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then # если текущий пакет указан в /etc/portage/package.gcc, то
export OCC="${GCC}" # возвращаем старый компилятор
export OCXX="${GCXX}"
export CFLAGS="${GCCCFLAGS}" # и флаги для него
export CXXFLAGS="${GCCCXXFLAGS}"
if [ -r ${ROOT}/etc/portage/package.gcc-cflags ]; then # а если еще и в /etc/portage/package.gcc-cflags, то
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags" # добавим еще флаги
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.gcc-cflags
fi
return 0
fi
done < ${ROOT}/etc/portage/package.gcc
if [ -r ${ROOT}/etc/portage/package.icc-cflags ]; then # аналогично для icc
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags"
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.icc-cflags
fi
export CC_FOR_BUILD="${OCC}" # маленький workaround
unset GCC
unset GCXX
unset GCCCFLAGS
unset GCCCXXFLAGS
The second option: the main compiler is gcc, the secondary is icc
Similar to the previous case, only here is the list of packages collected by icc in /etc/portage/package.icc That's it! Your system is ready to collect packages with the new compiler.
[ -r ${ROOT}/etc/portage/package.icc ] || return 0
while read -a target; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then # если текущий пакет указан в /etc/portage/package.icc, то
export OCC="icc" # меняем компилятор
export OCXX="icpc"
export CFLAGS="${ICCCFLAGS}" # и флаги для него
export CXXFLAGS="${ICCCXXFLAGS}"
if [ -r ${ROOT}/etc/portage/package.icc-cflags ]; then # а если еще и в /etc/portage/package.icc-cflags, то
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags" # добавим еще флаги
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.icc-cflags
fi
export CC_FOR_BUILD="${OCC}" # маленький workaround
return 0
fi
done < ${ROOT}/etc/portage/package.icc
if [ -r ${ROOT}/etc/portage/package.gcc-cflags ]; then # аналогично для gcc
while read target flags; do
if [ "${target}" = "${CATEGORY}/${PN}" ]; then
export CFLAGS="$CFLAGS $flags"
export CXXFLAGS="$CXXFLAGS $flags"
break
fi
done < ${ROOT}/etc/portage/package.gcc-cflags
fi
fi
Pros and cons
A plus
One but bold. Noticeable acceleration of processor-intensive processes - (de) encoding audio / video, (de) encryption, etc.
Minuses
1. Incomplete compatibility with gcc. Some programs are not built by icc, some are built, but do not work. For example, programs using the LZMA algorithm (xz-utils, p7zip) are collected, but they do not decompress the archives - they say they are beaten. I am sure that this is not the only example.
2. icc links executable files with its own libraries, and if for some reason you decide to remove it, then you will have to rebuild all the packages that it compiled.
3. icc is closed. For some, this is not a minus, but you must admit that the discovery of its source code would have done no harm (except Intel, of course).
Conclusion
I want to say that the transition to other compilers is no different in essence - in the script you just need to change icc to the selected compiler.
I hope you find this article useful.
PS Thanks gribozavr for invite!