Makefile Writing Primer

Source: Internet
Author: User

First of all, this article is based on the Chenhao blog related articles rewritten. The reason is that the article is too comprehensive, and this article extracted a few of the more practical, to a user's point of view to explain how to write makefile, and only limited to the Linux C language makefile, other not discussed. If you are interested in the original text, here is the link

I. INTRODUCTION of MAKEFILE

Makefile is a tool that helps us compile and link programs. As we all know, C programs need to preprocess, compile, and link several steps from the source file to an executable file. Under Windows, we have a variety of ides (like VS, Eclipse, codeblocks, etc.) to help us with this work, and all we have to do is click on a button. But in the Linux system, we have to use the command line to do these things, I believe you have some knowledge, such as to compile a name called MAIN.C, we want to enter the command Gcc-o main main.c. When the file is relatively young, you can also reluctantly deal with, once our project becomes larger, such as there are seven or eight source files, five or six header files, they contain references to each other, at this time it is very clumsy to use such a method. And makefile is to help us achieve something like the IDE midpoint button that function, it defines a series of rules to specify which files need to be compiled first, which files need to be compiled, and which files need to be recompiled.

Second, compiler compiler rules

In order to understand the principle of writing makefile, it is necessary to know a little bit about the C program's compiling rules. The final goal of the compilation is to generate several (usually one) executable programs, such as the above command Gcc-o main main.c is to generate a executable program called Main. This executable program is made up of several target files (under Windows for. O), which are compiled from the source file, so there is a build diagram for the obj,linux.


From this figure we can see two points: first, to generate an executable file, you must find all the target files, which forms a dependency, in order to build an executable, you must first have a target file, between the target file and the source file, the source file and the header file is also this dependency. Second, because of this dependency, once we have modified the source code, such as B.C has been modified, then we must update the B.O, and then modify the executable file. Other files that are unrelated to this, such as C.O, do not need to be modified, that is, they do not need to be updated. Our makefile is to express this dependency, and can determine whether a file's dependent file has been updated, and then determine if the file should not be updated.

Iii. What is the use of makefile?

