A brief introduction to make/makefile [linux]

A brief introduction to make/makefile [linux]

  • 1. What is make/makefile?
  • 2. makefile
    • 2.1 Dependencies and dependency methods
    • 2.2 Simple use of make
        • 2.2.1 make test
        • 2.2.2 clean
    • 2.2 make executes multiple steps at a time
    • 2.3 Some modifiers
      • 2.3.1 .PHONY (pseudo target)
      • 2.3.2 @
      • 2.3.3 $@ $^

1. What is make/makefile?

make/makefile can be said to be partners, both are indispensable.
Make and makefile can be said to be indispensable functions for large-scale projects
In essence
make is a command that comes with the system
makefile is a file

After using make:
The compiler will find the makefile file in the directory and execute it

It can be said that the function of the make command: It is to execute the makefile file in this directory
An error will be reported when there is no makefile in the directory.

So we are learning the functions of make/makefile, mainly focusing on the inside of makefile

2. makefile

If you want to use the make/makefile function, just create a makefile in this directory

touch makefile


Use vim editor to make modifications.

It was found that the file was completely empty, so we want to write a usable makefile. We need to understand the dependencies and dependency methods first

2.1 Dependency and dependency methods


Here is the most common makefile instruction for compiling test

Let’s see what these two lines are


Here we can see that an instruction consists of two parts:

1. Dependencies
2. Dependence method

Next, let’s look at these two parts separately:

Dependencies:

The left side can be said to be the command name.
When using it,
make test to execute

test.cpp is the file that the test instruction depends on.

Dependency method

The dependency method can be said to be
The content of a function within a function body in a programming language.
It’s the instruction to execute

2.2 Simple use of make

After understanding the details, we can try to write two makefiles.

2.2.1 make test


This is our example above, let’s use it next.

I just wrote a test.cpp file here

Enter here

make test

You can find that it has been executed here.

It is found that there is an additional executable program and the makefile instruction has been executed.

2.2.2 clean

Similarly, we can also write a clean instruction that cleans the executable program like the destructor in C++

clean:
        rm -rf test

There is no file after the dependency colon, which means that this command has no dependent files

Let’s execute it here

make clean


It was found that the test executable program was deleted

2.2 make executes multiple steps at a time

When talking about this content, the execution process of language will be involved. If you don’t understand it, you can read my previous blog
Compilation process of C language program

Heretest.i,test.s,test.o
They are all generated files from previous program compilation, assembly and linking.

What will happen if you directly use make test.i here?
Isn’t this very simple?
Direct execution

g + + test.cpp -o test.i -E

It’s over.

But what happens if weexecute make test?

We will find that all instructions are executed.

Let us analyze the process here.


When executing the test in the first step, the dependency is found to be the test.o file, but the system cannot find it.
At this time, you will look for commands with test.o

At this time, the test.o command is found, but it is found that test.s is required for execution, and then the test.s file is found again

I kept searching and found test.i and I can create it.

At this time, return to the previous instruction that requires test.i and execute it
Execute and return one by one, similar to recursion

What if we just change the order and the result is the same

It was found that the results will not change because the order does not affect the execution
The system will look for executable instructions and execute them automatically. If not, it will report an error
Just like functions in C language, there is no need to pay attention to the order of reference functions, as long as they can be found by the system

2.3 Partial modifiers

Next are a few more basic modifiers

2.3.1 .PHONY (pseudo target)

When executing the makefile, if the executable file has already been generated, in order to prevent repeated meaningless execution of the instructions to generate the executable file
It will automatically determine whether the source file of the executable file has changed to determine whether to perform compilation

Example:
The first compilation is done here.

When you execute it for the second time, you will find that the system will prevent you from repeating make

How is such a high-level function achieved?

In fact, it’s just through comparing time

we can pass

stat [file name]

View file properties

access: access time
Modify the file content: modify
Make changes to file attributes: change

Note here: When the file attributes are modified, the time of the file content will generally be modified
Because the file content has a size attribute

Logically speaking, when executing instructions on a file, the access time must be changed.
But because the access changes too frequently, the file is on the disk, and multiple users have to change the access when accessing the file, causing the server to be very slow
Therefore, in the newer version, the access time can only be changed after a certain amount of operations on the file

So when the make file performs dependency operations on the source file
Convert the time of the executable program into a timestamp, and convert the modification time of the .cpp file into a timestamp
Compare to determine whether to execute the instruction

If you want to cancel the timestamp comparison here
You can add .PHONY modification (pseudo target)
However, it is not recommended to modify the generated executable file with pseudo-target


You can execute it casually here without comparing timestamps.

2.3.2 @

After we enter make
make will automatically pop up the dependent methods for executing instructions in the makefile


After adding @, you can prevent dependency methods from popping up

2.3.3 $@ $^

These two modifiers are mainly used in dependencies


These two represent the two sides of the dependency relationship.

So what exactly is it used for?


When writing dependency methods, you can use symbols instead of file names


Here you can find that the file is executed normally.