# 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