This section describes how to use the make command, which is mainly used to compile source files by describing build dependencies in a file called Makefile.
First, let’s check the operation with a simple example.
Create a file named “Makefile” and write the following
xxx: echo 'Hello World' yyy: echo 'Good Bye'
xxx and yyy are called targets, and you specify them when executing the make command. If you execute without specifying the target, the topmost target will be executed.
$ ls Makefile $ $ make echo 'Hello World' Hello World $ $ make xxx echo 'Hello World' Hello World $ $ make yyy echo 'Good Bye' Good Bye $ $ make xxx yyy echo 'Hello World' Hello World echo 'Good Bye' Good Bye
How to write Makefile
# comment target: prerequisite recipe … …
- Usually, the target is the file you wish to generate.
- The preconditions specify the files on which the target depends.
- The recipe describes the commands to generate the files specified in the target.
- When writing a recipe, a tab character must precede the command.
- If an error such as
"Makefile:xx: *** missing separator. Stop."occurs, it is possible that the tab character is not used. Check to see if it is a tab character.
- Comments are written after #.
Let’s check the operation with a slightly more complex example. Write the following in the Makefile.
# comment app.txt: sub1.txt sub2.txt cat sub1.txt sub2.txt > app.txt sub1.txt: src1.txt cp -f src1.txt sub1.txt echo "hello sub1" >> sub1.txt @echo "wakuwaku" >> sub1.txt sub2.txt: src2.txt cp -f src2.txt sub2.txt echo "hello sub2" >> sub2.txt @echo "bank" >> sub2.txt .PHONY: clean clean: rm -f app.txt sub1.txt sub2.txt
- If you put
@at the beginning like
@echo "wakuwaku" >> sub1.txt, the command will not be displayed when make is executed.
- There are also targets like
cleanthat do not generate files but only execute tasks.
- By stating
.PHONY: clean, it indicates that the target does not generate files.
- By stating
src2.txt before executing the make command.
$ cat src1.txt hello src1 $ $ cat src2.txt hello src2 $ $ ls Makefile src1.txt src2.txt
$ make cp -f src1.txt sub1.txt echo "hello sub1" >> sub1.txt cp -f src2.txt sub2.txt echo "hello sub2" >> sub2.txt cat sub1.txt sub2.txt > app.txt
Check the generated file.
$ ls Makefile app.txt src1.txt src2.txt sub1.txt sub2.txt $ $ cat sub1.txt hello src1 hello sub1 wakuwaku $ $ cat sub2.txt hello src2 hello sub2 bank $ $ cat app.txt hello src1 hello sub1 wakuwaku hello src2 hello sub2 bank
Run make again.
$ make make: `app.txt' is up to date.
Nothing is executed. make compares the file modification date and time with the dependent files to avoid wasting builds that are not needed.
Execute the following command to update
$ echo "hello src1 updated" > src1.txt $ $ cat src1.txt hello src1 updated
Run make again.
$ make cp -f src1.txt sub1.txt echo "hello sub1" >> sub1.txt cat sub1.txt sub2.txt > app.txt $ $ cat app.txt hello src1 updated hello sub1 wakuwaku hello src2 hello sub2 bank
Only builds that depended on the updated file (
src1.txt ) were done.