Skip to main content

Makefile

Building HTTPd

HTTPd is the largest project you have worked on this year until now. As a project expands in size, it brings forth new challenges, including writing maintainable code and establishing a sustainable architecture.

Recursive Makefiles

Recursive Makefiles are not required, but they are a practical way to build the httpd binary in a modular project. If you want to do a well-structured build that scales with subdirectories, adopting a recursive layout is encouraged.

tip

In this section, we assume that you are already familiar with make and simple Makefiles. For a refresher, you may look into the various Piscine tutorials on Makefiles as well as the recorded conference.

When using make(1), the option -C can be used to specify the build directory. Make will then move into the directory and run as usual, using the Makefile in it.

42sh$ ls Test./
Makefile votai.c

42sh$ cat Test./Makefile
votai: votai.o

42sh$ make -C Test./
make: Entering directory '/home/lucasTheSpider/Test.'
cc -c -o votai.o votai.c
cc votai.o -o votai
make: Leaving directory '/home/lucasTheSpider/Test.'

42sh$ Test./votai
Votai Test.

This is equivalent to cd Test./ && make && cd - but with additional information about which directory you are calling and which commands are called. As you may recall, a Makefile is composed of rules, and rules are composed of three things:

  • targets (The goal to produce)
  • dependencies (What the target needs prior)
  • recipes (Composed of various commands to run)

Since recipes are composed of any command, it is possible to declare a rule that can call another Makefile if needed.

42sh$ tree
.
|-- Makefile
`-- Test.
|-- Makefile
`-- votai.c

2 directories, 3 files
42sh$ cat Makefile
all:
make -C Test./
42sh$ make
make -C Test.
make[1]: Entering directory '/home/lucasTheSpider/Test.'
cc -c -o votai.o votai.c
cc votai.o -o votai
make[1]: Leaving directory '/home/lucasTheSpider/Test.'
42sh$ Test./votai
Votai Test.

Now, the root Makefile is considered the top-level Makefile, and every Makefile called by it is considered as a sub-Makefile.

tip

Each Makefile handles its own environment, so changing the flags of a sub-Makefile does not affect the top-level one, but modifying the top level will change the environment for the sub-Makefiles if the variable is exported.

export CC = gcc

Defining this variable in the top-level Makefile will make the variable available in every sub-Makefile.