Write the project makefile from scratch (1): Basic Rules

Source: Internet
Author: User

[Copyright statement: reprinted. Please retain the Source: blog.csdn.net/gentleliu. Mail: shallnew at 163 dot com]

Generally, a slightly larger Linux project may contain many source files, and the final executable program is also compiled by the links of these many source files. Compiling is to compile a. C or. cpp file into an intermediate code. o file. The link is to use these intermediate code files to generate executable files. For example, the current project directory contains the following source files:

# lscommon.h  debug.c  debug.h  ipc.c  ipc.h  main.c  tags  timer.c  timer.h  tools.c  tools.h #

The above source code can be compiled as follows:

# gcc -o target_bin main.c debug.c ipc.c timer.c tools.c

If a file (such as tools. c) is modified later, execute the previous line of code. However, it is not reasonable to compile it if there are thousands of source files. In this case, we can follow the steps below to compile:

# gcc -c debug.c# gcc -c ipc.c# gcc -c main.c# gcc -c timer.c# gcc -c tools.c# gcc -o target_bin main.o debug.o ipc.o timer.o tools.o

If the tool. C is modified, you only need to compile the file and then generate the executable file. That is, perform the following two steps:

# gcc -c tools.c# gcc -o target_bin main.o debug.o ipc.o timer.o tools.o

This seems reasonable. However, if you modify multiple files, you may forget to compile a file, which may cause errors during running. If the common. h file is modified, all. c files containing the header file need to be re-compiled. This makes it more complex and error-prone. It seems that this method is not good enough, and manual processing is prone to errors. Is there an automatic processing method? Yes, it is to write a makefile to process the compilation process.

The following is a simple makefile. Create a file named makefile under the source code directory:

target_bin : main.o debug.o ipc.o timer.o tools.o>---gcc -o target_bin main.o debug.o ipc.o timer.o tools.o main.o: main.c common.h                                                                                                                                                                   >---gcc -c main.c debug.o: debug.c debug.h common.h>---gcc -c debug.c ipc.o: ipc.c ipc.h common.h>---gcc -c ipc.c timer.o: timer.c timer.h common.h>---gcc -c timer.c tools.o: tools.c tools.h common.h>---gcc -c tools.c

Then run the following command on the command line:

# make gcc -c main.cgcc -c debug.cgcc -c ipc.cgcc -c timer.cgcc -c tools.cgcc -o target_bin main.o debug.o ipc.o timer.o tools.o## lscommon.h  common.h~  debug.c  debug.h  debug.o  ipc.c  ipc.h  ipc.o  main.c  main.o  Makefile  Makefile~  tags  target_bin  timer.c  timer.h  timer.o  tools.c  tools.h  tools.o#

The. o file and the target_bin executable file are generated in this directory. Now we only need to execute a make command to complete all the compilation tasks. Instead of manually executing all the actions as before, the make command will read the MAKEFILE file in the current directory and complete the compilation steps. From the compilation process output to the screen content, we can see the work done after executing the make command, which is actually the commands we previously manually executed. What is makefile?

The so-called makefile is actually a file composed of a group of compilation rules. The format of each rule is roughly as follows:

target ... : prerequisites ... >---command        ...

Target is the target file, which can be an executable file, *. o file, or tag. Prerequisites is the source file or *. o file required to generate the target. It can be the target of another rule. Commond is the operating system command to be executed to generate the target. The command must start with a tab (with the "> ---" character in the text) and cannot be replaced by a space.

To put it bluntly, you need to generate a target, which depends on the prerequisites file, and then execute commond to generate the target. This is the same as manually executing each compilation command. In fact, it defines a dependency. We write the dependency file that generates each file and finally automatically execute the compilation command.

For example, in the makefile example, target_bin main. O is the target, Main. O debug. o ipc. O timer. O tools. O is the prerequisites of target_bin, and GCC-O target_bin main. O debug. o ipc. O timer. O tools. O is commond, which compiles all the target files into the final Executable File target, while Main. c Common. H is main. O prerequisites, its gcc-C main. C command to generate the main. o file.

In this example, the makefile process is as follows:

