What it is
GCC (GNU Compiler Collection) is the primary compiler for C, C++, Objective-C, Fortran, Ada, Go, and D, and it’s the standard for building software on Linux and many other Unix-like systems. You reach for it to turn your source code into executable programs.
Installation
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install build-essential
This installs gcc, g++, make, and other essential development tools.
Linux (Fedora/CentOS/RHEL)
sudo dnf groupinstall "Development Tools"
# or for older systems:
# sudo yum groupinstall "Development Tools"
macOS
Install Xcode Command Line Tools:
xcode-select --install
This will install clang, which is a compatible compiler, and often gcc is provided as a symlink or an alternative. For a native GCC, you can use Homebrew:
brew install gcc
Windows
The easiest way is to install MinGW-w64:
- Download the installer from the MinGW-w64 website.
- Run the installer and select the desired architecture (e.g.,
x86_64for 64-bit) and thread model (posixis generally recommended). - Add the
bindirectory of your MinGW-w64 installation (e.g.,C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin) to your system’s PATH environment variable.
Core Concepts
- Compilation: The process of translating human-readable source code (like
.cor.cppfiles) into machine-readable object code. - Linking: The process of combining one or more object files and libraries into a single executable file.
- Pre-processing: The first stage of compilation where directives like
#includeand#defineare handled. - Assembly: Translating pre-processed code into machine instructions.
- Object File: An intermediate file (
.oextension) produced by the compiler that contains machine code but is not yet a complete executable program. - Executable: The final output file that can be run directly by the operating system.
Commands / Usage
GCC is typically invoked directly from the command line. The most common usage is to compile source files into an executable.
Compiling a Single Source File
C:
gcc hello.c -o hello
Compiles hello.c into an executable named hello.
C++:
g++ main.cpp -o my_program
Compiles main.cpp into an executable named my_program. (Note: g++ is the C++ driver for GCC).
Compiling Multiple Source Files
C:
gcc main.c utils.c -o app
Compiles main.c and utils.c together into an executable named app.
C++:
g++ main.cpp helpers.cpp -o service
Compiles main.cpp and helpers.cpp together into an executable named service.
Linking Libraries
Linking a standard library (e.g., math library):
gcc math_example.c -o math_app -lm
Compiles math_example.c and links it with the math library (libm.so or libm.a).
Linking a custom library:
gcc main.c -L/path/to/your/lib -lyour_lib -o custom_app
Compiles main.c and links it with a library named your_lib found in /path/to/your/lib. The -L flag specifies the directory, and -l specifies the library name (e.g., -lyour_lib looks for libyour_lib.so or libyour_lib.a).
Debugging and Optimization Flags
-g: Include debugging information in the executable. Essential for using debuggers like GDB.gcc -g my_code.c -o my_code_debug-O0: No optimization (default). Fastest compilation, slowest execution.gcc -O0 my_code.c -o my_code_no_opt-O1: Basic optimization.gcc -O1 my_code.c -o my_code_opt1-O2: More optimization. A good balance for release builds.gcc -O2 my_code.c -o my_code_opt2-O3: Aggressive optimization. May increase code size.gcc -O3 my_code.c -o my_code_opt3-Os: Optimize for size. Useful for embedded systems or where binary size is critical.gcc -Os my_code.c -o my_code_small-Og: Optimize for debugging experience. Enables optimizations that don’t interfere with debugging.gcc -Og my_code.c -o my_code_debug_opt
Warning Flags
-Wall: Enable all common warning messages. Highly recommended.gcc -Wall my_code.c -o my_code_warn-Wextra: Enable additional warning messages beyond-Wall.gcc -Wall -Wextra my_code.c -o my_code_extra_warn-Werror: Treat all warnings as errors. Prevents compilation if any warnings are issued.gcc -Wall -Werror my_code.c -o my_code_no_warnings
Language Standards
-std=c99: Compile using the C99 standard.gcc -std=c99 my_c99_code.c -o c99_app-std=c11: Compile using the C11 standard.gcc -std=c11 my_c11_code.c -o c11_app-std=gnu99: Compile using the C99 standard with GNU extensions (often the default).gcc -std=gnu99 my_gnu_code.c -o gnu_app-std=c++11: Compile using the C++11 standard.g++ -std=c++11 my_cpp11_code.cpp -o cpp11_app-std=c++14: Compile using the C++14 standard.g++ -std=c++14 my_cpp14_code.cpp -o cpp14_app-std=c++17: Compile using the C++17 standard.g++ -std=c++17 my_cpp17_code.cpp -o cpp17_app-std=c++20: Compile using the C++20 standard.g++ -std=c++20 my_cpp20_code.cpp -o cpp20_app
Pre-processing and Intermediate Stages
-E: Stop after the pre-processing stage. Outputs the pre-processed code to standard output.gcc -E hello.c > hello.i-S: Stop after the assembly stage. Outputs assembly code (.sfile).gcc -S hello.c -o hello.s-c: Compile or assemble the source files, but do not link. Produces object files (.o).
Then you can link them:gcc -c main.c utils.c -o # This creates main.o and utils.ogcc main.o utils.o -o my_program
Include Paths
-I/path/to/include: Add a directory to the list of places to search for header files.gcc main.c -I/usr/local/mylib/include -o app
Output Control
-o output_file: Specify the name of the output file. If omitted, GCC defaults toa.out(ora.exeon Windows).gcc main.c -o my_executable-v: Verbose output. Shows the compiler commands being executed.gcc -v main.c -o verbose_app
Other Useful Flags
-D MACRO[=VALUE]: Define a pre-processor macro.gcc -D DEBUG my_code.c -o debug_build # Equivalent to #define DEBUG in the sourcegcc -D VERSION="1.2.3" my_code.c -o versioned_app # Equivalent to #define VERSION "1.2.3"-U MACRO: Undefine a pre-processor macro.gcc -U DEBUG my_code.c -o release_build # If DEBUG was defined elsewhere (e.g., by -DDEBUG), this removes it.-pedantic: Issue all the warnings demanded by strict ISO C / ISO C++ conformance.gcc -Wall -pedantic my_code.c -o strict_app-shared: Produce a shared object (dynamic library) which can be linked with other objects to create an executable, or with other shared objects.gcc -shared -fPIC my_lib.c -o libmylib.so
Common Patterns
- Compile and link a simple program:
gcc my_program.c -o my_program - Compile with debugging symbols and all warnings:
gcc -g -Wall -Wextra my_app.c -o my_app_debug - Optimize for release, enable common warnings:
gcc -O2 -Wall my_app.c -o my_app_release - Compile multiple files into an executable:
gcc main.c module1.c module2.c -o my_application - Compile files individually into object files, then link:
This is useful for large projects where you only want to recompile changed files.gcc -c main.c -o main.o gcc -c module1.c -o module1.o gcc -c module2.c -o module2.o gcc main.o module1.o module2.o -o my_application - Compile C++ code with C++17 standard and optimizations:
g++ -std=c++17 -O3 main.cpp utils.cpp -o my_cpp_app - Create a static library:
(The# Compile source files into object files gcc -c lib_part1.c lib_part2.c # Create the static library archive ar rcs libmy_static_lib.a lib_part1.o lib_part2.o # Link your program with the static library gcc main.c -L. -lmy_static_lib -o my_app-L.tells the linker to look in the current directory for libraries.) - Create a shared library:
# Compile source files with position-independent code flag gcc -fPIC -c lib_part1.c lib_part2.c # Create the shared library gcc -shared -o libmy_shared_lib.so lib_part1.o lib_part2.o # Link your program with the shared library gcc main.c -L. -lmy_shared_lib -o my_app # You might need to set LD_LIBRARY_PATH or install the library correctly # to run the executable if it's not in a standard system path. # export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH # ./my_app
Gotchas
a.outas default output: If you forget the-oflag, GCC will create an executable nameda.out(ora.exeon Windows). This can be confusing if you compile multiple files without specifying output names.g++vsgccfor C++: Whilegcccan compile C++ code with the-x c++flag, it’s best practice to useg++for C++ projects.g++automatically links the C++ standard library, whichgccdoes not. Forgetting this can lead to linker errors.# Correct for C++ g++ main.cpp -o my_app # Incorrect for C++ (will likely fail to link std::cout, etc.) # gcc main.cpp -o my_app # Correct but verbose for C++ # gcc -x c++ main.cpp -lstdc++ -o my_app- Order of source files and libraries: The linker processes libraries and object files in the order they appear. If library A depends on library B, you must list A before B.
# Correct: lib_a depends on lib_b gcc main.o -L. -l_a -l_b -o my_app # Incorrect: lib_b is linked before lib_a, so dependencies might not be resolved # gcc main.o -L. -l_b -l_a -o my_app - Header file vs Library path:
-Iis for header files (.h), and-Lis for library files (.so,.a). They are distinct. makefor larger projects: For anything more than a few files, manually invoking GCC becomes tedious. Tools likemakeare essential for managing the build process, automatically determining which files need recompilation.- Shared library runtime path (
LD_LIBRARY_PATH): When you compile a program against a shared library that isn’t in a standard system location, you often need to tell the dynamic linker where to find it at runtime. This is commonly done by setting theLD_LIBRARY_PATHenvironment variable (on Linux/macOS).
On Windows, you’d typically place the DLL in the same directory as the executable or in a system-wide DLL directory.export LD_LIBRARY_PATH=/path/to/your/libs:$LD_LIBRARY_PATH ./your_executable - Position-Independent Code (
-fPIC): When creating shared libraries, you usually need to compile the object files with-fPIC(or-fpic) to ensure they can be loaded at any memory address. - Warning flags are crucial: Compiling without
-Walland-Wextracan hide subtle bugs. Treating warnings as errors with-Werrorenforces code quality.