---
# System prepended metadata

title: Note about Makefile
tags: [C++, Linux, C]

---

# Note about Makefile
###### tags: `C` `C++` `Linux`

## Makefile?
Makefiles are used to help decide which parts of a large program need to be recompiled.

## make command:
On Unix-like operating systems, make is a utility for building and maintaining groups of programs (and other types of files) from source code.   In fact, make is not limited to programs. **You can use it to describe any task where some files must be updated automatically from others whenever the others change.** Prepare to use make, you should write a file named GNUmakefile, makefile, or Makefile(Make command will search these target in order.).

* make command syntex
    ```
    make [ -f makefile ] [ options ] ... [ targets ] ...
    ```
* Options
   https://www.computerhope.com/unix/umake.htm#syntax
* Examples

## Makefile Syntax
A makefile consists of a set of rules:
:::    success
targets: prerequisites
   <\tab>command  #not space!!!
   <\tab>command
   <\tab>command
:::

* The targets are file names, separated by spaces. Typically, there is only one per rule.
* The commands are a series of steps typically used to make the target(s). These need to **start with a tab** character, **not spaces**.
* The **prerequisites** are also **file names** which should be **separated by spaces**. These files need to exist before the commands for the target are run. These are also called **dependencies**.

:::info
Useful tip: cat -e -t -v makefile_name
This command can check if each command starts with a tab
if the command starts with ^I, this means there is a tab.
Ex: 
```shell=1
#command
cat -e -t -v makefile_name 
```
```shell=1
#output
test: test.o$
^Icc test.o -o test$ #this is ok
```
:::

#### Example
```she    
test: test.o # Third rule. if test not exists, run this when test.o exists
	cc test.o -o test
test.o: test.c # Second rule. if test.o not exists, run this when test.c exists
	cc -c test.c -o test.o
test.c: # First rule. If test.c not exist, run command.
	echo "int main() { return 0; }" > test.c 

clean:
	rm *.o *.c
	rm -f test
```

#### Variables:
* variables can only be **string**
* reference variable: ${} or $()
* Example:
    ```she    
    files = file1 file2
    x = dude
    test_files: $(files)
        echo "Look at this variable: " $(files)
        echo "Look at this variable again: " ${files}
        echo "Look at this variable again in bad practice: " $files
        echo "Look at x in bad practice: " $x
        touch some_file
    file1:
        touch file1
    file2:
        touch file2
    clean:
        rm -f file1 file2 some_file
    ```
    Output:
    ```shell
    echo "Look at this variable: " file1 file2
    Look at this variable:  file1 file2
    echo "Look at this variable again: " file1 file2
    Look at this variable again:  file1 file2
    echo "Look at this variable again in bad practice: " iles
    Look at this variable again in bad practice:  iles
    echo "Look at x in bad practice: " dude
    Look at x in bad practice:  dude
    touch some_file

    ```
    :::danger
    Danger: reference variable by $var is a bad idea. The previous example show that the output is expected in "x=dude" but is wrong in "files= file1 file2".
    :::
* Automatic variables(not finished: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html)
* Wildcard: * and %
    (star)* means searching in filesystem for matching filenames. 
    % means differently in three seperated situation:
    1.         When used in "matching" mode, it matches one or more characters in a string. This match is called the stem.
    2.         When used in "replacing" mode, it takes the stem that was matched and replaces that in a string.
    3.          % is most often used in rule definitions and in some specific functions.
    4.          The usage example will be exposed in the rules below.(please add url)
    Example:

    
        
       





## reference
Learn Makefiles With the tastiest examples: https://makefiletutorial.com/#makefile-cookbook
Makefile 語法和示範 : https://hackmd.io/@sysprog/SySTMXPvl

