How To Use GCC Compiler Options Like Optimization, Flags?
gcc is very popular compiler in Linux world.
gcc provides interpreter and compiler for programming languages like C, C++, Java etc. In this tutorial we will examine popular compiler options like error, pre-processor, output, optimization etc.
Example C Application Code
During this tutorial we will use following simple example code. As we can see this code only prints
HELLO POFTUT.COM to the standard output.
Specify Output Executable File Name
The default behavior of the the gcc is putting compiled executable file as
a.out . This may not be suitable of pretty solution for professional work. We can specify the compiled executable output file name with
-o option by providing the executable file name explicitly. In this example we will set the executable file name as
$ gcc -o app main.c
We can check create executable file with
file command which will print
- File type
Optimize A Little Bit
Optimization will make created binary run faster in general. We can use
-O1 option in order to optimize a little bit.
$ gcc -O1 main.c
More optimization means more speed. This is level 2 optimization and best selection in most of the cases.
$ gcc -O2 main.c
Compherensive optimization will make our binary faster but this may not work some cases. Use this optimization level accordingly. We will use
$ gcc -O3 main.c
Optimize For Size
In embedded systems disk size may be a matter. We may need to compile the whole library or framework in a size optimized manner. So we can use the
0s option which will reduce the size of the created binary executable.
$ gcc -Os -o main main.c
We can see the difference in the screenshot were before optimization the size was
8.2K but after optimization it reduced to the
Enable All Compile Warnings
By default warnings are not display. But this may hide problems about the code quality and security. We can enable to output warnings explicitly by using
-Wall option. This option is the merge or Warning all .We will use following code to create some warnings.
printf("HELLO POFTUT.COM [%d]\n",a);
We will compile with the following command.
$ gcc -Wall main.c
We can see that variable
a is not initialized and used without an explicit value.
Do Not Compile Only PreProcess
As we know
gcc compiles C applications in 3 phase. The first phase is preprocessing. We can stop compile operation after the preprocess and interrupt compile operation. We will use
-E option to get preprocessed file but create output will be put to the standard output. So we will redirect this output to a file named
main.i . Preprocessed files have
$ gcc -E main.c > main.i
We print first 10 lines of
Produce Only Assembly Code
The second phase of the C application compilation is generating assembly code from preprocessed code which is generated in previous phase. We can output assembly code with
-S option and redirect to a file named
$ gcc -S main.c > main.s
As we have print the assembly code with
head we can see assembly instructions.
Produce Only Compiled Code
We can only produce compiled code with
-C option. This will only contain machine level code without any linking.
$ gcc -C main.c
Produce All Intermediate Steps Files Like PreProcess, Assembly
As we previously looked there are phases during compilation. By default the intermediate files are or temporary files are removed automatically. If we want to inspect these files and do not remove them we can use
-save-temps options which will do not delete preprocessed and assembly files.
$ gcc -save-temps main.c
We can also list these files with
file command like below.
$ file main.*
Link with Shared Libraries
If we will use external shared libraries we need to link them to the executable. We can link shared libraries with
-l option and provide the library name without any extension. For example if we want to use library named
abc.so we will use following
$ gcc -labc -o main main.c
Produce Memory Position Independent Code
While creating shared libraries the assembly code positions is protected. We can create position independent code with the
-fPIC option like below.
$ gcc -fPIC -o main main.c
Print All Intermediate Steps of Compile Operation
As we see there are intermediate steps and process during compile operation. We can print information about these steps in a verbose manner with the
$ gcc -v main.c
We see that information like;
- Thread mode
- gcc version
- gcc options
- gcc assembler version
Enable ANSI/ISO C89 Support
C programming language have different versions and standards set by ANSI or ISO. We can strictly implement and enforce these standards during the compilation. For example we can inplement ISO/ANSI C89 with the
-ansi option like below.
$ gcc -ansi main.c
Interpret char As unsigned char
char types in C programming language provides some flexibility during compile operation. We can interpret them differently according to given gcc options. We can interpret
char type variable as
unsigned char with
$ gcc -funsigned-char main.c
Interpret char As signed char
Another option for
char type usage is
signed char . We can interpret
char type variables as
signed char with
-fsigned-char like below.
$ gcc -fsigned-char main.c
Use Compile Time Macro
Macro provides ability to inject compile time actions to the source code. Simply macro parts are compiled with the given macro options. In this example we will use
-D option with the macro name which is
printf("HELLO POFTUT.COM \n");
and we will run following
$ gcc -DMYMACRO -o main main.c
Interpret Warnings As Errors
Errors are compile interrupting situations. On the other side warnings do not interrupts the compile process , just provide some information about the situation. We can made
gcc to interpret warnings like errors and interrupt compilation with
$ gcc -Werror -o main main.c
Provide gcc Options From File
Up to now we have provided the
gcc options from command line interactively. We can also provide these options from a file or batch file. This will made the
gcc command more readable if we have a lot of options. We will use
@ sign before the options file. We will use following options in our options file named
-Werror -v -DMYMACRO
and we will compile like below.
$ gcc @opt -o main main.c