How To Use GCC Compiler Options Like Optimization, Flags? – POFTUT

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.

#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
Specify Output Executable File Name
Specify Output Executable File Name

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
Optimize For Size
Optimize For Size

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
Enable All Compile Warnings
Enable All Compile Warnings

We can see that variable a is not initialized and used without an explicit value.

LEARN MORE  Compile C Hello World Program

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
Do Not Compile Only PreProcess
Do Not Compile Only PreProcess

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
Produce Only Assembly Code
Produce Only Assembly Code

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 Only Compiled Code
Produce Only Compiled Code

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
Produce All Intermediate Steps Files Like PreProcess, Assembly
Produce All Intermediate Steps Files Like PreProcess, Assembly

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
Print All Intermediate Steps of Compile Operation
Print All Intermediate Steps of Compile Operation

We see that information like;

  • Target
  • Thread mode
  • gcc version
  • gcc options
  • gcc assembler version
LEARN MORE  How To Install Tar.Gz or Tar.Bz2 Application Source Code?

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
Use Compile Time Macro
Use Compile Time Macro

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
Provide gcc Options From File
Provide gcc Options From File

Leave a Comment