Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Kosukhin__Sergey
Beginner
187 Views

Intel compiler and /usr/include/target

Hello, All!

I am not sure if this is the right place to write about this but I would like to share a piece of information regarding a potential problem one might face when using Intel C compiler with a self-built gcc.

Assume we have two gccs on our system. The first one (system gcc, e.g. gcc 4.9) came along with our Linux distribution and the second one (self-built gcc, e.g. gcc 6.2.0) is built from sources by ourselves. Now, we want to compile a hello-world C program that includes stdio.h (which, several levels of recursion later, includes sys/cdefs.h). On some Linux distributions (e.g. Debian 8) the latter file resides in /usr/include/x86_64-linux-gnu.

We start with making sure that our program can be compiled with both system and self-built gccs (both system and self-built GNU preprocessors know that they should look into /usr/include/x86_64-linux-gnu).

We also don't (we shouldn't) have problems compiling it with icc when it's configured to work with the system gcc (either by making sure that it's the first gcc in the PATH or by specifying the -gcc-name flag of icc). But if we try to compile with icc in conjunction with the self-built gcc we might get an error:

/usr/include/features.h(374): catastrophic error: cannot open source file "sys/cdefs.h"

If you run icc -dryrun hello.c you'll see that /usr/include/x86_64-linux-gnu is not among --sys_include directories.

So, I wrote a wrapper script for gcc and cpp to store the arguments they are called with to a text file to find out how icc gets information on the environment from them. I expected to see that icc calls something like 'cpp -v' to get the list of the system include directories but it didn't do that. In fact, icc does not call cpp at all (well, in this case) but tries to guess what should be on the list by analysing the output of 'gcc -### dummyfile.c' (just FYI, the dummyfile contains only one string: void foo();).

It looks like the reason for the problem is that the self-built gcc was built without explicit specification of the target and if you do not specify the target explicitly gcc's configure script uses whatever the config.guess script returns. In my case, it's 'x86_64-pc-linux-gnu'. My assumption is that since 'x86_64-linux-gnu' is not equal to 'x86_64-pc-linux-gnu', icc does not look into /usr/include/x86_64-linux-gnu.

I decided that it was fair enough (although it's not a problem for GNU cpp and it would make sense to ask it for the list) and recompiled gcc adding the following arguments to the configure script: --target=x86_64-linux-gnu --host=x86_64-linux-gnu --build=x86_64-linux-gnu. It helped: icc included the necessary path on the list and managed to compile the program.

That would be it but I checked one more thing. Instead of giving the same value to all three --target --host and --build flags, it should be OK to specify the value only for --build, since the flags --host and --target inherit the value from --build (if not specified otherwise). To my surprise, icc 17.0.1 could not handle it, which already looks like a bug to me. Let's hope this will be fixed some day but for now,  make sure that you provide gcc's configure script with all three flags. And all of them should get the same value as your system compiler's target.

0 Kudos
0 Replies
Reply