-`-fpie -Wl,-pie`: enable full ASLR(address space layout randomization) for better security
-`-fpie -Wl,-pie`: enable full ASLR(address space layout randomization) for better security
## Build Automation
Build automation involves automating the process of compiling code into libraries and executables. This can be a very complex process for large projects.
For large programs, recompiling all the pieces of the program can be very time consuming. If we only recompile the files that have changed, we can save a lot of time.
`Make` is such a build automation tool that solves those problems for us. `Make` and its variants are available on Linux, MacOS and Windows.
### Makefile
`Make` uses a file called `Makefile` which contains declarative rules. We can use this language to to tell `Make` what we want.
You can invoke the `Make` program via the executable named `make`.
`target` can be the name of a file that needs to created or a "phony" name that can be used to specify a certain action.
`prerequisites` are those files that must exist before the target can be successfully created.
And the `commands` are those shell commands that will create the target from the prerequisites. Each command must be indented with a tab.
For example, here is a rule for compiling a C file into a object file:
```makefile
foo.o:foo.c foo.h
gcc-cfoo.c
```
#### Automatic Variables
These are the variables that allow you to refer to the same name defined in `target` or `prerequisite`:
```makefile
hello:p1 p2
# Outputs "hello", since this is the target name
echo$@
# Outputs all prerequisites newer than the target
echo$?
# Outputs all prerequisites
echo$^
# Outputs the first prerequisite
echo$<
touchhello
p1:
touch p1
p2:
touchp2
clean:
rm-fhellop1p2
```
#### Marcos/Variables
`Make` allows you to use macros, also called variables. These are defined using `=` pairs. It is traditional to use upper case letters in variable names:
```makefile
CFLAGS=-O2-Wall
CC= gcc
```
There is a bunch of built-in variables, but you can overwrite them to suit your needs.
#### Implicit Rules
Implicit rules tell `Make` how to use customary techniques so that you do not have to specify them in detail when you want to use them.
For example, there is an implicit rule for C compilation:
-`filename.o` is made automatically from `filename.c` with a command of the form `$(CC) -c $(CPPFLAGS) $(CFLAGS) $^ -o $@`
- The executable `filaname` is made automatically from `filename.o` with the command `$(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@`
The built-in implicit rules use several variables in their recipes so that, by changing the values of the variables, you can change the way the implicit rule works.
Here is an example of using the implicit rules:
```makefile
CC= gcc # Flag for implicit rules
CFLAGS=-g# Flag for implicit rules. Turn on debug info
# Implicit rule #1: blah is built via the C linker implicit rule
# Implicit rule #2: blah.o is built via the C compilation implicit rule, because blah.c exists
blah:blah.o
blah.c:
echo"int main() { return 0; }"> blah.c
clean:
rm-f blah*
```
#### Pattern Rules
It's quite verbose to write for each file a specific rules. We can use pattern rules to specify a rules for a series of files that fall into the same category:
```makefile
# Define a pattern rule that compiles every .c file into a .o file
%.o:%.c
$(CC)-c$(CFLAGS)$(CPPFLAGS)$<-o$@
```
Pattern rules contain a `%` in the target. This `%` matches any nonempty string, and the other characters match themselves.
### Run make
Then you can invoke `make [target]` to generate the specified target described in `makefile`. The default command `make` will use the first target in the `makefile` if the target is not specified.
### Makefile example
A simple and typical `Makfile` looks like this:
```makefile
# Define required macros here
PROG= main
OBJS= main.o
CFLAG=-Wall-g
CC= gcc
INCLUDE=-I.
# binary target
$(PROG):$(OBJS)
$(CC)$(CFLAGS)$(INCLUDES)-o$@$(OBJS)
# implicit rule for building .o from .c
%.o:%.c
$(CC)-c-o$@$<$(CFLAGS)$(INCLUDES)
.PHONY:clean
# clean all the .o and executable files
clean:
rm-rf*.o core *.core $(PROG)
```
### Learning Materials
`Make` has lots of other useful rules which allows you to write a more generic `makefile` for your projects.
We won't cover those details in this document, but here are some useful materials if you are interested in learning more about `Make`: