Make

Compile commands

Commands to compile programs can get quite long:

clang -std=c11 -pedantic -Wall -g hello.c -o hello

It is time consuming and error prone to type them

The simplest solution is to use the arrow keys in the terminal window to go back to the time you last typed the command, edit it a little if necessary, and press enter to re-issue it, but it would be nice to find something better

Aliases

A convenient alternative is to use aliases:

alias c='clang -std=c11 -pedantic -Wall -g hello.c -o hello'
alias r='./hello'

After typing those lines, you can compile just by typing c, and run by typing r

If you want the system to remember your aliases when you logout and in again, put them in a file called .profile or .bashrc in your home directory

Scripts

A slightly more flexible way to achieve the same thing is to use scripts or script functions

You can find out about those for yourself by looking up the documentation for bash, which is almost certainly the command interpreter running in your terminal window

But it would be better to use something which (a) is 'standard' among programmers and (b) which has a file which you can store with a project to document the way it is compiled and built

The make command

You should find the make command already installed in the lab, and on Linux and Mac computers

On Windows, if you follow the instructions for installing Cygwin (see aside computers) you should have make available

There are more modern and cleverer tools than make, but they have their own complexities, and knowing make is essential for your career

And you can combine make with aliases, say, for your own convenience

Simplified make

These slides describe the simplest ways to use make, avoiding its complex features

The idea is that you create a file called Makefile, which is a kind of script containing commands for compiling and perhaps testing

Then you type make or make something to run those commands

Creating a Makefile

You can create a Makefile using your normal editor

Warning: if you create or download a file called Makefile on Windows, it will probably end up being called Makefile.txt, which is not the default name that make looks for (and you might get confused because you can't see the extension)

Use a Cygwin/Bash terminal window to fix this:

mv Makefile.txt Makefile

A simple Makefile

A simple Makefile might look like this:

hello: hello.c
        clang -std=c11 hello.c -o hello

The first line contains the name of the program, then a colon, then the files that the program is compiled from

Then you can type make hello, or just make if the hello rule is the first one in the Makefile

The make command compiles the program if hello.c has changed since last time

Tabs

Here's the Makefile again:

hello: hello.c
        clang -std=c11 hello.c -o hello

Warning: the second line must start with a hard tab character, not eight spaces (a nasty historical accident), so do not blindly copy-paste the text above

So, your editor must be set up so that Makefiles are an exception to your normal soft tab setting (atom does the right thing)

Dependencies

The dependencies are the files after the colon, and they should include all files which affect the program

Then make checks the timestamps, and if any files have changed since the program was last compiled, it recompiles, but

An alternative Makefile

The Makefile could look like this instead:

.PHONY: hello

hello:
        clang -std=c11 hello.c -o hello

Declaring hello as phony tells make that it is just a rule name, not a file, so the dependencies are ignored and the compile command is always executed

This works without .PHONY if the rule name isn't a file name, but it is better to guard against accidents

Commands

A Makefile rule can run two or more commands:

program:
        clang -std=c11 hello.c -o hello
        ./hello

or it can run one long command, split onto multiple lines, using \:

program:
        clang -std=c11 -pedantic -g -Wall \
        -Werror hello.c -o hello

Multiple entries

A Makefile can have two or more rules:

program:
        clang -std=c11 hello.c -o hello
        ./hello

p2:
        clang -std=c11 oxo.c -o oxo
        ./oxo

The first is the default if you type make on its own, and the second is triggered if you type make p2

Abbreviations

You can define an abbreviation, to be used repeatedly:

OPTIONS = -std=c11 -g -Wall -Werror -pedantic

program:
        clang $(OPTIONS) hello.c -o hello
        ./hello

p2:
        clang $(OPTIONS) oxo.c -o oxo
        ./oxo

The notation $(...) is used to expand an abbreviation

Further features

Makefiles have many more features, which you can find out about for yourself

Warning: be wary of Makefiles you find on the Web, which are full of unnecessary, confusing, obsolete, and fragile gunge

Often, this is to do with compiling modules separately - I suggest you don't do this unless (a) compilation starts to take too long and (b) you understand everything