AUTHOR:	Robert Connolly <robert at linuxfromscratch dot org> (ashes)
	Daniel Baumann <daniel.baumann at panthera-systems.net>

DATE: 2006-11-06

LICENSE: GNU General Public License

SYNOPSIS: Installing and using the Intel C/C++ compiler with LFS.

PRIMARY URL:
http://www.linuxfromscratch.org/hints/downloads/files/intel-c-compiler.txt

DESCRIPTION:
The Intel C/C++ compiler collection (ICC) is a full featured compiler and
debugger suite, which is close to compatible with the GNU C/C++ compiler
collection (GCC). ICC is made only for Intel chips and takes advantage of
Intel technology, such as Hyper-Threading, more than GCC does. Software
compiled with ICC usually performs better than if it were compiled with GCC.
The performance difference can range between 2% and 40% depending on the
software and compiler flags. Most of the LFS base system will compile with ICC.

The Intel compiler is not opensource. A non-commercial Linux user license is
available for application developers. This license does not expire but only
entitles you to upgrades for one year (you may be able to renew the license).

A commercial license allows you to distribute packages you built with ICC,
and costs up to $400. Discounts are available for students.

If you are using ICC for personal use, to help develop ICC, the non-commercial
application developer license is right for you.

There is a PDF document describing ICC-9.0 here:
http://cache-www.intel.com/cd/00/00/22/23/222301_222301.pdf

PREREQUISITES:
- An Intel CPU (Intel-clones may not work).

- The Intel website says a PentiumII with 256MB of RAM is required to use
  ICC-9.1.

- Glibc (icc is linked to /lib/ld-linux.so.2).

- 4GB of free space, above the LFS requirement, to be able to build DB, Bash,
  and Perl with code profiling (they will be normal size when installed).

- This hint is for i86, but could be adapted for other Intel platforms.

HINT:
The homepage for the Intel compiler (application developer license) is here:
http://www.intel.com/cd/software/products/asmo-na/eng/compilers/clin/219856.htm

The ICC-9.1 compiler is compatible with gcc-4.1 and supports the newest Intel
CPU's.

To obtain the Intel compiler, and user license, go to the homepage and
register. You should receive an email with a URL for the ICC tarball, and a
user license attachment.

After that you should have two files (the versions may be different):

l_cc_c_9.1.042.tar.gz (279MB)
and
NCOM_L_CMP_CPP_NZDM-FT472MJ3.lic

*****************
Table of contents
*****************
	- Installing ICC
		Installing ICC files
		Configuring ICC files
		Configuring system files
	- Optimizations
	- Building LFS packages

# ***************************************
# - INSTALLING ICC - Installing ICC files
# ***************************************

# The rpm packages for ICC are designed to install ICC to /opt. This is
# convienient because ICC headers can overwrite libc headers, but is
# inconvienient because software built with ICC will be linked to /opt. I don't
# like /opt because I think it's redundent. So this hint installs ICC to /usr,
# and configures ICC to use private header directories so that ICC will not
# overwrite headers from other packages. Installing ICC to /usr is also
# compatible with any use, whether you want to use ICC for specific software,
# or use ICC to build most of LFS.

# ICC does not currently build Glibc, so ICC must be installed after Glibc,
# Binutils, and GCC, are installed in the chapter 6 chroot.

# As a general rule, always apply GCC4 patches for packages if available.

# We need Cpio to unpack the ICC rpm packages. Cpio can be compiled in the
# chapter 6 chroot after Binutils. Follow the BLFS instructions:
# http://www.linuxfromscratch.org/blfs/view/svn/general/cpio.html
# You can rebuild Cpio with ICC later if you want.

# We also need the rpm2cpio script:
# http://www.rpm.org/tools/scripts/rpm2cpio.sh

# Install rpm2cpio to /usr:

install -v rpm2cpio.sh /usr/bin/rpm2cpio

# Set your ICC package version in the shell environment (you may need to
# modify the values for your version). This is done so that the rest of the
# commands in this hint can be copied and pasted:

export ICC_V_MAJOR=9
export ICC_V_MINOR=1
export ICC_V_PATCH=042
export ICC_VERSION="${ICC_V_MAJOR}.${ICC_V_MINOR}.${ICC_V_PATCH}"

# Unpack the Intel CC tarball and change to the data/ directory:

tar zxvf l_cc_c_${ICC_VERSION}.tar.gz &&
cd l_cc_c_${ICC_VERSION}/data/

# Extract the rpm file for the C/C++ compiler:

rpm2cpio intel-icc?????-${ICC_VERSION}*.i386.rpm | \
	cpio --make-directories --extract --verbose &&
rm -vf opt/intel/cc/${ICC_VERSION}/bin/uninstall.sh &&
chown -vR 0:0 opt/

# Copy the files to /usr:

