Make is a very important compilation command in both Linux and UNIX environments. Make or make install is often used for project development and application software installation. With the make tool, we can break down large development projects into multiple modules that are easier to manage. For an application that includes hundreds of source files, by using make and makefile, You can streamline the complex relationships between various source files. In addition, if so many source files need to be compiled by typing the GCC command every time, it would be a disaster for programmers. The Make tool can automatically complete compilation, and only compile the part that the programmer modified after the last compilation. Therefore, the effective use of make and makefile tools can greatly improve the efficiency of project development. After you have mastered make and makefile, you will not be overwhelmed by the application software in Linux.
Unfortunately, this powerful but extremely complex compilation tool is not described in detail in many books about Linux applications. Here I will introduce make and its description file makefile in detail.
Makefile
The most important and basic function of the make tool is to use the MAKEFILE file to describe the relationship between source programs and automatically maintain the compilation work. The MAKEFILE file needs to be compiled according to a certain syntax. The file must describe how to compile each source file and generate an executable file, and define the dependency between the source files. Makefile is a common method for many compilers-including compilers in Windows NT-to maintain compilation information. It is only possible for users to modify makefile files on a friendly interface in the integrated development environment.
In Unix systems, makefile is used as a makfile. If you want to use other files as makefile, you can use the 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 library files are compiled and generated by ls. These three files also contain their own header files. h, B. H and C. h. Generally, the C compiler outputs three target files: filea. O, fileb. O, and filec. O. Assume that filea. C and fileb. C both need to declare that a file named defs is used, but filec. C does not. That is, the statement # include "defs" is included in filea. C and fileb. C"
The following documents describe the relationships between these files:
# It is a example for describing makefile
Prog: filea. O fileb. O filec. o
CC filea. O fileb. O filec. O-ls-O prog
Filea. O: filea. c a. H defs
CC-C filea. c
Fileb. O: fileb. c B. H defs
CC-C fileb. c
Filec. O: filec. C. H
CC-C filec. c
This description file is a simple MAKEFILE file.
The preceding example shows the behavior comment line with the first character. The first non-annotation row specifies that the prog is generated by the three target files filea. O, fileb. O, and filec. o. The third line describes how to create an executable file from the file on which prog depends. The following lines 4, 6, and 8 specify three target files, as well as the. C and. H files they depend on, and defs files. Lines 5, 7, and 9 specify how to create a target from the file on which the target depends.
When filea. C or. if the H file is modified after compilation, the make tool can automatically recompile filea. o. If the filea. C and. H is not modified, and test. if O still exists, there is no need to re-compile it. This dependency is particularly important in the compilation of multi-source files. With this dependency definition, the make tool can avoid many unnecessary compilation tasks. Of course, the use of shell scripts can also achieve the effect of automatic compilation, but the shell script will compile all the source files, including those that do not need to be re-compiled, the Make tool can automatically determine which source file to compile based on the last Compilation Time of the target and the Update Time of the source file on which the target depends.
Makefile, as a description, generally includes the following content:
◆ Macro definition
◆ Dependency between source files
◆ Executable commands
Makefile allows you to use a simple macro to refer to the source file and its related compilation information. In Linux, macros are also called variables. When referencing a macro, you only need to add the $ symbol before the variable, but it is worth noting that if the length of the variable name exceeds one character, you must add parentheses () When referencing ().
The following are valid macro references:
$ (Cflags)
$2
$ Z
$ (Z)
The last two references are exactly the same.
Note that some macro pre-defined variables, in Unix systems, $ *, $ @, $? And $ <the values of the four Special macros change accordingly during command execution, while more predefined variables are defined in GNU make. With regard to the details of predefined variables, the use of macro definitions can separate us from those tedious compilation options, making it very convenient to compile makefile files.
# Define a macro for the object files
Objects = filea. O fileb. O filec. o
# Define a macro for the library file
Libes =-ls
# Use macros rewrite makefile
Prog: $ (objects)
CC $ (objects) $ (libes)-O prog
......
At this time, if you execute the make command without parameters, the three target files and the library files will be connected. However, if you run the make command with the new macro definition:
Make "libes =-ll-ls"
The macro definition after the command line overwrites the macro definition in the MAKEFILE file. If ll is also a library file, the make command will connect the three target files and the two library files LS and LL.
The constant null is not clearly defined in Unix systems, so the following macro definition is used to define a Null String:
Stringname =
Make command
After the make command, the macro definition can be displayed, and other command line parameters can be used to specify the target file to be compiled. The standard format is:
Target1 [TARGET2…] : [:] [Dependent1…] [; Commands] [#…]
[(Tab) commands] [#…]
The part in the middle of the square brackets indicates the option. Targets and Dependents can contain characters, numbers, periods, and "/" symbols. In addition to references, commands cannot contain "#" or line breaks.
In general, the command line parameter contains only one ":". In this case, the command sequence is generally related to the description line of the dependency between some definition files in the MAKEFILE file. If the descriptive lines related to the target are specified with the relevant command sequence, execute these related Command commands, even in the semicolon and (Tab) the following aommand field may even be null. If no command is specified for the lines related to the target, the system will call the default target file generation rule.
If the command line parameter contains two colons ":", the command sequence may be related to all the lines in the makefile that describe the file dependency. At this time, the related commands directed to the description line related to the target will be executed. The build-in rule is also executed.
If a non-"0" error signal is returned when the command is executed, for example, the wrong target file name or the command string with a hyphen appears in the MAKEFILE file, the make operation is generally terminated. However, if the make operation carries the "-I" parameter, make ignores this error signal.
Make contains four parameters: Flag, macro definition, description file name, and target file name. The standard format is:
Make [flags] [macro definitions] [targets]
The flags option in UNIX System and Its Meaning are:
-F file specifies that the file is a description file. If the file parameter is a "-" character, the description file points to the standard input. If the "-F" parameter is not specified, the system uses makefile or makefile in the current directory as the description file by default. In Linux, the GNU make tool searches for makefile files in the current working directory in the order of gnumakefile, makefile, and makefile.
Third floor
-I ignore the error message returned by the command execution.
-S silence mode. No command line information is output before execution.
-R prohibits the use of build-in rules.
-N: in non-execution mode, all execution commands are output but not executed.
-T update the target file.
-The Q make operation returns the status information of "0" or not "0" based on whether the target file has been updated.
-P outputs the description of all macro definitions and target files.
-D debug mode: outputs detailed information about the file and detection time.
The common options of the make flag in Linux are slightly different from those in UNIX systems. Below we only list different parts:
-C dir changes to the specified directory dir before reading makefile.
-I dir: when other makefile files are included, use this option to specify the search directory.
-H help text block, show all make options.
-W displays the working directory before and after makefile processing.
You can use the target parameter in the command line parameter to specify the targets to be compiled by make and allow simultaneous definition of multiple targets for compilation, during the operation, the target Files specified in the target option are compiled sequentially from left to right. If no target is specified in the command line, the system default target points to the first target file in the description file.
In general, the makefile also defines the clean object, which can be used to clear intermediate files in the compilation process, for example:
Clean:
Rm-f *. o
When you run make clean, the RM-f *. O command is executed to delete all intermediate files generated during compilation.
Implicit rules
The Make tool contains built-in or implicit rules that define how to create specific types of targets from different dependent files. UNIX systems generally support implicit rules based on file extensions, that is, filename suffixes. This suffix rule defines how to convert a file with a specific filename suffix (for example, a. c file) into a file with another filename suffix (for example, a. o file ):
. C:. o
$ (CC) $ (cflags) $ (cppflags)-c-o $ @ $ <
The default common file extensions in the system and their meanings are:
. O target file
. C source file
. F Fortran source file
. S Assembly source file
. Y YACC-C source syntax
. L Lex source syntax
In earlier Unix systems, YACC-C source syntax and Lex source syntax were also supported. During the compilation process, the system first looks for the files related to the target file in the MAKEFILE file. c file, if there is a dependency with it. Y and. l file, first convert it. compile the c file and generate the corresponding one. o file; if there is no target-related. c files and only related. Y file, the system will compile directly. Y file.
In addition to suffix rules, GNU make also supports another type of implicit rules-pattern rules. This type of rule is more common, because pattern rules can be used to define more complex dependency rules. The Pattern Rule looks very similar to a regular rule. However, a % sign is added before the target name and can be used to define the relationship between the target and the dependent files, for example, the following pattern rule defines how to convert any file. c file to file. o file:
%. C: %. o
$ (CC) $ (cflags) $ (cppflags)-c-o $ @ $ <
# Example #
The following provides a comprehensive example to explain how to execute the makefile and make commands. The make command not only involves the C source file but also the YACC syntax. This example is from "UNIX programmer's Manual 7th edition, Volume 2a" page 283-284
The following describes the specific content of the file:
# Description file for the make command
# Send to print
P = und-3 | OPR-R2
# The source files that are needed by Object File