1. First, find the target of the first rule. The target of the first rule is called the default target. If the default target is updated, the task is completed. Other work is done for this purpose. The target target_bin of the first rule in this makefile. Since this is the first compilation, the target_bin file has not yet been generated and needs to be updated, but the main file is dependent at this time. O debug. o ipc. O timer. O tools. O is not generated, so you need to update these files before updating target_bin.

2. Therefore, make will further search for rules targeting these dependent files main. O Debug. o ipc. O timer. O tools. O. First find main. o, the target is not generated, and the target dependency file is main. c Common. h, the file exists, so execute the rule command gcc-C main. c. Generate main. o. Other dependent files required by target_bin also perform the same operation.

3. Execute gcc-O target_bin main. O Debug. o ipc. O timer. O tools. O to update target_bin.

 

Run make again without changing the source code:

# makemake: `target_bin' is up to date.#

The system prompts that the target target_bin is up to date.

If you modify the file main. C, run make:

# vim main.c# makegcc -c main.cgcc -o target_bin main.o debug.o ipc.o timer.o tools.o#

At this time, make will automatically select the affected target for re-Compilation:

First, update the default target. First, check whether target_bin needs to be updated. This requires that the dependent file main. O Debug. o ipc. O timer. O tools. o be updated.

Secondly, Main. o needs to be updated, because main. O main. c. The last modification time is later than main. o late, so you need to execute the generate target main. O command: gcc-C main. c. Update main. o.

The dependency file main. O of the target target_bin has been updated. Therefore, execute the corresponding command gcc-O target_bin main. O Debug. o ipc. O timer. O tools. O to update target_bin.

To sum up, follow these steps:

1. Check its dependent files first. If the dependent files need to be updated, execute the rule with the object as the target. If the rule is not found but the file is found, the dependent file does not need to be updated. If the file does not exist without this rule, an error is returned and the file is exited.

2. Check the target of the file. If the target does not exist or the target exists, but the modification time of the dependent file is later than that of the file, or a dependent file has been updated, run the command of this rule.

It can be seen that makefile can automatically discover updated files and automatically regenerate the target. Using makefile is more efficient than manually compiling it, but also reduces the possibility of errors.

 

Makefile has many targets. You can compile one of them with the target name after the make command. If no compilation target is specified, make will compile the default target, that is, the first target. The first target of makefile in this article is target_bin. If you only modify the tools. c file, you may just want to check whether the changed source code has a syntax error and do not want to re-compile the project. You can execute the following command:

# make tools.o gcc -c tools.c#

After compilation is successful, another problem occurs. If you continue to execute the same command:

# make tools.omake: `tools.o' is up to date.#

We can manually delete the tools. o file and then execute it. How can this problem be done manually? We want automatic. We want Automatic !! Well, we add a target to delete the temporary files generated during the compilation process. The target is clean.

Add the following content to the makefile:

clean:>---rm *.o target_bin

This target is not executed when we directly make the command, because it is not included by the default target target_bin target or the target with the target_bin dependency file. To execute this target, you must specify the target in make. As follows:

# make cleanrm *.o target_bin#
As you can see, when the clean target is executed, make will re-generate all objects corresponding to the target when executing make clean, because the files are cleared when the make clean command is executed.

The Clean object should exist in your makefile. It can facilitate secondary compilation and keep the source files clean. This target is generally placed at the end, not at the beginning, or it will be executed as the default target, which is probably not your intention.

In conclusion, makefile only tells the make command how to compile and link programs, and tells the make command to generate the files required for the target file, the specific compilation link is done by the command corresponding to your target.

Give a complete makefile for today:

target_bin : main.o debug.o ipc.o timer.o tools.o>---gcc -o target_bin main.o debug.o ipc.o timer.o tools.o main.o: main.c common.h                                                                                                                                                                   >---gcc -c main.c debug.o: debug.c debug.h common.h>---gcc -c debug.c ipc.o: ipc.c ipc.h common.h>---gcc -c ipc.c timer.o: timer.c timer.h common.h>---gcc -c timer.c tools.o: tools.c tools.h common.h>---gcc -c tools.c clean:>---rm *.o target_bin

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.