Makefile Fundamentals
Tags: learning, linux, tips, tutorial
Published: 2020-09-17 12:36:26

---
title: Makefile Fundamentals
published: true
date: 2020-09-11 00:00:00 UTC
tags: [learning, linux, tips, tutorial]
description: Automate build processes with ease
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/m2na4jn9dbus1vr25d3m.png
canonical_url: https://0066cc.com/blog/makefile/
---

# 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:

```
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.
another_target_name:
    echo "And this is another command that could be run independently!"
    # This is also a valid comment
final_target_name: example.txt
    echo $(msg)

```

The key takeaways from this example are that:

- Each runnable target of your makefile must have a name that ends with a colon (:).
- Each command inside a section must be indented by one tab. Indenting with spaces will result in an error.
- In larger makefiles it may be appropriate to add comments explaining non-obvious commands. Comments can be inserted with a hashtag (#). Comments do not need to be indented the same way regular commands are.
- Placing a file name after the target name can be used to specify file(s) that are needed for the target to run.
- Makefiles also offer support for variables like those seen on the first and last line.

# 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:

```
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:

```
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:

```
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:

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

```

## Output of Step 9:

```
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`.

```
> 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:

```
> 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(`@`).

```
make:
    @echo "Hi!"

```

Doing so will now output:

```
> 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:

```
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:

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

```

Using the same makefile as above will now display:

```
> 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:

```
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:

```
> 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:

```
> 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:

```
> 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:

- Makefile structure and syntax.
- Requirements
- Declaring, using, and passing variables.
- Modifying output with command suppression.
- Custom makefile names

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](https://www.gnu.org/software/make/manual/make.html).