CFLAGS

From Gentoo Wiki
Jump to: navigation, search

About CFLAGS

The CFLAGS and CXXFLAGS are environment variables whose content is passed on to each invocation of cc (the C compiler, usually gcc) or c++ (the C++ compiler, usually g++) respectively during compile and build phases of software. Within Gentoo, these variables are set in /etc/portage/make.conf so that each compile job invoked by the package manager uses them.

For example:

File/etc/portage/make.conf

CFLAGS="-march=native -O2 -pipe"
CXXFLAGS="${CFLAGS}"

A short explanation:

  • -march=native: this tells GCC to automatically detect the CPU architecture to use instead of manually specifying one
  • -O2: this tells GCC to optimize the code it produces
  • -pipe: this speeds up the compilation process in that temporary files are not used for the various compilation stages

To see what -march=native or -mtune=native enables for your specific CPU, run gcc -march=native -E -v - </dev/null 2>&1 | grep cc1. Simply using this whole output instead of -march=native is not recommended, but cache parameters can be used safely.

Please note that optimization level -O2 is 2 preceded by an uppercase "o", not by a zero.

For development and quality control purposes, this variable can instruct the compiler to add debug information to the generated binaries. A typical setting would then be:

File/etc/portage/make.conf

CFLAGS="-march=native -O2 -pipe -ggdb -frecord-gcc-switches"
CXXFLAGS="${CFLAGS}"

For Intel Core i7 CPU users or those having econf error during install (with the current 2012.1 release of Gentoo which ships with GCC 4.5.3 compiler) it is recommended to begin your install with the -march=core2 flag to generate a base install against GCC 4.5.3, then later you can upgrade GCC to 4.6.3 or newer in order to support the new -march=corei7 flag. Below is the recommended setting to begin with for Core i7 users:

File/etc/portage/make.conf

CFLAGS="-march=core2 -O2 -pipe"
CXXFLAGS="${CFLAGS}"

Graphite / LTO / OpenMP

Some optimizations are hard to enable for a reason. If you don't understand how they work, then you should consider using the default recommended Safe CFLAGS or use the package's recommended CFLAGS. Also keep in mind, that at the moment (GCC 4.7 and 4.8) auto parallelization is only working in rare cases (see Discussion), often leads to decreased performance since GCC currently does not check if the performance gain outweighs the added parallelization overhead, and causes runtime failures for some packages, a notable example being the lame MP3 encoder. Therefore it might not be the worst idea to keep "-floop-parallelize-all and -ftree-parallelize-loops=n" disabled globally, and to enable these flags only for packages known to benefit from them (by using per package environment variables). Also, please always keep in mind that of course the common misconceptions regarding CFLAGS apply to graphite as well. For instance a benchmark comparing the effect of numerous CFLAGS settings on audio encoding reveals that lame gains much more performance by switching compiler (from gcc to clang) instead of tinkering with CFLAGS.

Enabling everything at once will either break packages, cause segmentation faults or break GCC or Glibc; effectively rendering the system useless until those packages are overwritten by the stage3 archive. So please, don't try this at home.

To enable the "Holy Grail" combo, first install Gentoo with as little packages as possible. Be sure to use GCC newer than 4.7.2. Once GCC is installed, edit package.mask to block newer and older versions of GCC. At this point, use -O2 and disable all other non-default flags. The system will get fragile, so some packages need to be frozen in time. Once this is done, use "emerge -e world" twice to make sure the system is compiled using itself. GCC needs to be compiled using libraries compiled with this GCC compiled version and using this GCC configuration. This may seem useless, but if it is skipped you will get "undefined references to gomp" errors.

It is now time to emerge dev-libs/cloog and dev-libs/cloog-ppl. Once this is done, enable graphite CFLAGS and USE flag. Emerge GCC again, then "emerge -e world" again to make sure all packages are built using this version and configuration of GCC. Again, a half updated system will cause program compilation breaks or segfaults later on.

Now it is time to turn on ",-fopenmp -lgomp" within the LDFLAGS, and "-fopenmp, -floop-parallelize-all and -floop-parallelize-loops=4" within the CFLAGS. Add openmp to the USE flags. I think it is safe to also enable LTO at this point. The system resulting from the new "emerge -e world" should be fairly stable with minimal packages failing to compile.

If you still experience massive failures while recompiling the system or world, or have a non-working system, you probably skipped one of these steps.

Note
If your system fails to compile, you can blame Elv13 for forgotting one of the steps when he wrote this advice.

See also

External resources