Makefile Fundamentals

Marc on 2020-09-11

What's a makefile?

A makefile is simply a file consisting of one or more scripts, referred to as targets, that can be run by the user using the make program that is available on most Linux distributions.

These targets consist of one or more commands that would otherwise need to be repeatedly typed out by hand; hence by bundling these commands together it is possible to automate portions of, or all, of the build process when compiling a program. Additionally, makefiles can also be used to automate testing and general computing processes.

Makefile Fundamental Structure

An outline example of a makefile is listed below:

```makefile msg="This message was stored in a variable!" target_name: echo "Hi! This is a command that will be run!" echo "Each target can run more than one command!"

This is a comment, it wont show up when you run the makefile.

anothertargetname: echo "And this is another command that could be run independently!" # This is also a valid comment finaltargetname: example.txt echo $(msg) ```

The key takeaways from this example are that:

Using A Makefile

If you wish to get a better feel for how makefiles work, try experimenting with changing the target names and ordering. To run the above makefile for yourself:

  1. Create a new blank text file in a directory you have access to.
  2. Open the new file in a text editor.
  3. Either copy or type out the example makefile listed above.
  4. Save the file as makefile and close the file.
  5. Open a terminal and navigate to the directory containing the makefile.
  6. Type make target_name and run the command.
  7. Type make another_target_name and run the command.
  8. Type make final_target_name and run the command.
  9. Type make and run the command.

Output of Step 6:

makefile echo "Hi! This is a command that will be run!" Hi! This is a command that will be run! echo "Each target can run more than one command!" Each target can run more than one command!

Output of Step 7:

makefile echo "And this is another command that could be run independently!" And this is another command that could be run independently!

Output of Step 8:

makefile make: *** No rule to make target 'example.txt', needed by 'makefile'. Stop.

Requirements

You should have received an error when you attempted to run this target. Why is that? The reason for this error is that a requirement has been specified for this target; in order for this target to run the file specified immediately after the target name must be present (in this example 'example.txt').

Output of Step 8 (Corrected):

In order to make this target run create a file called 'example.txt' in the same directory as the makefile. 'Example.txt' can contain anything or even be blank but as long as the file exists, it meets the requirements of the makefile.

Running the makefile now presents the following:

makefile echo "This message was stored in a variable!" This message was stored in a variable!

Output of Step 9:

makefile echo "Hi! This is a command that will be run!" Hi! This is a command that will be run! echo "Each target can run more than one command!" Each target can run more than one command!

No target Specified

It can also be important to remember that simply typing make with no additional specifications will automatically attempt to run the first target listed in the makefile. In this instance, running 'make' will output the same result as make target_name.

```makefile

make echo "Hi! This is a command that will be run!" Hi! This is a command that will be run! echo "Each target can run more than one command!" Each target can run more than one command!

make target_name echo "Hi! This is a command that will be run!" Hi! This is a command that will be run! echo "Each target can run more than one command!" Each target can run more than one command! ```

Additional Features

Hide Displaying Commands

By default, makefiles will automatically display the command that is being run, like how the echo command is shown before actually echoing the text:

```makefile

make echo "Hi!" Hi! ```

To suppress showing the command that is being run and just display the output, prepend the command in question with an at-symbol(@).

makefile make: @echo "Hi!"

Doing so will now output:

```makefile

make Hi! ```

Variables

It's also possible to define variables in a makefile, these can be used to include additional information that can be passed to a command or used to alter how a target should run.

Declaring and Using Variables

Variables must be declared outside any targets like so:

makefile msg="Hello!" text="Another variable!" make: echo $(msg) echo $(text)

Once a variable has been declared, it can then be used in a target by enclosing the variable name with a dollar-sign and brackets $().

Passing Variables

It is possible to pass variables into the makefile from the command-line when a target is run like so:

```makefile

make msg="New value!" ```

Using the same makefile as above will now display:

```makefile

make msg="New value!" echo "New value!" New value! echo "Another variable!" Another variable! ```

By passing variables this way, they do not need to be declared and initialised in the makefile itself, instead it is possible to simply use the variable as if it has already been declared like so:

makefile make: echo $(msg)

Note how msg has not been declared at the top of the file; if you attempt to run the makefile with no additional information then the following will be displayed:

```makefile

make echo ```

As the variable has not been given a value, nothing is printed to the screen. In order to give msg a value, the makefile must be ran like so:

```makefile

make msg="New value!" echo "New value!" New value! ```

Custom Makefile Name

Although makefile is the default filename that will be checked for when you run make, it is possible to use an alternative filename. To do so, when running the make command include the -f switch followed by the name of the file you want to use:

```makefile

make -f alternativeMake print_msg ```

In the above, the make command is used on a file called alternativeMake and attempts to run a target called print_msg.

Additional Resources

That concludes the fundamentals of makefiles, this guide covered:

If you are interested in learning about even more of the features that makefiles offer (such as conditional targets, functions, and recursively expanded variables), consider consulting the official documentation.