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.
#include<stdio.h> int main(void) { printf("HELLO POFTUT.COM\n"); return 0; }
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 app
.
$ gcc -o app main.c

We can check create executable file with file
command which will print
- File type
- Architecture
- Version
- BuildID
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
Optimize More
More optimization means more speed. This is level 2 optimization and best selection in most of the cases.
$ gcc -O2 main.c
Comprehensive Optimization
Compherensive optimization will make our binary faster but this may not work some cases. Use this optimization level accordingly. We will use -O3
option.
$ 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 8.1K
.
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.
#include<stdio.h> int main(void) { int a; printf("HELLO POFTUT.COM [%d]\n",a); return 0; }
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 *.i
extensions.
$ gcc -E main.c > main.i

We print first 10 lines of main.i
with head
command.
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 main.s
$ 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
command.
$ 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 -v
option.
$ gcc -v main.c

We see that information like;
- Target
- Thread mode
- gcc version
- gcc options
- gcc assembler version
- …
are provided
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 -funsigned-char
option.
$ 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 MYMACRO
.
#include<stdio.h> int main(void) { #ifdef MYMACRO printf("MYMACRO"); #endif printf("HELLO POFTUT.COM \n"); return 0; }
and we will run following gcc
command.
$ 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 -Werror
option.
$ 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 opt
.
-Werror -v -DMYMACRO
and we will compile like below.
$ gcc @opt -o main main.c
