Makefile Handouts (1)--makefile Basics (Overview)

Source: Internet
Author: User

Recently in learning Linux under the C programming, bought a called "Linux environment in the C Programming Guide" read to makefile more and more confused, may be my understanding can not.

So Google came to the following article. Plain and easy to understand. Then post it for easy learning.

PostScript, read this article and the "Linux environment in the C Programming Guide," The makefile chapter of the astonishing similarity, but this article from an example into, in some places better understanding. It is a good article to make people understand.

Write Makefile with me.


Chenhao (CSDN)

Overview——
What is makefile. Maybe a lot of WINODWS programmers don't know this, because the Windows IDE does the work for you, but I think that to be a good and professional programmer, Makefile still have to understand. It's like there are so many HTML editors now, but if you want to be a professional, you still have to understand the meaning of the HTML logo. Especially in Unix software compiled, you can not write makefile, will not write makefile, from a side to explain whether a person has the ability to complete large-scale projects.

Because, makefile is related to the compilation rules of the whole project. A project in the source file does not count, its type, function, modules are placed in several directories, makefile defined a series of rules to specify which files need to compile first, which files need to compile, which files need to recompile, and even more complex functional operations, Because makefile is like a shell script, it can also execute operating system commands.

The benefit of makefile IS-"automated compilation", once written, only need a make command, the entire project completely automatic compilation, greatly improve the efficiency of software development. Make is a command tool, a command tool that interprets instructions in makefile, and in general, most Ides have this command, such as: Delphi's Make,visual C + + Nmake,linux under GNU. It can be seen that makefile has become a method of compiling engineering.

There are fewer articles on how to write makefile, which is why I want to write this article. Of course, different manufacturers make different, but also have various syntax, but its essence is in the "file dependencies" on the fuss, here, I only to the GNU make, my environment is Redhat Linux 8.0,make version is 3.80. Surely, this make is the most widely used and the most used. It is also the most consistent with the IEEE 1003.2-1992 Standard (POSIX.2).

In this document, will be the source code for C/A + + as our foundation, so there must be some knowledge of C + + compilation, related to this aspect, and please see the relevant compiler documentation. The default compiler here is GCC and cc under UNIX.
about compiling and linking programs——————————
Here, I would like to say more about the procedures of compiling some of the norms and methods, in general, whether C, C + +, or PAS, the first to compile the source file into the intermediate code file, under Windows is the. obj file, Unix is an. o file, that is, Object file, This action is called compilation (compile). Then a lot of object file is synthesized to execute the file, this action is called link.

At compile time, the compiler needs the correct syntax, the declaration of functions and variables. For the latter, it is usually the location where you need to tell the compiler header file (the header file should be just a declaration, and the definition should be placed in a C + + file), and as long as all the syntax is correct, the compiler can compile the intermediate target file. In general, each source file should correspond to an intermediate target file (o file or obj file).

Links are mainly linked functions and global variables, so we can use these intermediate target files (o files or obj files) to link our applications. The linker does not care about the source file where the function resides, just the intermediate object file of the function, most of the time, because there are too many source files, there are too many intermediate target files generated by the compilation, and when the link needs to clearly indicate the intermediate target filename, which is inconvenient for compiling, We're going to pack the middle target file, which is called "Library file" in Windows, the. lib file, under Unix, is archive file, which is. A.

To sum up, the source file first generates an intermediate target file, which is then generated by the intermediate target file. At compile time, the compiler detects only the program syntax, and whether the function or variable is declared. If the function is not declared, the compiler gives a warning, but can generate object File. And when you link a program, the linker will look for the implementation of the function in all object file, if cannot find, that will report link error code (Linker error), in VC, this kind of error is generally: Link 2001 error, meaning say, linker failed to find the realization of function. You need to specify the object File for the function.

Well, to be sure, GNU make has a lot of content, gossip less, or let's start.

Makefile Introduction———————
When the make command executes, a Makefile file is required to tell the make command how to compile and link the program.

First, we use an example to illustrate the writing rules of Makefile. In order to give everyone a sense of awareness. This example comes from the GNU Make Manual, in which our project has 8 C files, and 3 header files, and we're going to write a makefile to tell make commands how to compile and link the files. Our Rules are:
1 if the project has not been compiled, then all of our C files will be compiled and linked.
2 If a few C files of this project are modified, we only compile the modified C file and link the target program.
3 If the header file of the project is changed, we need to compile the C file that references the header files and link the target program.

