# Makefile
[TOC]
# Introduction
## What is Makefile
The “Make” tool needs to get its knowledge of how to build a program from a file called the “makefile”. This makefile lists each of the non-source files and how to compute it from other files. When you write a program, you should write a makefile for it, so that it is possible to use “Make” to build and install the program.
## How to Install
### Ubuntu
```bash
apt-get install build-essential #Will install gcc, g++, make
```
### MacOS
```bash
xcode-select --install
```
### Windows
MinGW: https://sourceforge.net/projects/mingw/files/latest/download?source=files
## Simple Makefile
```cmake=
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
```
# Rules
## Simple Rules
```cmake=
target … : prerequisites …
recipe
…
…
#or like this:
targets : prerequisites ; recipe
recipe
…
```
- Target
- The targets are file names, separated by spaces.
- Wildcard characters may be used \(*, ?, \[...\], \~\)
- A name of the form a(m) represents member m in archive file a.
- Usually there is only one target per rule, but occasionally there is a reason to have more.
- Recipe
- The recipe lines start with a tab character
(or the first character in the value of the .RECIPEPREFIX variable).
- Because dollar signs are used to start _make_ variable references,
if you really want a dollar sign in a target or prerequisite you must write two of them, ‘\$\$’.
- If you have enabled *secondary expansion* and you want a literal dollar sign in the prerequisites list, you must actually write four dollar signs '\$\$\$\$'.
Examples :
```cmake=
foo.o : foo.c defs.h
cc -c -g foo.c
```
This rule says two things:
- How to decide whether foo.o is out of date: it is out of date if it does not exist, or if either foo.c or defs.h is more recent than it.
- How to update the file foo.o: by running cc as stated. The recipe does not explicitly mention defs.h, but we presume that foo.c includes it, and that is why defs.h was added to the prerequisites.
```cmake=
.SECONDEXPANSION:
ONEVAR = onefile
TWOVAR = twofile
myfile: $(ONEVAR) $$(TWOVAR)
```
The final result is that there are two prerequisites, `onefile` and `twofile`.
## Variables Assgin
```cmake=
immediate = deferred
immediate ?= deferred
immediate := immediate
immediate ::= immediate
immediate += deferred or immediate
immediate != immediate
define immediate
deferred
endef
define immediate =
deferred
endef
define immediate ?=
deferred
endef
define immediate :=
immediate
endef
define immediate ::=
immediate
endef
define immediate +=
deferred or immediate
endef
define immediate !=
immediate
endef
```
Comparison examples :
```cmake=
x = foo
y = $(x) bar
x = xyz
# the final value of y is xyz bar
```
```cmake=
x := foo
y := $(x) bar
x := xyz
# the final value of y is foo bar
```
## Wildcard
```cmake=
$(wildcard pattern…)
$(patsubst pattern, replacement, text)
$(patsubst %.c, %.o, x.c.c bar.c) #equals: x.c.o bar.o
```
## Automatic Variable
- `$@` : The file name of the target of the rule.
- `$<` : The name of the first prerequisite.
- `$^` : The names of all the prerequisites, with spaces between them.
- `$*` : The stem with which an implicit rule matches.
## Newline
### newline with whitespace
command: \<space\>\\
```cmake=
#object will be assign: abcdef<space>ghijkl<space>mnopqr
object = abcdef \
ghijkl \
mnopqr
```
### new line without whitespace
command: \$\\\<newline\>
```cmake=
#object will be assign: abcdefghijklmnopqr
object = abcdef$\
ghijkl$\
mnopqr$\
```
## include others Makefile
```cmake=
include filenames… #include others Makefile
-include filenames… #exclude others Makefile
#
# examples
#
include another_Makefile_name
include foo *.mk $(bar)
```
## Common Variables Name
```cmake=
CC = gcc -o # CC usually equals c compiler command
CFLAGS = -Wall # CFLAGS is c compiler arguments
OBJS = $(SRCS_C:.c=.o) $(SRCS_Y:.y=.o) #Need to be compile .o
```
## Common Phony Name
```cmake=
.PHONY: install
.PHONY: clean
```
* Two reasons of using `.PHONY` :
* To avoid a conflict with a file of the same name.
* To improve performance.
# Examples
# Reference
GNU make: https://www.gnu.org/software/make/manual/make.html