Make is a very important compilation command, both in Linux and in the UNIX environment. Whether you are developing your own projects or installing applications, we often use make or makes install. With make tools, we can break down large-scale development projects into more manageable modules, and for an application that includes hundreds of source files, using the Make and makefile tools, you can easily and concisely straighten out the intricacies of each source file. And with so many source files, it would be a disaster for programmers to compile a gcc command every time. The Make tool automates the compilation process and compiles only the parts of the programmer that have been modified since the last compilation. Therefore, effective use of make and makefile tools can greatly improve the efficiency of project development. At the same time mastering make and Makefile, you will not face the Linux application software at a loss.
Unfortunately, in many books on Linux applications, this powerful but very complex compilation tool is not covered in detail. Here I will give you a detailed introduction to make and its description file makefile.
Makefile file?
The most important and basic function of the Make tool is to use the makefile file to describe the interrelationship between the source programs and to automatically maintain the compilation work. While the makefile file needs to be written in a certain syntax, the file needs to explain how to compile the individual source files and connect to build the executable file, and ask to define the dependencies between the source files. The makefile file is a common way for many compilers-including compilers under Windows NT-to maintain compilation information, but in an integrated development environment, the user modifies the makefile file through a friendly interface.
In UNIX systems, it is customary to use Makefile as a makfile file. If you want to use a different file as makefile, you can specify the makefile file with the Make command option similar to the following:
?
$ make-f makefile.debug?
For example, a program named Prog is generated by three C source files, FILEA.C, FILEB.C, and FILEC.C, and the library file LS compilation, which also contains its own header files A.h, B.h, and c.h, respectively. Typically, the C compiler will output three target files filea.o, FILEB.O, and FILEC.O. Suppose FILEA.C and FILEB.C both declare a file named Defs, but FILEC.C not. That is the statement in FILEA.C and FILEB.C:?
#include "defs"?
Then the following document describes 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 c.h?
Cc-c filec.c?
This description document is a simple makefile file.
Note from the above example that the first character is a # behavior comment line. The first non-commented line specifies that the prog is delivered by three target files FILEA.O, FILEB.O, and FILEC.O chains. The third line describes how to build an executable file from a file that prog depends on. The next 4, 6, and 8 lines specify three target files, along with the. C and. h files they depend on, and the Defs file. The 5, 7, and 9 lines specify how to set the target from the file the target depends on.
When the FILEA.C or A.H file is modified after compilation, the Make tool can automatically recompile the FILEA.O, and if the FILEA.C and A.H are not modified between the previous and two compilations, and TEST.O exists, there is no need to recompile. This dependency is especially important in program compilation of multi-source files. With this dependency definition, the Make tool avoids a lot of unnecessary compilation work. Of course, the use of shell scripts can also achieve the effect of automatic compilation, but the shell script will all compile any source files, including which do not need to recompile the source files, and make The tool can automatically determine which source file should be compiled based on the time of the Target's last compilation and the update time of the source file that the target depends on.
The makefile file as a description document generally needs to include the following:?
Macro definition?
Dependencies between source files?
An executable command?
Makefile allows the use of simple macros to refer to source files and their related compilation information, in Linux is also called the macro as a variable. When referencing 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, it must be parenthesized () at the time of reference.
Here are the valid macro references:?
$ (CFLAGS)?
$ $?
$Z?
$ (Z)?
The last two references are exactly the same.
Note that some of the predefined variables of the macro, in the UNIX system, $*, [email protected], $?, and $< four special macro values will change during the execution of the command, and in GNU make, more predefined variables are defined. With regard to the details of the predefined variables, the use of macro definitions can leave us out of those tedious compilation options and make it much easier to write 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?
......?
If you execute the make command without parameters, you will connect three target files and library files, LS, but if you have a new macro definition after the Make command:?
Make "libes=-ll-ls"?
The macro definition after the command line overrides the macro definition in the makefile file. If LL is also a library file, then the make command will connect three target files and two library files LS and LL.
?
There is no explicit definition of constant NULL in UNIX systems, so we want to define a null string using the following macro definition:?
Stringname=?
Make command?
Not only can macro definitions be present after the make command, but they can also be followed by other command-line parameters that specify the target files that need to be compiled. Its standard form is:?
target1 [Target2 ...]:[:][dependent1 ...] [; commands] [#...]?
[(tab) commands] [#...]?
The middle part of the square brackets represents the optional. Targets and dependents can contain characters, numbers, periods, and "/" symbols. In addition to references, commands cannot contain "#", nor does it allow line wrapping.
In the usual case, there is only one ":" in the command line argument, which is usually related to the description line of the dependencies between some definitions files in the makefile file. If the description rows associated with the target specify the relevant command sequence, then these related command commands are executed, even though the Aommand field after the semicolon and (tab) may even be null. If those rows that are associated with the target do not specify a command, then the system default target file generation rule is called.
If the command-line argument contains two colons "::", then this command sequence might be related to all the rows in makefile that describe the file dependencies. The related commands that are pointed to by the description line associated with the target are executed. The build-in rules will also be enforced.
If a non-"0" error signal is returned when a command command is executed, such as an incorrect target file name in the makefile file or a command string that begins with a hyphen, the make operation is generally terminated, but if make has a "-i" parameter, Make will ignore this type of error signal.
Make life itself can have four parameters: flag, macro definition, description file name and target file name. Its standard form is:?
make [flags] [macrodefinitions] [targets]?
The flags in the UNIX System Flags option and its meaning are:
?
The-f file specifies that the file file is a profile, and if the file parameter is a "-" character, the profile points to standard input. If there is no "-f" argument, the system will default to the current directory named makefile or a file named makefile as the description file. In Linux, the GNU make tool searches the current working directory for makefile files in the order of Gnumakefile, makefile, makefile.
-I ignores command execution to return an error message.?
-s silent mode, do not output the corresponding command line information before execution.
-R prohibits the use of build-in rules.?
-N Non-execution mode, which outputs all execution commands, but does not execute.?
-t updates the destination file.
The-Q make Operation returns status information for "0" or not "0" based on whether the target file has been updated.
-p outputs all macro definitions and destination file descriptions.?
-D debug mode, which outputs detailed information about the file and the time of the detection.
The common options for the make flag bit in Linux are slightly different from the Unix system, and we only have the different parts listed below:?
-C dir Changes to the specified directory dir before reading makefile.
-I dir Use this option to specify the search directory when you include other makefile files.
-H help block, showing all make options.
-W Displays the working directory before and after processing makefile.
By using target in command line arguments, you can specify the target to compile for make, and allow simultaneous definitions to compile multiple targets, and then compile the target file specified in the target option in order from left to right. If a target is not specified on the command line, the system default target points to the first target file in the description file.
In general, a clean target is also defined in makefile, which can be used to clear intermediate files during compilation, such as:?
Clean:?
Rm-f *.O?
When you run make clean, the rm-f *.o command is executed, and all intermediate files that are generated during compilation are eventually removed.
Implicit rules?
There are built-in or implicit rules in the Make tool that define how to establish a specific type of target from different dependent files. UNIX systems typically support an implicit rule that is based on the file name extension, which is the filename suffix. This suffix rule defines how to convert a file with a specific file name suffix (for example,. c files) to a file with another file name suffix (for example, an. o file):
?
. c:.o?
$ (CC) $ (CFLAGS) $ (cppflags)-c-o [email protected] $<?
The default common file name extension in the system and its meaning is:?
. o destination file?
. c C Source files?
. f Fortran Source files?
. s assembly source file?
. y yacc-c source syntax?
. l Lex Source syntax?
Yacc-c source syntax and Lex source syntax are also supported in earlier UNIX system systems. During the compilation process, the system will first look for the target file in the makefile file. c files, if there are any. y and. l files that are dependent on them, first convert them to. c files and then compile the corresponding. o files, and if there is no. c file associated with the target and only the associated. y file, the system will compile the. y file directly.
The GNU make supports another type of implicit rule-the pattern rule-in addition to the suffix rule. This rule is more common because schema rules can be used to define more complex dependency rules. A pattern rule looks very similar to a regular rule, but has a% number in front of the target name and can be used to define the relationship between the target and dependent files, for example, the following schema rule defines how to convert any of the file.c files to a FILE.O file:?
%.C:%.O?
$ (CC) $ (CFLAGS) $ (cppflags)-c-o [email protected] $<?
#EXAMPLE #?
A more comprehensive example is given below to further illustrate the execution of the makefile file and make command, where the makes command involves not only the C source file but also the YACC syntax. This example is selected from "Unix Programmer ' s Manual 7th Edition, Volume 2A" page 283-284?
Here's what the description file is about:?
#Description file for the Do command?
#Send to print?
p=und-3 | Opr-r2?
#The source files that is needed by object files?
files= Makefile version.c defs main.c donamc.c misc.c file.c \?
DOSYS.C gram.y lex.c gcos.c?
#The definitions of object files?
objects= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o?
Libes=-ls?
Lint= lnit-p?
Cflags=-O?
Make: $ (OBJECTS)?
CC $ (CFLAGS) $ (OBJECTS) $ (libes)-O make?
Size make?
$ (OBJECTS): Defs?
Gram.o:lex.c?
Cleanup:?
-rm *.o gram.c?
Install:?
@size Make/usr/bin/make?
CP Make/usr/bin/make; RM make?
#print recently changed files?
Print: $ (FILES)?
PR $? | $P?
Touch print?
Test:?
MAKE-DP | Grep-v Time>1zap?
/USR/BIN/MAKE-DP | Grep-v Time>2zap?
Diff 1zap 2zap?
RM 1zap 2zap?
LINT:DOSYS.C donamc.c file.c main.c misc.c version.c gram.c?
$ (LINT) dosys.c donamc.c file.c main.c misc.c version.c \?
Gram.c?
RM gram.c?
Arch:?
Ar uv/sys/source/s2/make.a $ (FILES)?
The command that the output will execute is usually defined in the description file as above. After the make command is executed, the output is:
?
$ make?
Cc-c version.c?
Cc-c main.c?
Cc-c donamc.c?
Cc-c misc.c?
Cc-c file.c?
Cc-c dosys.c?
Yacc gram.y?
MV Y.TAB.C GRAM.C?
Cc-c gram.c?
CC VERSION.O MAIN.O donamc.o misc.o file.o dosys.o gram.o \?
-ls-o make?
13188+3348+3044=19580b=046174b?
The final numeric information is the output of the Execute "@size make" command. The only reason for the output is that there is no command line, because the "@size make" command starts with "@", and this symbol suppresses the command line where it is printed.
The last few command lines in the description file are useful for maintaining compilation information. Where the "print" command line is to print out all the changed file names after the last "make print" command was executed. The system uses a 0-byte file called Print to determine the exact time to execute the Print command, while the macro $? points to the file name of the file that was modified after the print file was altered. If you want to specify that the print command is executed and the output is fed to a specified file, you can modify the macro definition for P:?
Make print "p= cat>zap"?
Most software in Linux provides the source code, not the ready-made executable file, which requires the user to configure and compile the source program according to the actual situation of the system and its own needs, before the software can be used. Only by mastering make tools can we really enjoy the free software world of Linux.
Make command in Linux/unix environment (GO)