Home  >  Article  >  Java  >  Parse the build rules of the Makefile

Parse the build rules of the Makefile

高洛峰
高洛峰Original
2016-11-22 14:24:511640browse

Makefile Edits countless source files in a project, which are placed in several directories according to type, function, and module. The makefile defines a series of rules to specify which files need to be compiled first, and even more complex Functional operation, because the makefile is like a shell script, in which operating system commands can also be executed.

The Makefile to be completed describes the compilation, connection and other rules of the entire project. These include: which source files in the project need to be compiled and how to compile them, which library files need to be created and how to create these library files, and how to finally generate the executable file we want. Although it may seem like a complicated matter, the benefit of writing a Makefile for a project is the ability to use a one-line command to complete "automated compilation" once one (usually multiple for a project) correct Makefile is provided. The only thing you have to do to compile the entire project is enter the make command at the shell prompt. The entire project is completely automatically compiled, greatly improving efficiency.

make is a command tool that interprets the instructions (should be said to be rules) in the Makefile. The Makefile describes the compilation order and compilation rules of all files in the entire project. Makefile has its own writing format, keywords, and functions. Just like C language has its own format, keywords and functions. And in the Makefile, you can use any command provided by the system shell to complete the desired work. Makefile (may be another file name on other systems) is used in most IDE development environments and has become a project compilation method.

The benefit of makefile is - "automated compilation". Once it is written, only one make command is needed, and the entire project is completely automatically compiled, which greatly improves the efficiency of software development. make is a command tool that interprets the instructions in the makefile. Generally speaking, most IDEs have this command, such as: Delphi's make, Visual C++'s nmake, and GNU's make under Linux. It can be seen that makefile has become a compilation method in engineering.

The most important and basic function of the Make tool is to describe the relationship between source programs through makefile files and automatically maintain the compilation work. The makefile file needs to be written according to a certain syntax. The file needs to explain how to compile each source file and connect it to generate an executable file, and it is required to define the dependencies between the source files. The makefile file is a common method for many compilers - including those under Windows NT - to maintain compilation information. In the integrated development environment, users only modify the makefile file through a friendly interface. In UNIX systems, it is customary to use Makefile as the makefile file. If you want to use other files as makefiles, you can use a make command option similar to the following to specify the makefile file:

$ make -f Makefile.debug _For example, a program named prog consists of three C source files filea.c, fileb .c and filec.c and the library file LS are compiled and generated. These three files also contain their own header files a.h, b.h and c.h respectively. Normally, the C compiler will output three object files filea.o, fileb.o and filec.o. Assume that filea.c and fileb.c both declare the use of a file named defs, but filec.c does not. That is, there is such a statement in filea.c and fileb.c:

include "defs"

Then the following document describes the interconnection between these files:

0 #It is an example for describing makefile Comment line

1 prog: filea.o fileb.o filec.o #Specify prog to be generated by linking three target files filea.o, fileb.o and filec.o

2 cc filea.o fileb.o filec.o -LS -o prog #How to create an executable file from the files prog depends on

3 filea.o : filea.c a.h defs #Specify the filea.o target file, as well as the .c and .h files and defs they depend on File

4 cc -c filea.c #How to create a target from the file on which the target depends, that is, how to create filea.o from filea.c

5 fileb.o : fileb.c b.h defs #Specify the fileb.o target file , as well as the .c and .h files and defs files they depend on

6 cc -c fileb.c #How to build the target from the files the target depends on, that is, how to build fileb.o from fileb.c

7 filec. o : filec.c c.h #Specify the filec.o target file, and the .c and .h files they depend on

8 cc -c filec.c #How to create a target from the files on which the target depends, that is, how to create a target from filec. cCreate filec.o

This description document is a simple makefile that uses the depth-first principle to execute compilation commands. Let’s make some basic explanations about the code in the above example: CC is a global variable, which specifies the compiler used by your Makefile. Generally, the default is gcc; the .o file is an intermediate code target file under Unix, just like in Windows Like the .obj files under Unix, the process of generating .o files under unix is ​​called compile, and the process of gathering countless .o files to generate executable files is called linking; sometimes you will see .a in the unix interface. file, that is Archive File, which is equivalent to the Library File under windows. The function of the .a file is: because there are too many source files (the above example refers to too many .c and .h files), the intermediate target file generated by compilation ( There are too many .o files), and the name of the intermediate target file needs to be clearly pointed out when linking, which is very inconvenient for compilation. Therefore, we need to package the intermediate target file, and this package is the .a file.

When the filea.c or a.h file is modified after compilation, the make tool can automatically recompile filea.o. If neither filea.c nor a.h has been modified between the two compilations, and filea.o If it still exists, there is no need to recompile. This dependency is especially important in program compilation of multiple source files. By defining this dependency, the make tool can avoid a lot of unnecessary compilation work. Of course, you can also use Shell scripts to achieve automatic compilation effects. However, Shell scripts will compile all source files, including source files that do not need to be recompiled, while the make tool can compile based on the last time the target was compiled and what the target depends on. Automatically determine which source file should be compiled based on the update time of the source file. _

Let us first take a rough look at the rules of Makefile. [3] target ... : prerequisites ... command ... ... Target: dependency execution command ... target is a target file, which can be an Object File or an execution file. It can also be a label. ① prerequisites are the files or targets required to generate that target. ② command is the command that make needs to execute. (Any Shell command) This is a file dependency, that is to say, one or more target files of target depend on the files in prerequisites, and their generation rules are defined in command. To put it bluntly, if there is more than one file in prerequisites that is newer than the target file, the command defined by command will be executed (command must start with the Tab key, otherwise the compiler will not recognize the command), reducing repeated compilation. Improved its software engineering management efficiency.

Makefile allows the use of simple macros to refer to source files and their related compilation information. Macros are also called variables in Linux. When quoting a macro, you only need to add the $ symbol before the variable, but it is worth noting that if the variable name is longer than one character, you must add parentheses () when quoting. Valid macro references are $(CFLAGS) $Z $(Z) where the last two references are identical. It should be noted that some predefined variables of macros. In Unix systems, the values ​​of four special macros $*, $@, $? and $< will change accordingly during the execution of commands, while in GNU make More predefined variables are defined in . Regarding the details of predefined variables, the use of macro definitions can free us from those tedious compilation options and bring great convenience to writing makefiles.

Main predefined variables of GNU make Predefined variables Meaning $* The name of the target file without extension. $+ All dependent files, separated by spaces, in order of appearance, may include duplicate dependent files. $< The name of the first dependent file. $? All dependent files, separated by spaces, whose modification date is later than the target's creation date. $@ The full name of the target. $^ All dependent files, separated by spaces, do not include duplicate dependent files. $% If the target is an archive member, this variable represents the archive member name of the target. For example, if the target name is (image.o), then $@ is and $% is image.o. AR The name of the archive maintenance program. The default value is ar. ARFLAGS Options for the archive maintenance program. AS The name of the assembler, default is as. ASFLAGS assembler options. CC The name of the C compiler, default is cc. CFLAGS C compiler options. CPP The name of the C precompiler, default value is $(CC) -E. CPPFLAGS C precompilation options. CXX C++ compiler name, default is g++. CXXFLAGS C++ compiler options. FC The name of the FORTRAN compiler. The default value is f77. FFLAGS FORTRAN compiler options. Makefile compares the file on the right side of the colon in the format of file name: file name to see if it is newer than the file on the left. If it is updated, the next line of program code is executed. Therefore Makefile can associate files


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn