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
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
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
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
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
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 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
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)
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
make
's dependency checking is
unnecessaryThe 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
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
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
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
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