As long as our makefile is well written, all of this we can do with just one make command, and the make command automatically intelligently determines which files need to be recompiled based on the current file modifications to compile the required files and linked target programs.


I. Rules of the Makefile
Before telling this makefile, let's take a rough look at the makefile rules.

Target ...: Prerequisites ...
Command
...
...

Target is either an object file, or it can be an executable file. It can also be a label (label), which is described in the following "pseudo target" section for the label.

Prerequisites is the file or target that is needed to generate the target.

command is what you need to execute. (Arbitrary shell commands)

This is a file dependency, that is, target files of one or more objects depend on the files in prerequisites, and their generation rules are defined in the command. The white point is that if more than one file in prerequisites is newer than the target file, the commands defined by the command are executed. This is the makefile rule. Which is the core content of makefile.

At the end of the story, that's what makefile is all about, as if my document should be over. Oh. Not all, this is the main line and the core of makefile, but to write a good makefile is not enough, I will be followed by 1.1 points to combine my work experience to you slowly come. There's a lot of content. :)


Second Sample
As mentioned earlier, if a project has 3 headers, and 8 C files, our makefile should look like this in order to complete the three rules mentioned above.

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 disp LAY.O/
insert.o search.o files.o utils.o main.o:main.c defs.h cc-c main.c kbd.o:kbd.c
command . h
cc-c kbd.c
command.o:command.c defs.h command.h cc-c command.c display.o:display.c
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
  cc-c utils.c Clean
:
rm edit MAIN.O kbd.o command.o display.o
insert.o search.o files.o UTILS.O


The backslash (/) is the meaning of the line break. This makes it easier for makefile to read easily. We can save this content in a file "Makefile" or "Makefile", and then enter the command "make" directly in the directory to generate the Execute file edit. If you want to delete the execution file and all the intermediate target files, simply execute the "make clean".

In this makefile, the destination file (target) contains: Execute file Edit and intermediate object file (*.O), and dependent files (prerequisites) are those. c files and. h files after the colon. Each. o file has a set of dependent files, and these. o files are also dependent files for executing file edit. The essence of dependencies is the description of which files are generated by the target file, in other words, which files are updated by the target file.

After defining the dependencies, the subsequent line defines how to generate the operating system commands for the target file, and must begin with a TAB key. Remember that make does not matter how the command works, but he executes the commands that are defined. Make compares the modified dates of the targets and prerequisites files, and if the prerequisites file has a date that is newer than the date of the targets file, or if Target does not exist, make executes the subsequent defined command.

The point here is that clean is not a file, it's just an action name, a bit like the lable in C, with nothing in it, so that make doesn't automatically find the dependencies of the file, and does not automatically execute the commands that are defined later. To execute the subsequent command, it is obvious that the name of the lable should be indicated after the make command. Such a method is very useful, we can in a makefile to define not compile or compile-independent commands, such as program packaging, program backup, and so on.



Iii. How make is working
In the default way, we just enter the make command. So

1, make will be in the current directory to find the name "Makefile" or "Makefile" files.
2. If found, it will find the first target file in the file (target), in the above example, he will find "edit" this file, and the file as the final target file.
3. If the edit file does not exist or the subsequent. o file on which edit is dependent is newer than the edit file, he will execute the command defined later to generate the edit file.
4. If edit does not depend on the. o file, make will find a dependency on the target. o file in the current file, and then generate an. o file based on that rule if found. (This is sort of like a stack process)
5, of course, your C files and h files exist, so make will generate an. o file, and then use the final task of the. o File life make, that is, execute file edit.

This is the dependency of the entire make, and makes will find the dependencies of the files layer by layer until the first target file is finally compiled. In the process of searching, if there is an error, such as the last dependent file can not be found, then make will exit directly and error, and for the defined command errors, or the compilation is not successful, make at all ignore. Make just the dependency of the file, that is, if after I find the dependency, the file after the colon is still out, then I am sorry, I do not work.

With this analysis, we know that, like clean, which is not directly or indirectly associated with the first target file, the commands defined later will not be automatically executed, but we can show that we want to make execution. This is the command-"make clean", which clears all the target files for recompilation.

So in our programming, if this project has been compiled, when we have modified one of the source files, such as file.c, then depending on our dependence, our target FILE.O will be recompiled (that is, the command defined after this dependency relationship), so the file.o file is up to date, so FILE.O's file modification time is newer than edit, so edit will be relink (see edit The command defined after the document is marked.

And if we change the "Command.h", then KDB.O, COMMAND.O, and FILES.O will be recompiled, and edit will be linked again.


