Make

Certain tasks (such as compiling C, C++ or Fortran code) can be repetitive. Take the compilation of two C++ source files into a binary for example:

hello_world.C
#include <iostream>
void hello()
{
  std::cout << "Hello world!" << std::endl;
}
driver.C
#include <iostream>

void hello();

int main(int argc, char **argv)
{
  hello();
  return 0;
}

Compile & Link in your shell

g++ -c hello_world.C
g++ -c driver.C
g++ hello_world.o driver.o -o helloWorld.exe

Adding on third-party libraries or special compiler flags results in even more complicated compile commands.

Make is software that can be used to help simplify and automate repetitive tasks, such as compiling & linking code. This short tutorial shows how to use GNU Make in a build environment.

Example Makefile

Here is a Makefile that can be used to compile and link a simple program of two source files:

helloWorld.exe: hello_world.o driver.o
${CXX} -o $@ $^

Copy the preceding code into a file called "Makefile". To run the code, simply enter gmake at the command-prompt. This should compile and link an executable called "helloWorld.exe".

What does each line do?

Line 1

helloWorld.exe: hello_world.o driver.o

This line defines a target (aka rule) "helloWorld.exe" and its dependencies: "hello_world.o" and "driver.o". GNU Make will ensure that all dependencies are up-to-date before performing the tasks defined in a target. In this example, the dependencies will be compiled using the default rules. That is, the following lines will be executed:

g++ -c hello_world.C
g++ -c driver.C

Line 2

${CXX} -o $@ $^

Any lines indented directly below a target (ie. "helloWorld.exe") will be executed after all dependencies are up-to-date. After the tab, you can type any shell command. This particular command uses a few special variables defined by GNU Make:

$@ is the name of the target: "helloWorld.exe".

$^ is a list of the prerequisites: "hello_world.o" and "driver.o".

When this line is run via Make, the following lines will be executed:

xlc hello_world.o driver.o -o helloWorld.exe

Why Make?

Why type two lines of code into a Makefile to execute three compile & link commands? Although this example is a bit contrived, you gain several benefits:

  • Enter gmake once to compile and link the program
  • Makes sure that all targets are up-to-date (and does not recompile up-to-date targets!)
  • On large code bases, you can compactly specify many relationships and dependencies of the source code.

Summary

We have covered the absolute bare minimum of Makefiles. To learn more, experiment with Makefiles others have written. If you see something confusing, reference the resources below to learn more.

Resources

  • No labels