Week 4B - Building GCC and Make & Makefiles?! - Lab 4

Table of contents
- What is GCC?
- What is Make/Makefile?
- Building the GCC Compiler - Lab 4
- What is the screen command?
- 1) Creating a screen session
- 2) Clone the GCC source code using git
- 3) Create a build directory
- 4) Configuring the script
- 5) Running the build
- 6) Record the build time
- 7) Compare the built compiler with the system one
- 8) Testing both builds with a C program
- 9) Updating the timestamp & Rebuilding
- 10) Perform a null build
- Reflection
- References

Welcome everyone! In this article, I will discuss the GCC compiler and how we can build it together as well as what “Make” and “Makefiles” is. Let’s get started!!!
What is GCC?
You may be thinking, “GCC I’ve heard that before” or maybe you’re wondering “what is that, some sort of a car?!” Do not worry, I was in the same shoes and will explain to you GCC in such a way that I hope you all will understand.
GCC stands for “GNU Compiler Collection”. Think of it as one big codebase thats sole purpose is to take a bunch of code in languages like C, C++, Objective-C, and Fortran, and convert it into executable programs. The code we type with words like int x = 0
cannot be understood by computers. Don’t forget, computers understand 1
s and 0
s. Therefore, the GCC’s job is to take our code in a language like C and translate it into assembly language and then into machine code!
Now before we build the GCC compiler, I am going to explain Make and Makefiles first which should provide you with a clearer understanding of these concepts together. However, before I get into Make and Makefiles, I want you to follow along with me by using some example code that Professor Chris Tyler provided in his wiki. Please navigate to a directory of your choosing and run the following command in your bash terminal:
NOTE: If you are on mac, this may not work so use homebrew to install wget by running the command brew install wget
inside the terminal first.
After downloading these files, extract them using: tar xvf makefile-examples.tgz
What is Make/Makefile?
make
is a command you can execute inside the bash terminal. Now what this command does, it it executes a Makefile
that automates the compilation of programs. I am not sure if you know, but to build a C program, we use the following command: gcc nameOfFile.c
which then outputs an a.out
file. We can then run/execute this file like ./a.out
which will execute the C program. Now imagine, every time we change our program, we have to re-run the gcc command. Not fun right? This is where make comes in, its a command that can potentially automate this process by finding the Makefiles
within the same directory the program is in. Let’s learn more about Makefiles
.
Breakdown of Makefiles
Before we break down a Makefile, start off by going into the makefile-examples
directory you extracted before and go into ex1
directory. Run the command cat Makefile
. This will show you the following text:
# Makefile for hello.c
# CTyler 2004.06.07
# This defines the C compiler and compiler flags
CC=gcc
CFLAGS=
# Following two locations are for demo purposes only
MANDIR=/tmp
BINDIR=/tmp
# This first target is the default
hello: hello.c
${CC} ${CFLAGS} -o hello hello.c
# Cleans up any binaries or object files
clean:
rm hello
# Installs binary and man page
install: hello man8/hello.8
cp hello ${BINDIR}/ ; cp man8/hello.8 ${MANDIR}/
# Test the binary
test: hello
if (./hello|grep 'Hello, World!') ; \
then echo "***** Success." ; \
else echo "***** Failure" ; \
fi
# Tests the man page
test-man: man8/hello.8
man -M . 8 hello
Let’s break down the Makefile, at the top you’ll see the variables identified such as CC
that is simply the gcc command. The CFLAGS
can be used to specify optimizations for the GCC compiler to perform
Now when you scroll down you will see a bunch of sections per say like hello:
clean:
install:
. We call these targets or rules of the Makefile that specifies what to do and how. For example, the hello
target, will use the dependency hello.c
and then the command right under it is executed to compile hello.c
and output hello
. Likewise, the clean
target will remove the hello
output file and then the install
target will install all files somewhere. And lastly, the test
target simply tests the hello output build.
So what does make have to do with all this? The make command simply finds a Makefile with the recipe or set of instructions we specified inside and we can use this command to either call a specific target or the first target. For example, executing the command make
will execute the first target named hello:
. Therefore, if you want to quicly execute another target, it's simple. You can do it as follows:
make targetName
Important Things to Remember when building Makefiles!
Now before I move on, there is one more important factor to consider when it comes to the syntax of Makefiles. If you look at each target and the command under each of these targets, you will an indentation. Ensure you do this as well when constructing your own Makefile!
Building the GCC Compiler - Lab 4
In this weeks lab, we will be building the GCC compiler on two separate machines called the aarch64-002 & x86_64-001. To learn more about these servers click here. I will go over the build process, the build time, and also test the build! Let’s get started!
Please note: if you are following along and have multiple machines, simply use the same commands simultaneously in each ssh session. Later on, you will be able to compare the build time of each machine.
Before we begin cloning the GCC compiler from git. I will teach you a very useful command that Professor Chris Tyler went over in class and that is the screen
command.
What is the screen command?
The screen command allows us to run sessions within one terminal window. You can create a session and within that session, run a command, and even if you leave the session, it keeps it open to allow the command to run in the background. This is extremely useful when running commands that can take hours to execute. Especially for this lab, building the GCC compiler can take some time and we will start off by executing the screen command to create a session and continue with our build.
1) Creating a screen session
To create a screen session, first login to your server using ssh
or use your own machine by opening its terminal.
Now execute this command: screen -S building-gcc-x86
. NOTE: the 'building-gcc-x86
’ part can be named anything but remember this as we can use this to get back into a session.
2) Clone the GCC source code using git
Before we build the compiler, we need its source code. So let’s use git to clone the repository into a directory. Run the following command:
git clone https://gcc.gnu.org/git/gcc.git ~/git/gcc
NOTE: after the URL you can specify any directory you want!
3) Create a build directory
After the directory has been cloned into the directory you chose, let’s create a separate directory for the build. “The GCC source code may be built inside the source directories, but this is not recommended and strongly discouraged by the GCC developers” - Professor Chris Tyler (SPO600 Wiki).
Run the following commands:
mkdir ~/gcc-build-001
cd ~/gcc-build-001
This simply creates the directory and moves you into that directory.
4) Configuring the script
Now we want to configure the script by setting a custom prefix that enables us to set the prefix directory for where the installation will occur. Run the following command below:
~/git/gcc/configure —-prefix=$HOME/gcc-test-001
5) Running the build
Now this is the main part where we will execute a command that records the build time, runs the make command for the gcc build, specify the jobs and output the build log. Run the command below:
time make -j 24 |& tee build.log
Now while this is building, we can detach from our screen session safely by using the shortcut: Ctrl+A, D
. Now you can safely exit and do whatever you want, come back in an hour or so by running the command: screen -RaD nameOfSession to enter the session again.
6) Record the build time
After the build is complete, you will be shown the build time. Here are images for both machines:
For the AArch64 system, it took 110 minutes:
For the x86 system, it took 47 minutes:
7) Compare the built compiler with the system one
Now let's compare the GCC compiler we built with the one thats already installed on to the system. To do that we can run the following commands:
gcc —version
~/gcc-test-001/bin/gcc —version
For the AArch system:
The one installed onto the machine itself is of version 11.3.1
The version we installed is version 15.0.1
For the x86 system:
- The one installed onto the x86 machine itself is version 14.2.1
The version we installed is 15.0.1
8) Testing both builds with a C program
So we’ve built the gcc compiler and now its time to test it out. Navigate back into your home directory and create a directory. Inside that directory create a file using the touch command, name it hello.c. Use the vi command followed by hello.c to start editing and make a simple C program that prints Hello World!
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
After saving the program, run the following command:
$HOME/gcc-test-001/bin/gcc hello.c -o hello
./hello
If it prints Hello World, then the program was successfully built!
AArch64 program:
x86 program:
9) Updating the timestamp & Rebuilding
Now we will update the timestamp on a file called passes.cc
using the following command below. Thereafter we will see how long it takes to build again, but this time we will output the log in a different file.
touch ~/git/gcc/gcc/passes.cc
Now run the following command:
cd ~/gcc-build-001
time make -j 20 |& tee rebuild.log
AArch64 build time for passes.cc change was 3 minutes and 10 seconds long:
x86 build time for passes.cc change was 48 seconds
10) Perform a null build
Performing a null build just means not changing any files are re running the build command: time make -j |& tee nullbuild.log
So lets run this on both machines and see how long it takes
AArch64 null build time took only 23 seconds long:
X86 null build time took only 13 seconds:
Reflection
This lab was not necessarily difficult but was one where I had to come to it back and forth. (Thank you to whoever made the screen command, you are a life saver). I enjoyed learning more about the gcc compiler, how to build one, how to test it, and also the time it takes to build. GCC is large, so building it the first time takes time, however when you change a few files, it significantly reduces the time as it only rebuilds those files. And when we run the nullbuild where no file is changed, all it does is it looks for file changes and if none are found we are good to go!
In conclusion, this lab was an excellent way of learning about the GCC compiler but also brushing up my linux skills, I used a combination of commands like make, time, tee, and also use vim after a long time. Lastly, I feel like the best command I learned was the screen one which I will definitely use in my career, so a huge thank you to Professor Chris Tyler for such valuable information!
References
Professor Chris Tyler’s Wiki:
Cover Image:
- Image by Clker-Free-Vector-Images from Pixabay
Subscribe to my newsletter
Read articles from Hamza Teli directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