Iv. use of variables in makefile
In the example above, let's look at the rules for Edit:
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 disp LAY.O/
insert.o search.o files.o UTILS.O
We can see that the string of [. O] Files has been repeated two times, and if our project needs to add a new [. o] File, then we need to add two places (three places and one place in clean). Of course, our makefile is not complicated, so add in two places is not tired, but if the makefile become complex, then we will be able to forget a need to join the place, resulting in the compilation failed. Therefore, in order to makefile the easy maintenance, we can use the variable in the makefile. The makefile variable is a string, and it may be better to understand the macro in C language.

For example, we declare a variable, called OBJECTS, OBJECTS, Objs, Objs, obj, or obj, anyway, whatever it takes to be able to represent the obj file. We defined this at the beginning of the makefile:
objects = MAIN.O kbd.o command.o display.o/insert.o search.o files.o utils.o
So we can conveniently use this variable in our makefile as "$ (objects)", so our improved version makefile becomes the following:
objects = MAIN.O kbd.o command.o display.o/
insert.o search.o files.o utils.o

Edit: $ (objects)
Cc-o Edit $ ( objects)
main.o:main.c defs.h
cc-c main.c
kbd.o:kbd.c defs.h
command.h cc-c kbd.c
MMAND.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
files. O:FILES.C defs.h buffer.h command.h cc-c files.c utils.o:utils.c defs.h cc-c clean
: utils.c />RM Edit $ (objects)

So if a new. o file is added, we simply need to modify the objects variable.

For more on the subject of variables, I will give you one by one ways to follow.


Five, let make automatic deduction
GNU's make is so powerful that it automatically infers the commands behind the file and file dependencies, so we don't have to write a similar command after every [. O] File because our make automatically recognizes and infers the command ourselves.

As soon as make sees an [. o] File, it automatically adds the [. c] File to the dependency, and if make finds a whatever.o, then WHATEVER.C is WHATEVER.O's dependent file. And Cc-c Whatever.c will also be deduced, so that our makefile no longer need to write so complicated. Ours is the new makefile.
objects = MAIN.O kbd.o command.o display.o/
insert.o search.o files.o utils.o

Edit: $ (objects)
Cc-o Edit $ ( objects)

main.o:defs.h
kbd.o:defs.h command.h command.o:defs.h command.h
buffer. H
insert.o:defs.h buffer.h
search.o:defs.h buffer.h
files.o:defs.h buffer.h command.h
utils.o:de Fs.h

. Phony:clean clean
:
RM Edit $ (objects)

This approach, the "obscure rule" of make. Above the contents of the file, ". Phony "indicates that clean is a pseudo target file.

For more detailed "obscure rules" and "pseudo target files", I will give you one by one ways to follow.


Six, the makefile of alternative style
So that our make can automatically deduce the command, then I see the heap [. O] and [. h] Dependencies are a little uncomfortable, so many repetitions [. h], can you just fold it up, OK, no problem, this is easy for make, who has the ability to automatically derive commands and files. Take a look at the latest style of makefile.
objects = MAIN.O kbd.o command.o display.o/
insert.o search.o files.o utils.o

Edit: $ (objects)
Cc-o Edit $ ( Objects)

$ (objects): Defs.h
kbd.o command.o files.o:command.h display.o insert.o search.o
. h

. Phony:clean clean
:
RM Edit $ (objects)

This style makes our makefile very simple, but our file dependencies seem a bit messy. You can't have your cake and eat it. Also see your liking. I do not like this style, one is that the dependence of the file can not see clearly, the second is if the file is more than one, to add a few new. o File, it is not clear.

Vii. clear rules for target files
Each makefile should write a rule that clears the target file (. o and execution file), which is not only easy to recompile, but also helps keep the files clean. This is a "self-cultivation" (hehe, still remember my "programming accomplishment"). The general style is:

Clean:
RM Edit $ (objects)

A more robust approach would be to:
. Phony:clean clean
:
-rm Edit $ (objects)

As I said before,. Phony meaning that clean is a "pseudo target". and a small minus sign in front of the RM command means that there may be problems with some files, but don't worry, keep doing what's behind. Of course, clean rules should not be placed at the beginning of a file, otherwise, this becomes the default target of make, and no one is willing to do that. The unwritten rule is that "clean is always at the end of the file."


The above is a makefile of the general picture, but also the basis of makefile, there are many makefile the following details, ready to do. Come when you are ready.

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.