Before we learn the specific writing rules, let us first talk about the effect that makefile to achieve or can achieve. After we have written all the source and header files we need for a project, we can put them under a folder under Linux (or a different folder, which we'll talk about later), and then build a file under this folder named Makefile or makefile, Then write this file according to the header files and source files in our project (this is our focus), after writing, save exit, then you can enter the make command in the current directory and execute, all our files will automatically compile the link, generate an executable file. We can also use the make clean command to clear the files that were just generated, and most importantly, when we modify some code, just execute the following make command, and the system will generate a new executable file. How, is not very convenient. Let's summarize the task of Makefile's work:

1. If the project has not been compiled, all of our C files will be compiled and linked.

2. If some C files of this project are modified, then we only compile the modified C file and link the target program.

3. If the header file for this project is changed, then we need to compile the C file referencing the header files and link to the target program.

4. Can automatically clean up the various files produced by themselves, that is, the equivalent of clearing the cleaning solution (this is not required, but generally implemented) Iv. rules for the preparation of makefile files

Finally to the point, first of all to clarify what we write makefile is to express what, in fact, has been mentioned many times before, is to put the dependencies between the various documents expressed, in order to avoid too much theoretical explanation, we start from an example.

If we have a project with 8 source files (. c) Three header files (. h), the inclusion relationship between them is as follows

<pre name= "code" class= "CPP" ><span style= "font-size:18px;" >MAIN.C contains the		defs.h
kbd.c  		contains the defs.h	command.h
command.c	contains defs.h
command.h Display.c	contains the defs.h buffer.h insert.c contains defs.h buffer.h search.c	contains defs.h 	buffer.h
files.c		contains defs.h 	buffer.h 	command.h utils.c		contains Defs.h</span >
The specific content of the inside we do not bother, such a project corresponding to the makefile file can be written like this

<pre name= "code" class= "CPP" ><span style= "font-size:18px;" >EDIT:MAIN.O kbd.o command.o display.o  insert.o search.o files.o utils.o
           cc-o edit main.o kbd.o command.o di SPLAY.O insert.o search.o files.o utils.o
 
   main.o:main.c defs.h
           cc-c main.c
   kbd.o:kbd.c defs.h command.h
  cc-c kbd.c
   command.o:command.c defs.h command.h
           cc-c command.c
   display.o:display.c defs.h Buffer.h
  cc-c display.c
   insert.o:insert.c defs.h buffer.h
           cc-c insert.c
   search.o:search.c defs.h buffer.h
  cc-c search.c
   files.o:files.c defs.h buffer.h command.h
           cc-c files.c
   utils.o:utils.c defs.h
           C C-c utils.c Clean
   :
           rm edit MAIN.O kbd.o command.o display.o insert.o search.o files.o utils.o</span>


Do not be frightened by these "mess" things, in fact the rules are very simple and clear. In conjunction with the inclusion of the above files in Figure 1, we can get a context:

The first is the edit is an identifier, or in a straightforward, is a name, the name appears in the front of the makefile, well, that this name is the name of the executable in our Figure 1, that is, our entire makefile is to produce this file.

Look at the back, the colon is a delimiter, followed by a string of target file name, how these things are out of it. Actually look at figure 1 to understand, they are the target file, is the result of the source file compilation.

Anyway

<pre name= "code" class= "CPP" ><span style= "font-size:18px;" >EDIT:MAIN.O kbd.o command.o display.o  insert.o search.o files.o utils.o</span>

This is the expression of a layer of dependency, that is, to want to edit this executable (Linux executable file without a suffix), you must have the following string of target files. And look at the next line.

<span style= "FONT-SIZE:18PX;" >cc-o edit MAIN.O kbd.o command.o display.o insert.o search.o files.o utils.o</span></span>

This sentence is a program (note that when writing must start with the TAB key), is used to generate an edit file, which used the target files.

Look at the back almost the same structure, is a kind of dependency and a sentence code. This is actually the makefile file's writing rules, a file name, followed by a colon, plus a few other file names, the colon before the generation of the file is dependent on the file, followed by the following is the statement to generate this file.

The last word clean is a clear statement, we'll talk about it later.

V. Principles of Program execution

Understand makefile work principle does not have an immediate effect, but this is a programmer's internal strength, is so-called sharpening no firewood workers. As we have already said before, Makefile is going to show a chain of dependencies, and in fact, there is a dependency tree formed between the files. As shown in the figure below


By mapping the diagram to the program above, you will find that the file is the representation of the relationship between the parent node and the child node of each layer. The execution of the program is the process of traversing the tree, the order of traversal is edit->main.o->main.c->defs.h->kbd.o-> During the traversal, you will determine whether the files in each node are up-to-date:

① if it is a leaf node, that is. C,. h These files, that it must be up to date

② if it is not a leaf node, it accesses all its child nodes, only if all of its nodes are up-to-date and the current node is generated later than all child nodes, the current node is the most recent

③ Access determines whether the child node is up to date with the current node, i.e. this is a recursive process

If the current node is up-to-date, then nothing needs to be done, that is, do not execute the corresponding program statement below the node. And once a node corresponding to the file is not up-to-date, you have to execute the file label below the statement, and from this node to the root node all through the nodes are updated, because they are certainly not the latest.

In short, the execution of the program is the process of traversing the tree, in the process of constantly judging whether the file is up to date, and then determine whether to execute the corresponding statement according to the results. And the effect of this set of rules is the work of the makefile file we said above.

The following is the function of the clean label, the last clean label does not appear in the dependency tree, which means that it is not judged, the following statement will not be automatically executed, to execute it only one way, is to execute the make clean command, This command tells the system to start executing the program from the clean label. The next sentence is to clear the various files produced by the Make command.

There are two points to note:

① about the program that follows a label (usually a file), Makefile does not prescribe the function of that sentence, which means that you can execute any statement there, and makefile will execute it. But in order for the compiler to work properly, this statement is generally used to update the previous file, it is assumed that you are familiar with the compilation instructions of GCC, do not speak the syntax of these statements.

② file generation time is makefile to determine whether the file is the latest a key condition, in fact makefile did not go to determine the contents of the file has not changed, but simply to judge the last save time, if the save time compared to, then think this file has been modified.

Vi. Other technical issues

Here are some of the issues we will encounter in the specific use process and how to solve these problems.

Simplification of the 6.1 makefile file

The previous code is just the most basic version, which is cumbersome to write and maintain. There are many ways to simplify the makefile file, the basic idea is to compress the information, the duplication of information to remove, with the fewest characters to express the most information, but this compression is also limited, after all, the more compression, it will be more difficult to understand, like Chinese ancient prose, a word expression meaning too much, There will be obstacles to understanding. In view of this, we only introduce two simplification methods, one is the use of variables, but the use of makefile automatic derivation mechanism.

6.1.1 Using variables

The variables in makefile and the type of macros in the C language are represented by a number of repeated characters in a label. From the initial version of the program we can see that the most repeated is the target files, so we can define a variable, in place of these target files, the rewritten makefile file as follows

<span style= "FONT-SIZE:18PX;" >objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o 
Edit: $ (objects)
	cc-o edit $ (ob jects)
main.o:main.c defs.h
	cc-c main.c
kbd.o:kbd.c defs.h command.h
	cc-c kbd.c
Command.o:comm AND.C defs.h command.h
	cc-c command.c
display.o:display.c defs.h buffer.h
	cc-c display.c
insert.o:i nsert.c defs.h buffer.h
	cc-c insert.c
search.o:search.c defs.h buffer.h
	cc-c search.c
Files.o:fi LES.C defs.h buffer.h command.h
	cc-c files.c
utils.o:utils.c defs.h
	cc-c utils.c clean
:
	rm E DIT $ (objects) </span>
Program, we define a variable objects to replace all the target files, the definition of the rules is very simple is directly in the form of a=b can be. Then use the format of $ (a) when you are using it. Of course the variables in the makefile file are far more than that, and there's not much to say here.

6.1.2 Automatic derivation mechanism

Makefile is very powerful, and in order to minimize the programmer's work, Makefile supports the automatic derivation of the statements to be executed from the dependency relationship. As mentioned earlier, the code behind the label is generally used to generate this file, and in the process of compiling, those types of files need those instructions are fixed, so makefile to help us generate these codes, instead of our own to write. This gives you the following version of Makefile

<span style= "FONT-SIZE:18PX;" >objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o
 
Edit: $ (objects)
	cc-o edit $ (ob jects) 
main.o:defs.h
kbd.o:defs.h command.h
command.o:defs.h command.h display.o:defs.h
buffer.h< C6/>insert.o:defs.h buffer.h
search.o:defs.h buffer.h
files.o:defs.h buffer.h command.h
utils.o:defs.h Clean

:
	RM Edit $ (objects) </span>
Note that only if there is no statement below the label line, makefile will be automatically deduced, otherwise it will not automatically deduce the error, which is similar to the C + + constructor, or do not write anything, write it well.

6.2 How to set the search path

If our files are not placed in the same folder, then you need to set the Makefile file search path, set the way as follows

<span style= "FONT-SIZE:18PX;" >vpath = Path1:path2:path3<span style= "White-space:pre" >	</span>//in the middle is a colon </span>
Just put this sentence to the most front of the file, the makefile will follow the current path, path1, path2, path3 order to find the file to be added.

6.3 Final version

<span style= "FONT-SIZE:18PX;"  > #VPATH = path1:path2:path3
CC = gcc #set Compiler
objects = main.o kbd.o command.o display.o insert.o search.o FILES.O utils.o
 
Edit: $ (objects)
	$ (CC)-O-Edit $ (objects)
	@echo "^_^ ^_^ ^_^ ^_^ ^_^ ^_^ Compile completed ^ _^ ^_^ ^_^ ^_^ ^_^ ^_^ "#display Compile result
 
main.o:defs.h
kbd.o:defs.h command.h
command.o:defs.h Co Mmand.h
display.o:defs.h buffer.h
insert.o:defs.h buffer.h
search.o:defs.h buffer.h
files.o:def S.h buffer.h command.h
utils.o:defs.h

. Phony:clean clean

:
	RM Edit $ (objects) </span>
In the final version, we've added a couple of things

① comments, the pound sign (#) is followed by the comment content, similar to//in the C language

② added a variable cc, as the choice of different compilers, if it is a C + + program, the CC will be changed to g++ (we used the CC command from UNIX)

③ added interactive information, when the entire compilation process is complete, we output a word to the console

<span style= "FONT-SIZE:18PX;" > ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ Compile completed ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ </span>

④.phony is a description of the virtual label, the front said clean label, will not appear in the dependency tree, such a label is virtual, in order to more clearly this point, but also for some other functions, makefile in this way to illustrate that a label is virtual.

Seven, eggs

Makefile's introduction is over, let's talk a little off-topic. Makefile is the basic tool for the development of Linux/C + +, the reality of how programmers do Linux development, we briefly introduce, of course, these are I hear or see, not necessarily right.

First of all, Linux under development is to use VIM to knock code. The answer is no, even if it is a programmer specializing in Linux development, and few people directly in vim to edit the code, the reason is very simple, is too inconvenient. So people are writing the code in VS or Eclipse, and then uploading it to the Linux system, and even the makefile files we're talking about are all written in Windows. And for the convenience of Windows and Linux Direct file transfer, there is a special software is to do this, I personally use winscp this software, so if you want to do Linux under development, download such a software is very necessary, rather than go to vim under the code.

Secondly, many students who have just started to learn Linux system are in their own Windows installed virtual machine and then installed Linux system, and in real development, Linux is installed on the server, our computer as long as the installation of a "shell" software can be, the software can be connected to the server, Let's operate the server system directly. There are many such software, such as Xchell.

Finally, as a professional programmer, a professional text viewer is very necessary. If you still use TXT to view the file, it is too low. UltraEdit is a professional text view compilation software, how to use the details do not say.

This is said to tell you that although important, the operation is indispensable. A lot of things that you don't understand, but that you don't even know there is such a thing. So as a programmer the most painful is not the algorithm design, but the software is not good, because although the reason is important, but we are living in a specific life. Again, we had better not fall into the blind pursuit of the rational world, only a good concrete every day is the true success.












Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.