install -vd /usr/share/doc/icc-${ICC_VERSION} &&
mv -v opt/intel/cc/${ICC_VERSION}/doc /usr/share/doc/icc-${ICC_VERSION} &&
mv -v opt/intel/cc/${ICC_VERSION}/licenses /usr/share/doc/icc-${ICC_VERSION} &&
mv -v opt/intel/cc/${ICC_VERSION}/man/man1/* /usr/share/man/man1 &&
install -vd /usr/include/icc/ &&
mv -v opt/intel/cc/${ICC_VERSION}/include/* /usr/include/icc

# The iccvars.*sh files are shell startup/profile files, and belong in /etc:

mv -v opt/intel/cc/${ICC_VERSION}/bin/iccvars.*sh /etc &&
mv -v opt/intel/cc/${ICC_VERSION}/bin/* /usr/bin

# Runtime libraries should be installed to /lib:

mv -v opt/intel/cc/${ICC_VERSION}/lib/libirc.so /lib &&
mv -v opt/intel/cc/${ICC_VERSION}/lib/libsvml.so /lib &&
mv -v opt/intel/cc/${ICC_VERSION}/lib/libimf.so /lib

# The rest of the libraries can go in /usr/lib:

mv -v opt/intel/cc/${ICC_VERSION}/lib/locale /usr/lib/locale &&
mv -v opt/intel/cc/${ICC_VERSION}/lib/* /usr/lib &&
rm -rf opt/

# Extract the rpm and tar files for the ICC headers:

rpm2cpio intel-isubh*-${ICC_VERSION}*.i386.rpm \
	| cpio --make-directories --extract --verbose &&
tar -zvxf opt/intel/cc/${ICC_VERSION}/substitute_headers/libio.tar.gz -C \
	opt/intel/cc/${ICC_VERSION}/substitute_headers/ &&
chown -vR 0:0 opt/ &&
find opt/intel/cc/${ICC_VERSION}/substitute_headers/libio -type d \
	-exec chmod -v 755 {} \; &&
find opt/intel/cc/${ICC_VERSION}/substitute_headers/libio -type f \
	-exec chmod -v 644 {} \;

# Install the ICC headers:

mv -v opt/intel/cc/${ICC_VERSION}/substitute_headers/libio/* \
	/usr/include/icc &&
rm -rf opt/

# Extract the rpm for the debugger:

rpm2cpio intel-iidb*-${ICC_VERSION}*.i386.rpm | \
	cpio --make-directories --extract --verbose &&
rm -vf opt/intel/idb/${ICC_VERSION}/bin/uninstall.sh
chown -vR 0:0 opt/

# Install the ICC debugger, idbvars.sh belongs in /etc:

mv -v opt/intel/idb/${ICC_VERSION}/bin/idbvars.*sh /etc &&
mv -v opt/intel/idb/${ICC_VERSION}/bin/* /usr/bin &&
mv -v opt/intel/idb/${ICC_VERSION}/doc /usr/share/doc/idb-${ICC_VERSION} &&
mv -v opt/intel/idb/${ICC_VERSION}/man/man1/* /usr/share/man/man1 &&
rm -rf opt/

# ****************************************
# - INSTALLING ICC - Configuring ICC files
# ****************************************

# The compiler suite is installed. Now we set it up. First install the
# license file:

install -v -m444 *.lic /usr/share/doc/icc-${ICC_VERSION}/licenses/

# Configure the compiler:

sed -e \
"s/<installpackageid>/l_cc_c_${ICC_V_MAJOR}\.${ICC_V_MINOR}\.${ICC_V_PATCH}/" \
	-i /usr/share/doc/icc-${ICC_VERSION}/doc/csupport

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/lib/\/usr\/lib/g' -i /usr/bin/icc

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/lib/\/usr\/lib/g' -i /usr/bin/icpc

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/lib/\/usr\/lib/g' \
	-e 's/<INSTALLDIR>\/man/\/usr\/share\/man/g' -i /etc/iccvars.csh

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/lib/\/usr\/lib/g' \
	-e 's/<INSTALLDIR>\/man/\/usr\/share\/man/g' -i /etc/iccvars.sh

source /etc/iccvars.sh

# If you get "bash: manpath: command not found", don't worry about it.

# Configure the Intel debugger:

sed -e \
"s/<installpackageid>/l_cc_c_${ICC_V_MAJOR}\.${ICC_V_MINOR}\.${ICC_V_PATCH}/" \
	-i /usr/share/doc/idb-${ICC_VERSION}/idbsupport

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/man/\/usr\/share\/man/g' -i /etc/idbvars.csh

sed -e \
"s/<INSTALLDIR>\/licenses/\/usr\/share\/doc\/icc-${ICC_VERSION}\/licenses/g" \
	-e 's/<INSTALLDIR>\/bin/\/usr\/bin/g' \
	-e 's/<INSTALLDIR>\/man/\/usr\/share\/man/g' -i /etc/idbvars.sh

source /etc/idbvars.sh

# - INSTALLING ICC - Configuring system files:

# ICC links programs to libgcc_s.so. On an LFS system libgcc_s.so is in
# /usr/lib. On some systems libgcc_s.so is in /lib. If you plan to install
# software built with ICC to /bin or /sbin, you should move libgcc_s.so to
# /lib if it is not already there (this is recommended):

mv -v /usr/lib/libgcc_s.so.1 /lib/ &&
rm -v /usr/lib/libgcc_s.so &&
ln -vs libgcc_s.so.1 /lib/libgcc_s.so

# We also need to tell ICC where to find the headers we installed to
# /usr/include/icc:

echo "-I/usr/include/icc" >> /usr/bin/icc.cfg
echo "-I/usr/include/icc" >> /usr/bin/icpc.cfg
echo "-I/usr/include/icc/c++" >> /usr/bin/icpc.cfg

# Now we can use the Intel compiler.

# Test ICC to see that it is working:

echo "int main () {return 0;}" > /tmp/main.c &&
icc -o /tmp/main /tmp/main.c &&
/tmp/main &&
rm /tmp/main{,.c}

# If there are no errors then it worked.

# You can unset these now:

unset ICC_VERSION ICC_V_MAJOR ICC_V_MINOR ICC_V_PATCH

# Now we can configure the system to use ICC.

# Configure a GNU autoconf site file for ICC. This makes this hint shorter,
# and our lives easier. GNU ./configure scripts will search for
# "${prefix}/share/config.site" and use it to source environment variables.
# Alternately you can put, and name, the "config.site" anywhere and set
# the CONFIG_SITE environment variable to point to it:

cat > /usr/share/config.site-icc << "EOF"
CC="icc"
CXX="icpc"
LD="xild"
AR="xiar"
LANG="en"
LANGUAGE="en"
LC_ALL="C"
EOF

# If you want to build most of your LFS system with ICC you should export
# this site configuration:

export CONFIG_SITE="/usr/share/config.site-icc"

# If you only want to use ICC for specific packages then you can use this:

env CONFIG_SITE="/usr/share/config.site-icc" ./configure...

# ***************
# - Optimizations
# ***************

# Now you can read the ICC man pages for more information about its features
# and usage.

# You should also look at:
# http://gentoo-wiki.com/HOWTO_ICC_and_Portage#CFLAGS

# and:
# http://sc.tamu.edu/help/intel/9.0/main_cls/mergedProjects/optaps_cls/whnjs.htm

# I scribbled some notes while reading the ICC man page, and posted them here:
# http://www.linuxfromscratch.org/~robert/new/icc-cflag-notes.txt

# We can add our optimizations to the ICC config file. This is what I use for
# my Prescott:

# The -xP optimization is just like GCC's -march=prescott:

echo "-xP" >> /usr/bin/icc.cfg
echo "-xP" >> /usr/bin/icpc.cfg

# Note that -axP is just like '-march=i586 -mtune=prescott'.

# The -fomit-frame-pointer optimization removes frame pointers from object
# code, and makes it perform better. Note that this option makes programs
# harder to debug:

echo "-fomit-frame-pointer" >> /usr/bin/icc.cfg
echo "-fomit-frame-pointer" >> /usr/bin/icpc.cfg

# The -mno-ieee-fp optimization disables floating-point precision. This breaks
# ANSI conformance but increases performance. This can break some software,
# if it does then add -mp to CFLAGS. Note that this option makes programs
# harder to debug:

echo "-mno-ieee-fp" >> /usr/bin/icc.cfg
echo "-mno-ieee-fp" >> /usr/bin/icpc.cfg

# The -no-prec-div optimization disables floating-point division computations.
# Note that the man page entry for this option is not completely correct,
# check google for this option. Note that this option makes programs harder
# to debug:

echo "-no-prec-div" >> /usr/bin/icc.cfg
echo "-no-prec-div" >> /usr/bin/icpc.cfg

# The -rcd enabled fast float-to-int conversions. This option breaks ANSI
# conformance:

echo "-rcd" >> /usr/bin/icc.cfg
echo "-rcd" >> /usr/bin/icpc.cfg

# This option tells ICC which GCC version to be compatable with:

echo "-gcc-version=410" >> /usr/bin/icc.cfg
echo "-gcc-version=410" >> /usr/bin/icpc.cfg

# Use -no-gcc to break GCC compatability. This will perform better, and some
# packages will need this. Libraries compiled with ICC should get -gcc
# added to CFLAGS, so that programs compiled with GCC can use the libraries
# compiled with ICC. I will provide commands to add -gcc to LFS packages,
# but you need to keep this in mind with BLFS packages:

echo "-no-gcc" >> /usr/bin/icc.cfg
echo "-no-gcc" >> /usr/bin/icpc.cfg

# Software-based Speculative Pre-computation (-ssp) performs thread based
# prefetching and takes advantage of hyper-threading. This option increases
# performance signicicantly. See google for more information. This option
# should not go together with -prof_gen, but -prof_use is okay. It might
# depend on profrun. This is 5 stage profiling:

-prof-gen
./a.out
-prof-gen-sampling -prof-use
profrun -dcache ./a.out
-prof-use -ssp

# The newer Pentium4 cpus perform Hardware-based Speculative Pre-computation,
# so I have never tried to use the -ssp option.

# The -ansi-alias optimization will add additional optimizations but must
# only be used if the package adheres to the ISO C Standard. The -strict-ansi
# option should be used with -ansi-alias, to make sure the source comforms
# to ansi.

# Interprocedural optimizations (-ipo) is a fantastic feature which optimizes
# code at link time, including expanding inline functions across multiple
# files. This is equivilent to combining all the source code into a single
# file. This allows the compiler to make better judgements. This option can
# be very particular and error prone (at compile time).

# The -ipo option can take an integer argument to specify the limit of output
# files it can generate. By default the limit is 1. -ipo0 will allow the
# compiler to decide how many object files to create depending on their size.

# The -Ob2 optimization adds -ip, a subset of -ipo but for single file
# compilation, and inlines functions at the compiler's descretion. This
# option can be used with all code.

# -Ob2, -ip, and -ipo can not be used during profile generation (see below)
# and will cause a compiler warning if we try. If you decide not to profile
# your packages then you can add -ipo0 or -Ob2 to the icc.cfg and icpc.cfg
# files. Using -ipo0 on the command line will supersede -ip and -Ob2 in
# icc.cfg. If you do not plan to use profiling then you can add -ipo0 to the
# icc.cfg and icpc.cfg files.

# The -fast option enables "-O3 -ipo -static -no-prec-div -xP". Make sure
# your cpu works with the -xP (pentium4 sse3) optimization before using -fast.
# Because this optimization statically links programs I do not suggest building
# most packages with it. Statically linked programs do not share virtual
# memory, and will eventually consume all memory when most of the system is
# statically linked. I do suggest using -fast with programs which are freed
# from memory quickly and are not run often, like Bzip2.

# The -ipo option does not work with private static libraries, which most
# packages have. So -ipo has to be surgically added.

# In ICC the -g option will disable the default -O2 optimization, unless
# -O1/-O2/-O3 are used on the command line. Setting CFLAGS in the environment
# will remove the -g option from most packages.

# Packages configured with Libtool add the --with-pic configure switch. This
# switch will build both shared and static libraries with -fPIC. We can take
# advantage of this by adding -gcc beside -fPIC so that -gcc will only be
# added to libraries, and not the programs. There is a disadvantage too.
# Static libraries compiled with -fPIC will perform slightly slower, however
# in LFS we link almost everything dynamically, so this should not become an
# issue. In this hint I will provide instructions to add -gcc beside -fPIC
# to make shared libraries GCC compatable, but not the static libraries. If
# the static libraries cause issues for you, you should rebuild the package
# with --with-pic. This way if you compile programs statically with ICC they
# will perform as well as possible.

# Profile-guided optimizations works by first compiling a program, or library,
# with profile generation (-prof_gen). When that program is executed it will
# generate data files with details about how the program works at runtime,
# such as which functions are called the most and how they relate to other
# functions. Then the program is recompiled to use the profiling data with
# -prof_use. This means compiling the package twice, but also means the
# installed package will perform as well as possible. You do not have to do
# this, but I do. If you choose not to profile your packages you can skip
# much of the rest of this hint and simply use the config.site file as-is.

# Rather than resetting our CFLAGS twice for every profiled package, it's
# easier to use a script. Some packages use 'libtool' to build packages,
# and using 'make CC="icc -prof_gen"' for these packages will not work. When
# profiling packages I suggest reconfiguring them. Also, some packages do not
# use CFLAGS/CXXFLAGS for all components because the package developer may
# not want particular parts of the programs optimized. So it is best to modify
# the CC/CXX environment variables, instead of CFLAGS/CXXFLAGS, when using
# -prof_gen and -prof_use.

# The following commands will add the profiling options to a few scripts,
# including additional optimizations when profile data is being used:

cat > /usr/bin/prof_gen-env << "EOF"
unset CONFIG_SITE
export LANG="en"
export LANGUAGE="en"
export LC_ALL="C"
export LD="xild"
export AR="xiar"
export CFLAGS="-O2"
export CXXFLAGS="-O2"
export CC="icc -prof_gen -prof_dir=$(pwd)"
export CXX="icpc -prof_gen -prof_dir=$(pwd)"
"$@"
EOF
chmod -v +x /usr/bin/prof_gen-env

cat > /usr/bin/prof_use-env << "EOF"
unset CONFIG_SITE
export LANG="en"
export LANGUAGE="en"
export LC_ALL="C"
export LD="xild"
export AR="xiar"
export CFLAGS="-O2 -ipo0"
export CXXFLAGS="-O2 -ipo0"
export CC="icc -prof_use -prof_dir=$(pwd)"
export CXX="icpc -prof_use -prof_dir=$(pwd)"
nice -n 19 "$@"
EOF
chmod -v +x /usr/bin/prof_use-env

cat > /usr/bin/prof_use-fast-env << "EOF"
unset CONFIG_SITE
export LANG="en"
export LANGUAGE="en"
export LC_ALL="C"
export LD="xild"
export AR="xiar"
export CFLAGS="-O3 -fast -ipo0"
export CXXFLAGS="-O3 -fast -ipo0"
export CC="icc -prof_use -prof_dir=$(pwd)"
export CXX="icpc -prof_use -prof_dir=$(pwd)"
nice -n 19 "$@"
EOF
chmod -v +x /usr/bin/prof_use-fast-env

# For some reason most GNU ./configure scripts do not pass environment set
# AR to Makefile. We need to use Intel's AR, not GNU's. So we need to create
# a 'make' wrapper script which will always override the AR variable. I added
# LD for good measure:

cat > /usr/bin/icc-make << "EOF"
nice make AR="xiar" LD="xild" "$@"
EOF
chmod -v +x /usr/bin/icc-make

# Use 'icc-make' instead of 'make' whenever you are compiling with ICC.

# ***********************
# - Building LFS packages
# ***********************

# To build packages without profiling then './configure && icc-make'. The
# /usr/share/config.site-icc file will be used. You may want to add
# "-O2 -ipo0" to CFLAGS and CXXFLAGS in /usr/share/config.site-icc:

echo 'CFLAGS="-ipo0 -O2"' >> /usr/share/config.site-icc
echo 'CXXFLAGS="-ipo0 -O2"' >> /usr/share/config.site-icc

# Some packages, such as Perl and Bash, generate large amounts of profiling
# data. You can expect these packages to use 4GB of storage, and more, during
# the build. Packages which generate especially large amounts of profiling
# data also take a lot of system resources to process this data.

# Some packages do not have testsuites, so we can not easily generate profiling
# data for them. With small packages we can manually run common commands to
# generating the profiling data.

# Beware I have frozen my system while computing profiling data (with Perl).
# Since then I began using 'nice -n 19' when using -prof_use, and have not
# frozen my system since. You can renice your whole login... first find your
# process ID for your LFS chroot with 'ps a | grep /tools/bin/bash', and then
# 'renice 10 -p ???'.

# The truely best way to generate profiling data is to install the programs.
# This way the program will be profiled against your specific system and uses.
# If you wish to do this, I'll let you modify the following instructions. You
# will need to store the profiling data in a dedicated directory, like
# /home/icc/prof_data/coreutils, reboot the system and run it normally for a
# few days, then rebuild with make-icc-prof_use (-prof_use). I have never
# tried this.

# In general, to profile packages, we would do something like this:

prof_gen-env ./configure &&
icc-make &&
icc-make check &&
icc-make distclean &&
prof_use-env ./configure &&
icc-make &&
icc-make install

# Packages (in the "Linux From Scratch - Version SVN-20061029" order):

# You should unset environment CFLAGS/CXXFLAGS, if you set them, so that
# ICC will use the optimizations in the icc config files.

# You should also run the testsuies whether you are using profiling or not.

# - Berkeley DB (and TCL)
# DB compiles with ICC, but the testsuite does not work without a full
# installation of TCL. Berkeley DB's testsuite takes about 150 SBU (many hours)
# to complete. If you are not prepared to do that then simply install Berkeley
# DB without profiling, like the LFS book does. These tests will also use
# about 4GB of space.

# If you want to profile Berkeley DB then install TCL from the BLFS book.
# Berkeley DB and TCL contain libraries, so you may want to add the -gcc
# option. I built my system using ICC as much as possible, so I did not build
# these libraries with -gcc because I have no compatability to worry about.
# TCL can also be profiled with ICC. If you want GCC compatability with TCL's
# libraries then run this command:

sed -e 's/-.*PIC/& -gcc /' -i unix/configure

# To profile TCL (make sure the ./configure --options are the same as in the
# BLFS book):

cd unix &&
prof_gen-env ./configure --prefix=/usr --enable-threads &&
icc-make &&
icc-make test

# TCL will fail several tests because networking does not work, and will also
# complain about the profiling data files being left behind, that's fine. Then
# rebuild TCL to use the profile data and -ipo:

icc-make distclean &&
prof_use-env ./configure --prefix=/usr --enable-threads &&
icc-make

# You can 'make test' again if you're paranoid. Then install TCL.

# We need GCC compatability with Berkeley DB libraries for Man-DB:

sed -e 's/-.*PIC/& -gcc /' -i dist/configure

# Build Berkeley DB just like TCL, with the prof_gen-env and prof_use-env
# scripts. Also add TCL and tests to the configure command:

cd build_unix &&
prof_gen-env ../dist/configure --prefix=/usr --enable-cxx \
	--enable-tcl --with-tcl=/usr/lib --enable-test &&
icc-make

# Then to run the testsuite open the tclsh shell:

tclsh

# At the % promt run the tests (this will take hours):

source ../test/test.tcl
run_parallel 5 run_std
exit

# Then clean Berkeley DB and rebuild:

icc-make realclean &&
prof_gen-env ../dist/configure --prefix=/usr --enable-cxx \
	--enable-tcl --with-tcl=/usr/lib &&
icc-make

# Then install Berkeley DB.

# - E2fsprogs
# E2fsprogs does not build properly with ICC. Build E2fsprogs with GCC:

env -u CONFIG_SITE ../configure...
make

# - Coreutils
# Build Coreutils with profiling:

prof_gen-env ./configure --prefix=/usr &&
icc-make

# Then run the testsuite, distclean, and rebuild with the profiling
# information:

prof_use-env ./configure --prefix=/usr &&
icc-make

# Then install Coreutils.

# - Iana-Etc has nothing to compile.

# - M4
# M4 is typical. Build and install it just like Coreutils.

# - Bison:
# Bison is a typical build, like M4.

# - Ncurses
# Ncurses builds with ICC, but I had serious issues with Bash. So for now
# I suggest building Ncurses with GCC:

env -u CONFIG_SITE ./configure...

# - Procps does not compile with ICC. It will compile with GCC by default.
# If you really want a pure ICC system, you can use the Procps utilities from
# Busybox.

# - Sed
# I compile Sed with -fast. If you don't want to, and/or you are not using
# the -xP optimization, then build Sed like Coreutils. To build Sed with
# -fast:

prof_gen-env ./configure...
icc-make
icc-make check
icc-make distclean
prof_use-fast-env ./configure...
icc-make

# Then install Sed.

# - Libtool
# 'libtool' itself is a script, but the package includes a library. To add
# GCC compatability (this is optional):

sed -e 's/^CFLAGS =/& -gcc/' -i libltdl/Makefile.in

# Then profile Libtool like Coreutils, but use 'make clean' instead of
# 'distclean'.

# - Perl
# Since I started using AR="xiar" I have not been able to get Perl to build
# with ICC. Even without AR="xiar" Perl will fail a couple tests. For these
# reasons I suggest building Perl with GCC. Just build Perl normally, it will
# ignore the config.site file.

# - Readline
# Readline is a library and you may want to add -gcc (I don't):

sed -e 's/^CFLAGS =/& -gcc/' -i {,shlib/}Makefile.in

# Readline does not have a testsuite, so it can not easily be profiled. Build
# it normally and it will use the config.site file to use ICC. Remember to
# use 'icc-make'.

# - Zlib can compile with ICC, but X11 will not be able to link to it even if
# -gcc is used, so I do not suggest it. To build Zlib with GCC:

env -u CONFIG_SITE ./configure...

# - Autoconf and Automake are perl scripts.

# - Bash
# Bash-3.1 can compile with ICC, and bash-3.2 does not. I do not suggest
# using Bash-3.2 because I had bad expirence with it (it's screwy).
# Bash-3.1 can be built with profiling, but not with -ipo. Remember to use
# the bash-3.1 upstream patch. The Bash sources directory will grow to almost
# 3GB with profiling data. Build Bash like this:

prof_gen-env ./configure...
icc-make
icc-make tests
icc-make distclean
nice -n 19 env -u CONFIG_SITE LANG="en" LANGUAGE="en" LC_ALL="C" \
	LD="xild" AR="xiar" CC="icc -prof_use -prof_dir=$(pwd)" \
	./configure...
icc-make

# Then install Bash.

# - Bzip2
# I'm building bzip2.so,a with -ipo, and bzip2 and bzip2recover with -fast.
# If you are not using -xP then change -fast to -ipo0.

icc-make CC=icc CFLAGS="-prof_gen -prof_dir=$(pwd) \
	-D_FILE_OFFSET_BITS=64 -O2" \
	AR=xiar LD=xild -f Makefile-libbz2_so &&
icc-make clean &&
icc-make CC=icc CFLAGS="-prof_gen -prof_dir=$(pwd) \
	-D_FILE_OFFSET_BITS=64 -O2" \
		AR=xiar LD=xild

# The bzip2 testsuite tests the bzip2 which has libbz2.a linked to it, so
# the libbz2.so shared libraries doesn't get tested and doesn't generate
# profiling data. We can do this ourselves:

dd if=/dev/urandom of=urandom.file bs=1M count=17
env LD_PRELOAD=./libbz2.so.1.0 ./bzip2-shared urandom.file
env LD_PRELOAD=./libbz2.so.1.0 ./bzip2-shared -d urandom.file.bz2
cat CHANGES LICENSE bzip2 | \
	env LD_PRELOAD=./libbz2.so.1.0 ./bzip2-shared -4 -c > non-random.bz2
env LD_PRELOAD=./libbz2.so.1.0 ./bzip2-shared -d non-random.bz2
env LD_PRELOAD=./libbz2.so.1.0 ./bzip2-shared --help

# Then rebuild Bzip2 with the profiling data:

icc-make clean &&
icc-make -f Makefile-libbz2_so clean &&
icc-make CC=icc CFLAGS="-prof_use -prof_dir=$(pwd) -O -gcc -ipo0 -O2 \
	-D_FILE_OFFSET_BITS=64" AR=xiar LD=xild -f Makefile-libbz2_so &&
icc-make clean &&
icc-make CC=icc CFLAGS="-prof_use -prof_dir=$(pwd) -D_FILE_OFFSET_BITS=64 \
	-ipo0 -fast" AR=xiar LD=xild

# Then when installing bzip2, do not install the 'bzip2-shared' version,
# install the statically linked (with -fast) 'bzip2' file instead.

# - Diffutils does not have a testsuite. You can build it with ICC the way the
# LFS book builds Diffutils. Remember to use 'icc-make'.

# - File
# File builds with ICC, and does not have a testsuite, just like Diffutils.

# - Findutils
# Findutils can be compiled with ICC profiling, just like Coreutils or M4.
# I compile Findutils with -fast because 'find' and 'locate' usually do
# intense operations and don't stay in memory after. To build Findutils with
# -fast:

prof_gen-env ./configure...
icc-make
icc-make check
icc-make distclean
prof_use-fast-env ./configure...
icc-make
 
# Then install Findutils.

# - Flex
# Build and install Flex typically, like Coreutils and M4.

# - Grub does not compile with ICC:

env -u CONFIG_SITE ./configure...

# - Gawk
# Build and install Gawk typically, like Flex. I used -fast with Gawk, via
# prof_use-fast-env.

sed -e 's/CFLAGS =/& -fast/' -i {,awklib/}Makefile &&
make-icc-prof_use

# Then install Gawk.

# - Gettext
# Gettext contains libraries, so you may want to add -gcc (I don't):

find gettext-runtime/ -name Makefile.in \
	-exec sed -e 's/^CFLAGS =/& -gcc/' -i {} \;

# I couldn't get Gettext to build with -ipo, but it builds with profiling.
# After 'make distclean':

nice -n 19 env -u CONFIG_SITE LANG="en" LANGUAGE="en" LC_ALL="C" \
	LD="xild" AR="xiar" CC="icc -prof_use -prof_dir=$(pwd)" ./configure..

# - Grep
# Build and install Grep typically. I used -fast for Grep too.

# - Groff
# Groff does not build with -ipo, and does not have a testsuite. Build Groff
# like this:

env -u CONFIG_SITE CC="icc" CXX="icpc" LD="xild" AR="xiar" \
	LANG="en" LANGUAGE="en" LC_ALL="C" ...

# Remember to use 'icc-make'.

# - Gzip
# Gzip doesn't have a testsuite, but we can mimick one:

dd if=/dev/urandom of=urandom.file bs=2M count=10
./gzip -9 urandom.file
./gzip -d urandom.file.gz
cat AUTHORS README README-alpha ChangeLog | ./gzip -4 -c > non-random.gz
./gzip -d non-random.gz

# I build Gzip with -fast too.

# - Inetutils
# Inetutils does not have a testsuite but will compile with ICC.

# - Iproute2
# Iproute2 needs the -gcc option, and does not have a testsuite:

icc-make SBINDIR=/sbin CC="icc -gcc" &&
icc-make SBINDIR=/sbin CC="icc -gcc" install

# - Kdb
# Kbd does not have a testsuite:

icc-make CC="icc"

# - Less
# Less does not have a testsuite. Configure and build it normally.

# - Make
# Build and install Make typically.

# - Man-DB
# Man-DB does not have a testsuite. Configure and build it normally.

# - Mktemp
# Mktemp does not have a testsuite, but we can simulate one:

./mktemp --help
./mktemp -V
./mktemp -p . && ./mktemp -p . XXXXXXXX
./mktemp -p . -d && ./mktemp -p . -d XXXXXXXX

# You can build Mktemp with -fast if you like.

# - Module-init-tools
# I suggest you use this patch to dynamically link insmod:
# http://www.linuxfromscratch.org/patches/downloads/module-init-tools/
#	module-init-tools-3.2.2-nostatic-1.patch

# Run the Module-init-tools tests like this:

prof_gen-env ./configure &&
prof_gen-env icc-make check &&
icc-make distclean

# Then rebuild with 'prof_use-env'.

# - Patch
# Patch does not have a testsuite. Build and install it normally.

# - Psmisc
# Psmisc does not have a testsuite. Build and install it normally.

# - Shadow
# Shadow does not have a testsuite. Build and install it normally.

# - Sysklogd
# Sysklogd does not have a testsuite. Build Sysklogd with ICC like this:

icc-make CC="icc -ipo0"

# - Sysvinit
# Sysvinit does not have a testsuite. Build Sysvinit with ICC like this:

icc-make -C src CC="icc -ipo0"

# - Tar
# Tar can be built typically, like Coreutils.

# - Texinfo
# Texinfo can be built typically, like Coreutils.

# - Udev does not compile with ICC.

# - Util-linux does not compile with ICC.

# - Vim
# Vim can be built typically. Vim's testsuite will almost certainly screw up
# your terminal. Pipe the output to a log, or /dev/null:

make test 2>&1>/dev/null

# Opening and reading the log can also screw up your terminal.

# After LFS is installed add the environment files to /etc/profile:

echo "source /etc/idbvars.sh" >> /etc/profile
echo "source /etc/iccvars.sh" >> /etc/profile
echo 'export CONFIG_SITE="/usr/share/config.site-icc"' >> /etc/profile
source /etc/profile

# There is a project to compile the Linux kernel with ICC:

# http://www.pyrillion.org/linuxkernelpatch.html

# But I couldn't get it to work.

# Your system should now be running like lightning :-)

# Beyond LFS packages which compile with ICC:

# - OpenSSL
# I couldn't get OpenSSL to compile with 'xiar'.

# - OpenSSH
# OpenSSH can compile with profiling, but has a couple issues. First the
# 'optreset' Glibc function doesn't resolve, but we can use the 'optreset'
# included with OpenSSH:

prof_gen-env env ac_cv_have_getopt_optreset=no ./configure...

# The other issue is with 'ld' not resolving symbols from the Glibc
# library, but we can 'icc' instead:

make LD=icc AR=xiar

# - LibPNG
# LibPNG can compile with ICC, but X11 won't be able to use it:

env -u CONFIG_SITE ./configure...

# - Freetype doesn't compile with profiling, but can compile with ICC.

# - Expat doesn't compile with profiling, but can compile with ICC.

# - Fontconfig can compile with ICC profiling.

# - Wget
# Wget will compile with ICC but has weird buggy behaviour, so I suggest
# building Wget with GCC:

env -u CONFIG_SITE ./configure...

# - Pkg-config
# Pkg-config will build with profiling, like Coreutils.

# - Xorg
# Don't build Xorg with ICC, its not well supported. Use:

env -u CONFIG_SITE ../build.sh...

# Jpeg-6b can compile with ICC profiling. Add -gcc to CFLAGS and because this
# is a library.

# LCMS can compile with ICC profiling. Add -gcc to CFLAGS because of the
# library.

# LibMNG can compile with ICC.

icc-make CC=icc CFLAGS="$ICC_CFLAGS -gcc"

# QT supports ICC.
# Add "-platform linux-icc -thread" to the ./configure command.

# Pkgconfig can compile with ICC profiling.

# Glib2 can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# Libogg can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# Libvorbis does not compile with ICC.

# Alsa-lib doesn't compile with profiling, but does compile with ICC.

# Alsa-utils can compile with ICC profiling.

# Audiofile can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# Libmad can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# Arts supports ICC, but the newest version of ICC does not build the latest
# stable release of Arts. So, for now, it doesn't work. I emailed KDE about it,
# after trying to build an Arts snapshot.

# Libart_lgpl does not compile with ICC.

# Wget can compile with ICC profiling.

# Libxml2 can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# Libxslt can compile with ICC profiling. Add -gcc to CFLAGS/CXXFLAGS.

# KDE does not compile with ICC.

# Zip compiles with ICC:

sed -e 's|gcc|icc|g' -i unix/Makefile

# And use "generic_icc" as the make target.

# Unzip compiles with ICC. Run this after applying the patches:

sed -e 's|gcc|icc|g' -i unix/Makefile

# Cpio can compile with ICC profiling.

# Tcsh can compile with ICC profiling.

# GnuPG can compile with ICC profiling.

# LibIDL can compile with ICC profiling.

# Others that compile with ICC:

# Glib
# Gtk
# Pango
# Atk
# Gtk2
# Libogg
# Libxml
# Libxst
# Audiofile
# Libmad
# Which
# GnuPG
# Cdparanoia
# Libungif
# Giflib
# Imlib2
# Aalib
# SDL
# Libdvdcs
# Libdvdread
# Xvidcore
# Lzo

# Lame
# If Lame is compiled with ICC it will cause problems with other packages, like
# FFmpeg, which try to link to libmp3lame. This package should be compiled with
# GCC.

# Xine-lib
# Popt
# Libao
# Flac123
# Wget
# Cvs
# Ncftp
# Subversion
# Ntp
# Lynx
# Bind-utils
# Vorbis-tools
# Mpg123

# For Mpg123 do:

sed -e 's at gcc@/opt/bin/icc at g' -i Makefile

# LibIDL

# Vorbisgain
# Libaal
# Reiser4progs
# Cdrtools
# Add "CC=/opt/bin/icc" to the make command.

# Irssi

# And more...

# ICC has its own Prelink program... check the man pages.

ACKNOWLEDGMENTS:
	* Thanks to Daniel Baumann for the original hint.
	* Thanks to Gentoo for their wiki page:
		http://gentoo-wiki.com/HOWTO_ICC_and_Portage

CHANGELOG:
[2005-06-25]
	* Adopted hint.
[2005-06-26]
	* Added more supported packages.
[2005-07-04]
	* It can reboot now.
[2005-12-08]
	* New Intel CC version.
	* New Cpio security patch.
	* Point Cpio to the correct location of rmt in /tools.
	* Use icpc for CXX.
	* Several more packages compile now.
	* Added instructions to profile code.
	* Added -gcc for Iproute2.
[2006-05-19]
	* Run 'make check' after building with prof_gen, to generate profiling data.
[2006-05-22]
	* Added notes for the -ipo option.
	* Added warning about Perl's large amount of generated profiling data.
	* Bash may compile with ICC now.
	* Fixed up the bzip2 instructions a bit.
	* Added note about Diffutils and File's lack of testsuite.
[2006-06-24]
	* Bump to icc-9.1.
	* Use some shell variables for icc version to make it easier for users
	  who are using a different icc version.
	* Add sed commands for -ipo.
	* Make a config.site for ICC.
	* Added make scripts for code profiling, to make things easier.
	* Add ICC_CFLAGS to the ICC config file, to make things easier.
	* Spell checked.
[2006-11-06]
	* Bump to ICC-9.1.042.
	* Added more uses for the -fast option, and other options.
	* Bumped to LFS-SVN-20061021
	* Static libraries can be built with -ipo, but only works if AR=xiar
	* Added icc-make so xiar (AR) is used.
