The syntax of makefiles (makefile syntax ):
Makefile mainly includes two aspects: 1. A set of dependencies 2. Rules
A simple MAKEFILE file: makefile1
MyApp: Main. o2. O3. O gcc-O MyApp main. o2. O3. Omain. O: Main. c a. H gcc-C main. c2. O:2. C a. h B. H gcc-C2. C3. O:3. C B. H C. H gcc-O3. C
1. A group of Dependencies:
Dependency defines the final applicationProgramThe relationship between each file and the source file. For example, the above final application (executable program MyApp) depends on the file main. O, 2.o, and 3.o. Similarly, Main. O depends on Main. C and A. H.
Dependency: first write the target name, followed by a colon, followed by a space or tab, finally, a list of files separated by spaces or tabs (these files are used to create the target file ). Above: MyApp: Main. O 2.o 3.o
2. Rules
The rule defines how the target is created. Above: gcc-O MyApp main. O 2.o 3.o
Here is a very strange and unfortunate syntax phenomenon: the space is different from the tab. The row where the rule is located must start with a tab, and it cannot be used with a space. If the tab is missing, the make command will not work normally. It will remind you that the tab is missing ).
3. Make makefile
If the makefile is not the default file name makefile, makefile, or gnumakefile, add the-F option when calling the make command.
Now try to create the MAKEFILE file:
First, create a three-header file (for simple files, all are empty files ):
Touch a. h
Touch B .h
Touch C. H
Then create the c file:
Main. C is as follows:
/*Main. c*/# Include<Stdlib. h># Include"A.h"Extern VoidFunction_two ();Extern VoidFunction_three ();IntMain () {function_two (); fucntion_three (); exit (exit_success );}
2. C:
/*2. c*/# Include<Stdio. h># Include"A.h"# Include"B. H"VoidFunction_two () {printf ("Hello");}
3. C:
/*3. c*/# Include<Stdio. h># Include"B. H"# Include"C. h"VoidFunction_three () {printf ("World \ n");}
Run the make command:
Make-F makefile1
Run the following command:
Gcc-C main. c
Gcc-C2. C
Gcc-C3. C
Gcc-O MyApp main. o2. O3. O
An executable file named MyApp is generated to run MyApp.
./MyApp
Running result: Hello World
If B. H is updated, what will happen to make again,
Touch B .h
Make-F makefile1
Run the following command:
Gcc-C2. C gcc-C3. C gcc-O MyApp main. o2. O3. O
It can be seen that the targets dependent on B. H are all re-compiled, and the main. O independent of B. H does not need to be re-compiled, which is also the advantage of make.
Comments in makefile
The comments in the MAKEFILE file are switched to #, and the end of this line is always continued.
Macros in makefile
Macros in the MAKEFILE file are equivalent to # define in C, and the benefit is self-evident.
Define macro: macroname = value in makefile
Macro reference: $ (macroname) or $ {macroname}. To set the value of a macro to null, leave the value after the equal sign (=) blank.
A makefile with macors: makefile2
ALL: MyApp # Which compilercc = GCC # Where are include file keptinclude = . # Options For Developmentcflags =-G-wall-ANSI # options For Release # cflags =-O-wall- Ansimyapp: Main. o 2 . O 3 . O $ (cc) -O MyApp main. o 2 . O 3 . Omain. O: Main. c a. h $ (cc) -I $ (include) $ (cflags )- C main. c 2 . O: 2 . C a. h B. H $ (cc) -I $ (include) $ (cflags)-C 2 . C 3 . O: 3 . C B. H C. H $ (cc) -I $ (include) $ (cflags)-C 3 . C
Delete the old Installation File and create a new installation file using the new MAKEFILE file:
RM *. O MyApp make-F makefile2
Run the following command:
Gcc-I.-G-wall-ANSI-C main. c gcc-I.-G-wall-ANSI-C2. C gcc-I.-G-wall-ANSI-C3. C gcc-O MyApp main. o2. O3. O
Run the executable file MyApp
./MyApp
Running result: Hello World
The make command replaces $ (CC), $ (cflags), and $ (include) with the corresponding macro definition.
Multiple targets can be specified at all (multiple executable files can be generated), for example, all: myapp1 myapp2.
Pseudo target:
A pseudo-target is not a file, that is, it does not generate an executable file such as MyApp. It is just a tag, so we cannot execute it (./MyApp) Like the executable file MyApp ). So how to execute it and what is its function? See makefile3 below:
ALL: MyApp # Which compilercc =GCC # Where are include file keptinclude = . # Options For Developmentcflags =-G-wall- ANSI # options For Release # cflags =-O-wall- Ansimyapp: Main. o 2 . O 3 . O $ (cc) -O MyApp main. o 2 . O 3 . Omain. O: Main. c a. h $ (cc) -I $ (include) $ (cflags )- C main. c 2 . O: 2 . C a. h B. H $ (cc) -I $ (include) $ (cflags)-C 2 . C 3 . O: 3 . C B. H C. H $ (cc) -I $ (include) $ (cflags)-C 3 . Cclean: -Rm main. o 2 . O3 . O MyApp
Makefile3 adds
Clean:-Rm main. o2. O3. O MyApp
Here, "clean" is a pseudo-target. To express it as a pseudo-target, it is generally written as follows:
. Phnoy: cleanclean:-Rm main. o2. O3. O MyApp
Delete the old installation and use makefile3 to make again.
RM *. O MyApp make-F makefile3
It is found that the makefil2 command is the same as the above.
In fact, the following command is the same as RM *. O MyApp.
Make-F makefile3 clean
It can be seen that the pseudo target must display the call.
Built-in rules:
If the makefile is called makefile, makefile, or gnumakefile, instead of the stream makefile1 and makefile2 as above, you do not need to perform the following command:
Make
Run the following command to run the pseudo-target clean command:
Make claen
Suffix and pattern rules:
The above files are all. c files. Suppose they are. cpp files.
To add a new suffix rule, you must first add a statement to the MAKEFILE file to tell the make command the new suffix name. Then you can define the rule with the new suffix of the primary device. Make uses special syntax
. <Old_suffix>. <new_suffix>
To define a general rule. With this rule, you can create a file with a new suffix from a file with an old suffix and keep the first half of the original file.
The following is a snippet of the MAKEFILE file. It uses a new general rule to compile the. cpp file into a. o file.
. Suffixes:. cpp. cpp. O: $ (cc)-XC ++ $ (cflags)-I $ (include)-C $ <
Special dependency. cpp. O: Tell make that the following rule is used to convert a file whose suffix is. cpp to a file whose suffix is. O.
-The XC ++ flag indicates that the GCC compiler is a C ++ source file.
$ <Is an automation variable, indicating the name of the current dependent file. There are several important automation variables:
$ @ Indicates the name of the current target.
$? Indicates that the current target is more dependent on the file list than the current target file.
$ * Indicates the name of the current dependent file that does not include the suffix.
The same principle is achieved through the available wildcard %:
%. Cpp: %. O $ (cc)-XC ++ $ (cflags)-I $ (include)-C $ <
Use make to manage the function library
The function library is actually a file, usually suffixed with. A (archive). This file contains a group of target files.
Put the files 2. o and 3. O in the library mylib.:
ALL: MyApp # Which compilercc = GCC # Where are include file keptinclude = . # Options For Developmentcflags =-G-wall-ANSI # options For Release # cflags =-O-wall- ANSI # local librariesmylib = Mylib. amyapp: Main. o $ (mylib) $ (cc) - O MyApp $ (mylib): $ (mylib )( 2 . O) $ (mylib )( 3 . O) Main. O: Main. c a. H 2 . O: 2 . C a. h B. H 3 . O:3 . C B. H C. hclean: -Rm main. o 2 . O 3 . O MyApp $ (mylib)
Where
Main. O: Main. c a. H2. O:2. C a. h B. H3. O:3. C B. H C. H
Use default rules.
Run the following command to test makefile 4 of the new version:
Rm-F MyApp *. O mylib. amake-F makefile4
Run the following command:
Gcc-g-wall-ANSI-c-O main. O main. c gcc-G-wall-ANSI-c-o2. O2. C
Ar RV mylib.2. O-2. O gcc-G-wall-ANSI-c-o3. O3. C
Ar RV mylib.3. O-3. O gcc-O MyApp main. O mylib.
The syntax used to manage the function library is lib (file. O), which means that the target file. O is stored in library Lib.. The make command uses a built-in rule to manage the function library. The common form of the rule is as follows:
. C. A: $ (cc)-C $ (cflags) $ <$ (AR) $ (arflgas) $ @ $*. O
The default values of macro $ (AR) and $ (arflags) are generally the command AR and option RV respectively. You can use man ar to view the meaning of related options.
The above syntax tells make that to get the. A file from the. c file, it must apply two rules:
1. $ (CC)-C $ (cflags) $ <the source file must be compiled to generate the target file
2. $ (AR) $ (arflgas) $ @ $ *. o use the AR command to add the new target file to the function library.
Finally, I posted an example of makefile used for my internship in the fcitx Input Method Project:
Cc = Gcccxx = G ++ Cflags =-Ifctix-IUI-I .- Wallcxxflags =-Ifcitx-IUI-I .- Wallbuild =Buildtarget = Inputfltk_path = '~ /Workspace/fltk- 1.3 . 0 /Fltk-config -- cxxflags -- Ldflags 'C _ SRCS = Fcitx/Py. c fcitx/pymap. c fcitx/ Punc. c cpp_srcs = Main. cpp UI/mwbutton. cpp UI/mwlabel. cpp UI/popupwidget. cpp fcitx/keyboardwidget. cpp fcitx/ Fcitx. cppobjs = $ (Build)/main. o $ (build)/Py. o $ (build)/pymap. o $ (build)/punc. o $ (build)/mwbutton. o $ (build )/ Mwlable. O \ $ (build) /Popupwidget. o $ (build)/keyboardwidget. o $ (build )/Fcitx. otarget: objs $ (cxx) $ (objs) -O $ (target )- L $ (fltk_path) Rm - RF buildobjs: $ (CC) $ (cflags) - C $ (c_srcs) $ (cxx) $ (cxxflags) $ (fltka_path) - C $ (cpp_srcs) If ! [- D build]; then mkdir build; FI mv * . O $ (build) All: Target dectsdicts_dir =/Home/Edan/mnt/ Input_dictdicts: If ! [-D $ (dicts_dir)]; then mkdir $ (dicts_dir); CP. /Dicts /* $ (Dicts_dir) If. Phony: thenclean: Rm $ (objs) $ (target)
Refference:
(1) Linux programming-Neil Matthew Richard stones development tools in Chapter 4th of version 9th
(2) Write makefile with me-Chen Hao
(3) makefile official documentation: http://www.gnu.org/software/make/manual/make.html#Introduction