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.
Hello World
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
basic format
# 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 #.
operation check
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
clean
that do not generate files but only execute tasks.- By stating
.PHONY: clean
, it indicates that the target does not generate files.
- By stating
Please create src1.txt
and src2.txt
before executing the make command.
$ cat src1.txt
hello src1
$
$ cat src2.txt
hello src2
$
$ ls
Makefile src1.txt src2.txt
Execute make.
$ 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 src1.txt
.
$ 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.