Makefiles tell make how to compile and concatenate source files by writing an elegant Makefile that makes it easy to manage the development of a large program
This article is the first of my personal blog: Jax Young’s blog can be visited if you have time 🙂
1. make
Make is commonly used to manage the development of C programs. By writing a Makefile you can automatically compile the connection from the modified file by typing make on the command line, instead of typing a long list of compile instructions each time. Make is not limited to compiling C programs. You can do almost anything you want with shell scripts.
2. Makefile
Make is a nice thing to use, but it needs to be configured, but it’s really easy to configure. You just write a Makefile and put it in your working directory, or make it a Makefile, depending on your preference. Let’s write a simple Makefile to see how it works.
2.1 Rules
The most basic part of a Makefile is the rules. If you can write rules, you can use make.
# rule
target ... : prerequisite ...
recipe Note that it must start with Tab.Copy the code
A rule usually consists of three parts: target, dependent document and recipe. The goal means that the rule will generate documents, the dependent document is the document needed for the rule to operate, and the step is the command that the rule will actually operate. Let’s take a look at the following code to understand what they do:
# Makefile
# rule0
hello.out : hello.c util_1.o util_2.o
cc -o hello.out hello.c util_1.o util_2.o
# rule1
util_1.o : util_1.c helper.h
cc -c util_1.c
# rule2
util_2.o : util_2.c helper.h
cc -c util_2.c
Copy the code
Write this code in the Makefile and run make:
$ make
# shell will execute
$ cc -c util_1.c helper.h
$ cc -c util_2.c helper.h
$ cc -o hello.out hello.c util_1.o util_2.o
Copy the code
If you run make without arguments, it will run the first rule. In this case, make checks to see if all dependent files exist, looks for a rule for missing files, executes a rule for missing files, and raises an error interrupt if none exists. So we’ll see above that rule0 is executed after rule1 and rule2 are run. Make is also smart. If your source file changes, for example, if you modify util_1.c and then make util_1.o, even if util_1.o already exists, it will re-compile rule1 to generate a new util_1.o.
2.2 Implicit rules
Because compiling source files to generate object files is a very frequent operation, make has built-in implicit rules to simplify the writing of these rules, such as:
# You can take the previous one
util_1.o : util_1.c helper
cc -c util_1.c
util_2.o : util_2.c helper
cc -c util_2.c
# written
util_1.o util_1.o : helper
Copy the code
Since the target suffix is.o, make knows that you will execute cc-c example.c to compile, so you only need to specify other dependency files at the end, and you can organize rules around dependency files. Instead of recompiling two files at once because one is missing, make will automatically select one, so there’s no doubt about make’s intelligence.
2.3. The PHONY tag
Make can do a lot more than compile build files, such as cleaning up working directories. As usual, let’s start with a piece of code:
# omits rules previously written. PHONY: clean clean: -rm hello. Out -rm util_1.o util_2.0Copy the code
To run this code, just type make clean. Because this is a pure task and does not require file generation, we tell make not to treat clean as a file using the.phony tag to avoid errors caused by a real clean file. The – in -rm tells make to continue with subsequent commands even if this command fails. If you do not add -, if the hello. Out file does not exist, then executing rm hello.out will return an error, which will cause make to exit and the subsequent commands will not be executed, while adding – will ignore the error and continue.
2.4 variable
Another way to simplify code is to define variables. Makefile variables are used in the same way as shell variables, but with Spaces around the equals sign, for example:
TARGET = hello.out
OBJS = util_1.o util_2.o
$(TARGET) : hello.c $(OBJS)
cc -o $(TARGET) hello.c $(OBJS)
$(OBJS) : helper.h
Copy the code
I’m not going to explain this because it’s too simple. Just look at it.
3. Summary
This is the end of this article, just a brief introduction to the basic functions of Makefile. In fact, there are many complex functions, but I have not been in touch with Make for a long time, and I have limited energy, so I will expand it again when I have the opportunity.
Here is a code from the official make documentation without explanation. It can be used for reference:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
Copy the code
4. Reference
GUN make
Make quick start