ArticleDirectory
Author: vamei Source: http://www.cnblogs.com/vamei welcome reprint, please also keep this statement. Thank you!
When compiling a large project, there are often many target files, library files, header files, and final executable files. Different files existDependency(Dependency ). For example, when we compile with the following command:
$ Gcc-c-o test. O test. c
$ Gcc-O helloworld test. o
The executable helloworld depends on test. O for compilation, while test. O depends on test. C.
Dependency
When compiling a large project, we often need to call the compiler many times to gradually compile the entire project based on dependencies. This method is bottom-up, that is, the downstream files are compiled first, and then the upstream files are compiled.
The Make tool in UNIX systems is used to automatically record and process dependencies between files. Instead of entering a large number of "GCC" commands, we only need to callMakeYou can complete the entire compilation process. All dependencies are recorded in the makefile text file. We only need make helloworld. Make will find all the dependencies required to compile the file from top to bottom based on the dependency, and finally compile the file from the bottom up.
(Make has multiple versions. This article is based on GNU make. Make will automatically search for makefile, makefile, or gnumakefile in the current directory)
Dependency
Basic Concepts
We use an example C language file:
# Include <stdio. h>/** By vamei * test. C for makefile demo*/IntMain () {printf ("Hello world! \ N");Return 0;}
Below is a simple makefile
# Helloworld is a binary fileHelloworld: Test. o
Echo "good"Gcc-O helloworld test. otest. O: Test. cGcc-C-O test. O test. c
Observe the makefile above
- #The starting line of the number isComment row
- Target: prerequisiteIs a dependency, that isTarget File(Target) depends onPrerequisite File(Prerequisite ). There can be multiple prerequisite files separated by spaces.
- The<Tab> indentRows are implemented by dependency.OperationIs a normal Unix Command. A dependency can be attached with multiple operations.
To put it bluntly, it is:
- Do you want helloworld? Then you must have test. O and perform the attached operations.
- If there is no test. O, you must search for other Dependencies and create test. O.
We execute
$ Make helloworld
To create helloworld.
Make is a process of recursive creation:
- Base Case 1: If no prerequisite file is specified in the current dependency, perform the operation directly.
- Base Case 2: If the current dependency describes the target file, and the prerequisite file required by the target file already exists, and the prerequisite file does not change with the previous make (based on the recent write time ), the dependency is also directly executed.
- If the prerequisite file required for the current target file dependency does not exist, or the prerequisite file changes, you can refer to the file as a new target file, find the dependency, and create the target file.
Dotted Line: dependency search
The above are the core functions of make. With the above functions, we can record all dependencies and related operations in the project, and compile with make. The following content is an extension of this core content.
Macro
Macro (macro) can be used in make ). Macros are similar to text variables. For example, the following CC:
Cc = gcc
# Helloworld is a binary fileHelloworld: Test. o
Echo "good"$ (Cc)-O helloworld test. otest. O: Test. c$ (Cc)-C-O test. O test. c
We use CC to represent "GCC ". In makefile, use $ (CC) to call macro values. Make will replace $ (CC) with the macro value (GCC) at runtime ).
Shell environment variables can be called directly as macros. If the same custom macro also has environment variables of the same name, make will give priority to the custom macro.
(You can use $ make-e helloworld to prioritize environment variables)
Similar to the Macros in C language, Macros in makefile can easily manage fixed texts and facilitate replacement operations. For example, when we use the ifort compiler in the future, we only need to change the macro definition:
Cc = ifort
You can.
Internal macro
Make has internal defined macros and can be used directly.$ @Contains the target file name with the current dependency$ ^The prerequisite file that contains the current target:
Cc = GCC # helloworld is a binary filehelloworld: test. O echo $ @ $ (CC)-o $ @ $ ^ test. o: test. C $ (CC)-c-o $ @ $ ^
Internal macro function
$ *The target file name in the current dependency, excluding the suffix.
$ *The prerequisite file for the change in the current dependency
$Character "$"
If the target or prerequisite file is a complete path, you can attachDAndFTo extract the folder and file name, such$ (@ F)Indicates the part of the target file name.
Suffix dependency
Use in makefile
. Suffixes:. c. o
. C and. O are suffixes.
We can use the suffix dependency method, for example:
Cc = GCC. suffixes :. c. o. c. o: $ (CC)-c-o $ @ $ ^ # ------------------------ # helloworld is a binary filehelloworld: test. O echo $ @ $ (CC)-o $ @ $ ^ test. o: test. c
We define. CAnd. OSuffix. There is a suffix dependency. C. O:. The former is the premise, and the latter is the goal. (Note: the order of dependency is different from that of General dependency)
The preceding test. O and test. C are dependent, but no operation is performed. Make will find that the dependency is in line with the. c. o suffix dependency, and execute the operation after the suffix dependency.
If a project is large, suffix dependency is very useful. Files that comply with the suffix dependency often have similar operations. We can use the suffix dependency to represent these operations to avoid repeated input.
Others
The resumable Line Character of makefile is\
The following dependencies are often defined in makefile:
ALL:
If the file name is not followed after make, the dependency is executed.
Clean:
It is often used to clear historical files.
For example:
Cc = GCC. suffixes :. c. o. c. o: $ (CC)-c-o $ @ $ ^ # ------------------------ all: helloworld @ echo "all" # helloworld is a binary filehelloworld: test. o @ echo $ @ $ (CC)-o $ @ $ ^ test. o: test. cclean:-RM helloworld *. O
Note:@And above RM-. @ Command will not display the command itself. -Subsequent commands will ignore errors (for example, deleting nonexistent files ).
Summary
The core function of make is to implement compilation and management based on dependencies.
Other functions of make allow users to write makefiles more conveniently.
Reference
Http://oreilly.com/linux/excerpts/9780596100292/gnu-make-utility.html