---
# System prepended metadata

title: Makefile

---

# 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