The GNU Compiler Collection (GCC) is one of the most fundamental tools in a Linux developer‘s toolbox. As a critical component of the GNU toolchain, GCC has helped enable Linux‘s rise to power the modern software world. This comprehensive guide will walk through installing GCC on Linux Mint and leveraging it for C/C++ compilation.

A Brief History of GCC

GCC was originally written in 1987 by Richard Stallman, founder of the GNU Project to create a free Unix-like operating system. It was designed to provide open source developers a way to compile software without relying on proprietary tools.

Over decades of development, GCC evolved to support over 10 programming languages across dozens of hardware architectures and platforms. It has been ported to work on operating systems ranging from Solaris and BSD derivatives to Microsoft Windows through Cygwin.

According to current statistics, over 96% of all C/C++ open source software is compiled using GCC. It ships by default on all major Linux distributions and powers development of the Linux kernel itself plus system tools, desktop environments, server daemons, and more. Even competing compilers like LLVM/Clang integrate closely with GCC via the GNU toolchain.

Its flexibility, maturity, and open source license has cemented GCC as an absolutely essential component for Linux growth over the past 30+ years.

Installing GCC and Build Tools

Modern Linux distributions include GCC in their base package repositories. On Debian-based distros like Linux Mint, we use the APT manager:

sudo apt update
sudo apt install build-essential

The build-essential meta-package brings in GCC plus additional utilities like make and gdb. Answer "Y" at the prompt to confirm installing GCC and friends.

To verify GCC got set up properly, print the version in your terminal:

gcc --version

gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The exact GCC version may differ depending on your Mint release, but confirming it runs means you are ready to compile programs.

Compiling Simple C and C++ Code

Let‘s experiment with basic GCC usage by compiling a simple "Hello World" program. First, create a file hello.c with the following C source code:

#include <stdio.h>

int main() {
  printf("Hello World!"); 
  return 0; 
}

To build the executable binary, run:

gcc hello.c -o hello

This tells GCC to take hello.c as input and build an output executable called hello.

Execute it with:

./hello

Output: 
Hello World!

It works! We have successfully invoked GCC to turn C code into a running program.

GCC is even more popular for C++ compilation, where it dominates as the top choice over alternatives like Clang. Here is a simple C++ example named hello_cpp.cpp:

#include <iostream>
using namespace std;

int main() {
  cout << "Hello C++ World!" << endl;
  return 0;
}

Use the g++ command to invoke the C++ compiler instead of gcc:

g++ -o hello_cpp hello_cpp.cpp
./hello_cpp

Output:
Hello C++ World!

Just like that, GCC is compiling and running basic C++ programs. Now let‘s explore more advanced compilation options.

Passing GCC Compiler Flags

GCC offers a rich set of compiler flags and options to control compilation. These expose lower-level capabilities that advanced developers can leverage to optimize their software.

Common flags include:

  • -Wall – Enables all compilation warnings. Helpful for catching issues early.
  • -Werror – Treat warnings as errors stopping compilation. Ensures strict code.
  • -O1 – Light optimization. Improves performance without growing binary size too much.
  • -O2 – Moderate optimization. Good balance of speed versus binary size.
  • -O3 – Heavy optimization. Favors performance over other considerations.
  • -g – Adds debugging symbols. Allow debugging executables with gdb.
  • -march=native – Tunes instruction set for local CPU. Enables AVX and other features.
  • -fno-semantic-interposition – Small speed boost by customizing symbol binding.
  • -fpie – Enables Position Independent Executable for security hardening.

For illustration, we can compile an optimized C program like so:

gcc -Wall -Werror -O2 -g -march=native -o optimized_program program.c

This leverages modern CPU features for performance while showing all warnings and errors during compilation. The resulting optimized_program binary is checked for issues and ready for debugging.

Later on we will explore integrating GCC with development environments that simplify passing compilation flags.

Installing Multiple GCC Versions

The GCC version shipped in Linux Mint may not be recent enough for your use case. Compiling newer projects often requires updating to the latest GCC release to enable the newest language features.

Thankfully multiple versions can co-exist thanks to Linux flexible filesystem layouts. This allows smoothly migrating legacy software builds across GCC upgrades.

To demonstrate, we will install GCC 10.3 from source without impacting the existing GCC installation. This will exist in parallel, available for specific builds.

