Project Stage 1: Preparation(part-1)
Tags: gcc, compiler
Published: 2024-05-31 23:58:47

Hii everybody!! I am here again with a new series of blogs for my Project Stage 1 called Preparation but trust me it is much longer than just preparation.🥲

So without wasting any time lets dive in to it.


## Project Stage 1: Preparation

### Step-by-Step Guide

#### Step 1: Become Familiar with the GCC Build Process

**Building the Current Development Version of GCC**

---

**Downloading GCC Source Code**

Start by cloning the GCC repository to get the latest development version of the source code:

```
git clone git://gcc.gnu.org/git/gcc.git
cd gcc
```

---

**Building GCC on AArch64 and x86**

GCC can be built for different architectures. Here, I'll show you how to build it for both AArch64 and x86 architectures.

**Create a separate build directory:**

   ```
   mkdir build
   cd build
   ```

**Configure the build for AArch64:**

   ```
   ../configure --prefix=$HOME/gcc-aarch64 --target=aarch64-linux-gnu --enable-languages=c,c++
   ```

Here's a detailed breakdown of each part of this command and why it is used:

1. ../configure:
This runs the configure script, which prepares the build system by checking for dependencies and setting up makefiles.
The ../ prefix assumes that you are in a separate build directory (e.g., gcc/build), and you need to reference the configure script located in the parent directory (gcc).

2. --prefix=$HOME/gcc-aarch64:
This option specifies the installation directory for the built GCC. By setting it to $HOME/gcc-aarch64, you ensure that the GCC built for AArch64 is installed in a local directory under your home directory ($HOME).
Using a local installation path avoids overwriting the system-wide GCC and allows you to manage multiple GCC versions for different architectures.

3. --target=aarch64-linux-gnu:
This option specifies the target architecture and system for the GCC build. The aarch64-linux-gnu target indicates that GCC will be built to generate code for the AArch64 architecture, which is used in many ARM 64-bit processors, and is intended to run on a GNU/Linux system.
This is essential for cross-compilation, where the build machine (host) is different from the target machine (where the generated code will run). Here, you are preparing a cross-compiler that runs on your current machine but produces executables for AArch64.

4. --enable-languages=c,c++:
This option specifies which programming languages the GCC compiler should support. By listing c,c++, you are instructing the build system to compile and include support for the C and C++ languages.
This helps reduce the build time and resource usage by excluding support for other languages that you might not need.

Same goes for x86_64.

**Configure the build for x86:**

   ```
   ../configure --prefix=$HOME/gcc-x86 --target=x86_64-linux-gnu --enable-languages=c,c++
   ```

**Build GCC:**

   ```
   make -j$(nproc)
   ```

- make: This is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program.
- -j: This option tells make to perform parallel builds. It allows make to run multiple jobs simultaneously. The number of jobs to run is specified immediately after -j.
- nproc: This command prints the number of processing units available (CPU cores). On a machine with 4 CPU cores, nproc will return 4.

**Install GCC locally:**

   ```
   make install
   ```

---

**Analyzing Build Time and Options**

To understand the build time and experiment with different build options, you can use the `time` command.

**Track build time:**

   ```
   time make -j$(nproc)
   ```

**Experiment with build options by adding flags to the configure command:**

   - `--disable-multilib`: Disable building libraries for multiple target architectures.
   - `--enable-checking=release`: Enable additional checks useful for release builds.
   - `--disable-bootstrap`: Disable the bootstrap process which rebuilds the compiler multiple times to ensure reliability.

   Example configuration with additional flags:

   ```
   ../configure --prefix=$HOME/gcc-x86 --target=x86_64-linux-gnu --enable-languages=c,c++ --disable-multilib --enable-checking=release --disable-bootstrap
   ```

---

#### Step 2: Navigate the GCC Codebase

Understanding the structure of the GCC codebase is crucial for making modifications and additions.

**a. Compilation Passes**

Navigate to the GCC source directory:

```
cd gcc
```

**Key Files:**

- `passes.def`: This file defines all the passes in GCC.
- `gcc/passes.cc`: This file controls the execution of passes.

`passes.def` is a key file in the GCC codebase that defines the list of compiler passes used during the compilation process. Each entry in passes.def represents a specific pass, which is a distinct phase in the compilation where certain analyses or transformations are performed on the code.

**How passes.def works**

1. Definition of Passes:
`passes.def` contains macro definitions for each pass. Each entry typically uses a macro (such as PASS) to register the pass with a unique identifier and its corresponding implementation.

2. Integration with the GCC Build System:
The entries in passes.def are processed by the GCC build system to generate the appropriate structures and function calls required to include these passes in the compilation pipeline.
This file essentially acts as a registry for all the passes that GCC will execute.

3. Control Flow:
During the compilation process, GCC iterates over the list of passes defined in passes.def, executing each one in sequence. This allows for modular and structured transformations and optimizations on the code.

4. Adding a New Pass:
To add a new pass, you add an entry to passes.def using the appropriate macro. For instance:
```
PASS(function_counter)
```

After defining a new pass in passes.def, you must implement the corresponding logic in a new or existing .c or .cc file and ensure it is registered properly in the GCC infrastructure (often in files like passes.cc).

By managing the list of passes in a centralized file like passes.def, GCC maintains an organized and easily extensible framework for implementing various compilation phases. This design allows developers to add, remove, or modify passes without disrupting the overall structure of the compiler.


And that's a wrap for today! 🎬 We've embarked on our journey into the intricate world of GCC preparation, but trust me, this is just the tip of the iceberg! Who knew building a compiler could be so exhilarating? But hey, if you're not feeling the adrenaline rush yet, don't worry, I've got more in store for you.

Stay tuned for the next episode of my GCC adventure, where we'll delve even deeper into the codebase, uncovering secrets, and maybe even stumbling upon a few surprises along the way. Until then, keep those compilers compiling and those keyboards clacking! ✨