Support Gentoo-Icc

Every support which has to do with icc and Linux or Gentoo is highly appreciated.
Just email me

Source patching hints

Here are some useful hints for patching sources to compile with icc specifically when using gcc sourcecode. Please use icc+gcc variants when patching source so they can be submitted to the software maintainers.

  1. Inline assembler
    1. Named variables
    2. Packed attribute
  2. Ebuilds
    1. Flags (general)
    2. Flags

Inline assembler
Named variables
Icc does not accept named variables so every named variable must be referenced by its index in the argument list. (Example taken from: here)

GCC source:
template <typename T> inline static bool compare_and_exchange(volatile T& dest, T& old_val_out, T old_val, T new_val)
{
	bool result;
	__asm__ __volatile__(
		"lock cmpxchgl %[newv], %[mem] \n setzb %[flag]"
		: [flag] "=qm"(result), [mem] "+m" (dest), "=a" (old_val_out)
		: "a" (old_val), [newv] "r" (new_val)
		: );
	return result;
}

ICC+GCC source:
template <typename T> inline static bool compare_and_exchange(volatile T& dest, T& old_val_out, T old_val, T new_val)
{
	bool result;
	__asm__ __volatile__(
		"lock cmpxchgl %4, %1 \n setzb %0"
		: "=qm"(result), "+m" (dest), "=a" (old_val_out)
		: "a" (old_val), "r" (new_val));
	return result;
}


Packed attribute
Icc ignores the __attribute__((__packed__)) statement if executed with the -no-gcc option.
Use the #pragma pack(...) syntax instead.

GCC source:
struct
{
  int   a;
  char  b;
  long  c;
}test __attribute__((__packed__));

ICC source (begin-end):
#pragma pack(push, 1)
struct
{
int   a;
char  b;
long  c;
}test;
#pragma pack(pop)

ICC+GCC source (begin-end):
#ifdef __INTEL_COMPILER
#pragma pack(push, 1)
#endif
struct
{
  int   a;
  char  b;
  long  c;
}
#ifdef __GNUC__
__attribute__((__packed__))
#elif __INTEL_COMPILER
#pragma pack(pop)
#endif
test;

ICC source (next struct):
#pragma pack(1)
struct
{
  int   a;
  char  b;
  long  c;
}test;

ICC+GCC source (next struct):
#ifdef __INTEL_COMPILER
#pragma pack(1)
#endif
struct
{
  int   a;
  char  b;
  long  c;
}
#ifdef __GNUC__
__attribute__((__packed__))
#endif
test;

Ebuilds
Flags (general)
Always use the functions provided by portage such as filter-flags

Flags examples
# Setting -gcc-sys
# Don't just use append-flags "-gcc-sys" as -no-gcc stays in the flags
if [ `basename "$CC"` == "icc" -o `basename "$CXX"` == "icc" -o `basename "$CXX"` == "icpc" ]; 
  filter-flags "-no-gcc" "-gcc-sys" "-gcc"
  append-flags "-gcc-sys"
fi

# Setting -gcc-sys only if -no-gcc is set
# Just for sure:
if [ `basename "$CC"` == "icc" -o `basename "$CXX"` == "icc" -o `basename "$CXX"` == "icpc" ]; 
  replace-flags "-no-gcc" "-gcc-sys"
fi

If an ebuild somehow cleans its flags (like glibc does) try to first set ALLOWED_FLAGS and add an flag manually only if this doesn't help.

Preventing from removing *gcc* flag
if [ `basename "$CC"` == "icc" -o `basename "$CXX"` == "icc" -o `basename "$CXX"` == "icpc" ]; then
  ALLOWED_FLAGS="${ALLOWED_FLAGS} -no-gcc -gcc-sys -gcc"
fi


Flags

Whenever modifying CFLAGS or CXXFLAGS in an ebuild, use something like the following to apply these settings only to icc:

For CFLAGS
if [ `basename "$CC"` == "icc" ]; then
  ...
fi

For CXXFLAGS
if [ `basename "$CXX"` == "icc" -o `basename "$CXX"` == "icpc" ]; then
  ...
fi