Top 10 Important GCC Flags For Linux Geeks

10 Useful GCC Flags

Let’s take a look at some of the most important GCC flags! GCC, aka the GNU project C and C++ compiler, is an essential tool for any Linux geek who codes in C/C++ and is probably the most widely used compiler. Like most command line utilities, we can further extend the functionalities of GCC with the help of flags. In this module, we’ll be looking at 15 such GCC flags.

Introduction

The GNU C/C++ Compiler is a must have tool for you if you plan to code in either of those two languages. The compiler has a lot of options for you to play around and test with which it implements via flags.

Important GCC Flags

Here are some of the important GCC Flags which might come handy :

1. Name the output file with -o file

This flag helps us to specify the name of the final executable produced by GCC. It places the output of the final executable in a file “file” as specified along with the flag.

If the -o flag is not supplied, it stores the output in a file called “a.out

$ gcc test.c -o out

This stores the output executable binary in a file called “out

2. Produce debugging information with -g

Adding the “-g” flag produces debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). This information can be interpreted by the GNU Debugger which can help us during the debugging process. This extra information makes debugging work better in GDB and helps in better understanding of the things at play.

3. Link a C program with a shared library using -l / -L

A combination of these two flags is required to link your C program with a shared library. The function of the two flags are :

  • -l : Indicates the name of the shared library
  • -L : Location of the shared library

For example, to link a shared library “foo” stored in /home/user/so, the command would be :

$ gcc -L/home/user/so -Wall -o test test.c -lfoo

4. Convert compile-time warnings into errors with -Werror

Often when compiling a binary, we come across a lot of warnings which we dismiss as trivial. These warnings indicated possible loopholes, security functions or flaws in the code and the binary produced produced as a result of such of code might be buggy.

Hence, to convert these warnings to errors, we can use the -Werror flag. As a result, all the warnings shown during compilation will be converted into errors. It might be a bit annoying to eliminate all the errors but the result would be that you have a less buggy executable.

5. Enable all warnings with -Wall

Want even more bug-free code? Try the -Wall flag. This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning).

The -Wall flag, combined with the -Werror flag gives makes sure you have a very bug-proof executable. These flags help you develop safe coding practices and write secure code.

6. Produce position-independent code with -fPIC 

This flag produces position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option especially comes in handy while creating shared libraries. This helps the shared library to get loaded as any address instead of some fixed address.

7. Optimize compilation time -O2/-O3

Optimizes both compilation time and the performance of the generated code. The two flags define the level of optimization of your code so that you can have a more optimal output.

8. Check for buffer overflows during compilation with -fstack-protector

This enables checks for buffer overflows, such as stack smashing attacks. This can go a long way to protect attacks against your binary and might prevent the hijack of the function pointer and prevent the stack from being over written by unwanted, malicious data

9. Use pipes instead of temp files with -pipe

This tells the compiler to use pipes rather than temporary files for communication between the various stages of compilation. This avoids the use of temporary files and speeds up the build process.

10. Save temporary files with -save-temps

When this option is enabled, output at all the stages of compilation is stored in the current directory. This includes the original C code, the Assembly code, the pre-processed output, the compiled code and the executable itself.

$ gcc -save-temps test.c
$ ls
a.out  test.c  test.i  test.o  test.s

Passing GCC Flags via a File

You can store all the flags which you might want to include with the help of “@” symbol. For example you have all the flags you want to be included during compilation like :

$ cat flags
-Wall -Werror -O3 -save-temps 

Then you can include the same with :

$ gcc test.c @flags

This can come in handy when you want to make sure that all your executables have some common standards or to save the pain of typing the same long list of files over and over again.

Conclusion

Thus in this module we saw some of the useful GCC flags. However, there are still MANY more flags which you can review with the command man gcc.