First grab build prerequisites like the GNU Multiple Precision Arithmetic Library:

sudo apt install g++-10-multilib gcc-10-multilib libgmp-dev libmpfr-dev libmpc-dev

Then download GCC 10.3 source code and extract it:

wget https://ftp.gnu.org/gnu/gcc/gcc-10.3.0/gcc-10.3.0.tar.gz
tar xf gcc-10.3.0.tar.gz
cd gcc-10.3.0

Bootstrap the GCC build process with:

./contrib/download_prerequisites
mkdir gcc-build
cd gcc-build
../configure --prefix=/opt/gcc-10.3.0 --enable-languages=c,c++
make -j 8

This will run approximately 30 minutes even on modern quad core CPUs. The -j flag parallelizes the build to utilize all cores.

Finally, install this GCC into a dedicated /opt directory:

sudo make install

The newly compiled gcc and g++ executables now reside in /opt/gcc-10.3.0/bin.

Check out the new GCC 10.3 version:

/opt/gcc-10.3.0/bin/g++ --version

g++ (GCC) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

So GCC 10 lives alongside GCC 9 on our Linux Mint system! We can choose either during compilation.

Having multiple compilers installed allows smoothly migrating software compilations across GCC versions rather than forcing immediate adoption of the latest. This flexibility helps advance the Linux ecosystem in parallel.

Integrating GCC with Development Environments

While GCC itself offers rich compilation functionality, directly invoking it from the terminal for large projects can become tedious. This is why most developers use IDEs and text editors that abstract away low-level tooling.

For building GCC projects, Visual Studio Code is a popular open-source editor with great C/C++ support. Its CodeLLDB extension wraps GCC invocations to provide:

  • Code auto-completion with IntelliSense
  • Project debugging via LLDB and GDB
  • Compilation flags configured through a GUI
  • Execution directly within the editor

This streamlines development using GCC without having to touch the command line.

Eclipse, NetBeans, and CLion offer similar GCC integration alongside proprietary IDEs like JetBrains. Linux developers can choose whichever editor suits their style.

Visual Studio Code GCC Integration

Cross Platform Compilation with GCC

A key strength of GCC is its high portability supporting dozens of architectures. This allows cross compilation – building executables for foreign systems right from your Linux desktop.

For example, you can install GCC‘s ARM toolchain to compile Android or embedded Linux software without needing the actual devices:

sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

arm-linux-gnueabihf-g++ -o arm_binary src.cpp

Similarly, the Mingw-w64 packages provide GCC for Windows compilation that looks like:

x86_64-w64-mingw32-gcc -o demo.exe demo.c

With containers and virtual machines, the possible cross-compile targets expand exponentially. GCC lowers the barriers to building software for restricted platforms that cannot host traditional compiler toolchains directly.

Best Practices for Production GCC Usage

When utilizing GCC in professional environments, developers should follow strict protocols to ensure production stability.

Some recommendations include:

  • Fix the GCC version across all development environments rather than blindly upgrading. Unexpected compile breaks can paralyze teams.
  • Extensively test CFLAGS changes before pushing to shared build servers. Regressions impact everyone downstream.
  • Build from release tarballs instead of Git to avoid skewing from mainline. Numerous GCC bugs arise from packaging issues.
  • Utilize a build daemon like Incredibuild for distributing overnight tests. Catch issues early before code reaches trunk.
  • Plan compiler migrations by staging a secondary GCC version and slowly transitioning legacy apps. Jumping GCC releases overnight is asking for trouble.
  • Contribute GCC patches upstream for platform-specific issues. Working with the GCC community prevents hacky one-off fixes.

Carefully managing GCC toolchains is mandatory to balance agility with stability for business workflows. Do not blindly run apt full-upgrade without expecting fallout!

Conclusion

This guide just scratched the surface of leveraging GCC during Linux application development. Entire books exist covering its compilation stages, internal design, and extension mechanisms.

Yet GCC remains approachable for even novice developers through simple invocation patterns. It offers the stability and language support needed for initiating new programmers into the open source ecosystem.

I encourage readers to explore further GCC capabilities like:

  • Link Time Optimization to whole-program analysis
  • Profile Guided Optimization using execution traces
  • Linker maps and intermediate representations
  • Integrated Assembler options and instruction tuning

Feel free to comment any other GCC topics you would like explained!

Similar Posts