Determine Compiler Version
Test Environments
Hardware Comments | Nut/OS 4.6.3 |
Nut/OS 4.6.4 |
Nut/OS 4.7.4 |
Nut/OS 4.8.0 |
Nut/OS 4.8.7 | |
Ethernut 1.3 H | OK | OK Binaries |
OK Binaries |
OK Binaries |
OK Binaries Compiler: AVR-GCC 4.3.2 | |
Ethernut 2.1 B | OK | OK Binaries |
OK Binaries |
OK Binaries |
OK Binaries Compiler: AVR-GCC 4.3.2 | |
Ethernut 3.0 E | OK | OK Binaries |
OK Binaries |
OK Binaries |
OK Binaries Compiler: AVR-GCC 4.3.2 | |
EIR 1.0 C | Set jumper JP1 to DEBUG mode. | OK | OK Binaries |
OK Binaries |
OK Binaries |
|
Compiler: ARM-GCC 4.2.2 ; AVR-GCC 4.3.0 |
Description
This example demonstrates how to determine which compiler was used to compile a program and in the case of the GNU C compiler how to display its version.
Source Code
<source lang="c">
- include <dev/board.h>
- include <stdio.h>
- define STRINGIFY_(x) #x
- define STRINGIFY(x) STRINGIFY_(x)
- if defined(__AVR__)
- define CPUTYPE "AVR"
- elif defined (__arm__)
- define CPUTYPE "ARM"
- else
- define CPUTYPE ""
- endif
- if defined(__GNUC__)
- if defined(__GNUC_PATCHLEVEL__)
- define COMPILER CPUTYPE "-" "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
- else
- define COMPILER CPUTYPE "-" "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__)
- endif
- elif defined (__IMAGECRAFT__)
- define COMPILER "ICCAVR"
- else
- define COMPILER "Unknown"
- endif
int main(void) {
u_long baud = 115200;
NutRegisterDevice(&DEV_DEBUG, 0, 0); freopen(DEV_DEBUG_NAME, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
printf("Compiler: %s\n", COMPILER);
for(;;); return 0;
} </source>
Output
Compiler: ARM-GCC 4.2.2
Details
The main action takes place in the preprocessor commands as you can see.
<source lang="c">
- define STRINGIFY_(x) #x
- define STRINGIFY(x) STRINGIFY_(x)
</source>
These lines are required to store an integer value in a string.
<source lang="c">
- if defined(__AVR__)
- define CPUTYPE "AVR"
- elif defined (__arm__)
- define CPUTYPE "ARM"
- else
- define CPUTYPE ""
- endif
</source>
This block of code checks if the current board uses an AVR or an ARM processor.
It makes use of the macros __AVR__
and __arm__
, which are defined, if the corresponding CPU is installed.
The new macro CPUTYPE
now is defined as ARM
or AVR
.
Before calling the main()
function, the preprocessor substitutes CPUTYPE
by ARM
or AVR
So, whenever we use CPUTYPE
in our program we get either an "ARM"
or an "AVR"
string.
<source lang="c">
- if defined(__GNUC__)
- if defined(__GNUC_PATCHLEVEL__)
- define COMPILER CPUTYPE "-" "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
- else
- define COMPILER CPUTYPE "-" "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__)
- endif
- elif defined (__IMAGECRAFT__)
- define COMPILER "ICCAVR"
- else
- define COMPILER "Unknown"
- endif
</source>
This segment of code consists of 2 nested if
statements, to determine, which compiler was used.
Aditionally, if GNUC (GCC) was used, which version was used.
To do so, these 4 predefined macros are used.
- __GNUC__ - Gets replaced by the major version number. (here: 4) Only defined if GCC was used as compiler.
- __GNUC_MINOR__ - Gets replaced by the minor version number. (here: 2)
- __GNUC_PATCHLEVEL__ - Gets replaced by the patchlevel (thrid position) version number (here: 2)
- __IMAGECRAFT__ - Is defined if ICCAVR was used to compile.
So macros are not only used to be replaced by certain values, but also just to check if they were defined or not.
With
<source lang="c">
- define STRINGIFY_(x) #x
- define STRINGIFY(x) STRINGIFY_(x)
</source>
defined
<source lang="c">
- define COMPILER CPUTYPE "-" "GCC" " " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
</source>
we can now use a macro "function" (STRINGIFY
) to define a macro (COMPILER
) as a string to contain integer values like __GNUC__
or (_GNUC_MINOR__
do.
In other words, STRINGIFY
turns its parameter into a string value. These string values as well as some dots and the CPUTYPE
macro (which "holds" a string already) replace COMPILER
.
<source lang="c"> printf("Compiler: %s\n", COMPILER); </source>
So everytime we use COMPILER
in our program, we get a string instead, which holds the compiler name and version.