current position:Home>Basics: a 5-makefile example

Basics: a 5-makefile example

2022-05-15 07:24:07Bleary calf

explain
   The purpose of this article is to summarize backup 、 For future reference , Because it's a personal summary , If there is any wrong , Welcome to correct ; in addition , Most of the content comes from the Internet 、 Books 、 And all kinds of manuals , In case of infringement, please inform , Immediately delete the post and apologize .
  QQ Group Number :513683159 【 Learn from each other 】
Content sources
   examples makefile Index blog
   According to the previous article, there are still many testable points , Here are just a few simple examples , There is time for replenishment .
Last one : Basic knowledge of : piece 4-make Tools and Makefile Document concept
Next : Basic knowledge of : piece 6-cmake Tools and CMakeLists.txt file

Experiment 1 : The header file and the source file are placed in the same folder

0、 create a file

   With this article 《 Basic knowledge of : piece 2- Multi source file compilation process 》 Consistent examples .

  1️⃣mymath.c file

#include<stdio.h>
#include "add.h"
#include "sub.h"

int main(int argc, char **argv)
{
    
        int a = 10 ,b = 5;
        printf("%d + %d = %d\n",a,b,add(a,b));
        printf("%d - %d = %d\n",a,b,sub(a,b));
        return 0;
}

  2️⃣add.c file

#include "add.h"

int add(int a, int b)
{
    
    return a + b;
}

  3️⃣add.h file

#ifndef _ADD_H_
#define _ADD_H_

int add(int a, int b);

#endif 

  4️⃣sub.c file

#include "sub.h"

int sub(int a, int b)
{
    
    return a - b;
}

  5️⃣sub.h file

#ifndef _SUB_H_
#define _SUB_H_

int sub(int a, int b);

#endif 

1、 File tree structure

.
├── add.c
├── add.h
├── Makefile
├── mymath.c
├── mymath.o
├── sub.c
└── sub.h

2、 compile

   The input terminal :gcc mymath.c add.c sub.c -o mymath, Get the executable mymath.
   This is implemented directly using instructions , Next, we will demonstrate the use of Makefile File for compilation

3、Makefile file

Version of a :( Display rule Standard Version )

mymath:mymath.o add.o sub.o
	gcc mymath.o add.o sub.o -o mymath

mymath.o:mymath.c add.h sub.h
	gcc -c mymath.c -o mymath.o

add.o:add.c add.h
	gcc  -c add.c  -o add.o

sub.o:sub.c sub.h
	gcc  -c sub.c  -o sub.o

clean:			
	rm -f *.o mymath

  PS:
     Write in strict accordance with the following structure :

 The goal is : Dependency list 
	 command 

  ① Note that the command must be in 【Tab】 start
  ② The dependency list is used to represent the connection with the target , Only write on the dependency list , When the dependent file changes , The target will recompile , If it's not on the dependency list , Even if the dependent file changes, it will be considered to be the latest version .

Version 2 :( Variable version )

TARGET = mymath							# ultimate objective 
OBJECT = mymath.o add.o sub.o			# Intermediate target file 
CC = gcc								# compiler 
CFLAGS = -c

$(TARGET):$(OBJECT)
	$(CC) $(OBJECT) -o $(TARGET)

mymath.o:mymath.c add.h sub.h
	$(CC) $(CFLAGS) mymath.c -o mymath.o

add.o:add.c add.h
	$(CC)  $(CFLAGS) add.c  -o add.o

sub.o:sub.c sub.h
	$(CC)  $(CFLAGS) sub.c  -o sub.o

clean:			
	rm -f *.o $(TARGET)

   Defining and using variables can simplify the program and make it easy to modify .

Version 3 :( Automatic derivation version )

  GNU Of make Tools are powerful , Command after automatically deriving files and their file dependencies , Such as :
    1️⃣ notice 【.o file 】 Automatically put 【.c file 】 Join dependencies , Such as :add.o = add.o:add.c
    2️⃣ And deduce the corresponding compilation instructions , Such as :$(CC) -c add.c

TARGET = mymath							# ultimate objective 
OBJECT = mymath.o add.o sub.o			# Intermediate target file 
CC = gcc								# compiler 

$(TARGET):$(OBJECT)
	$(CC) $(OBJECT) -o $(TARGET)

mymath.o: add.h sub.h
add.o: add.h
sub.o: sub.h

clean:			
	rm -f *.o $(TARGET)

   Note that other files in the dependency list still need to be placed in the dependency list , If omitted, the corresponding file will be changed without recompiling .

Version 4 :( Automatic variable version )

TARGET = mymath							# ultimate objective 
OBJECT = mymath.o add.o sub.o			# Intermediate target file 
CC = gcc								# compiler 

$(TARGET):$(OBJECT)
	$(CC) $^ -o [email protected]

mymath.o: add.h sub.h
add.o: add.h
sub.o: sub.h

clean:			
	rm -f *.o [email protected]

  [email protected]: The target file of the rule
  $^: All dependent files

Experiment two : The header file and the source file are not in the same folder

1、 File tree structure

.
├── include
│   ├── add.h
│   └── sub.h
├── Makefile
├── mymath.c
├── add.c
└── sub.c

2、 compile

   The input terminal :gcc mymath.c add.c sub.c -I ./include/ -o mymath, Get the executable mymath.
   This is implemented directly using instructions , Next, we will demonstrate the use of Makefile File for compilation

3、Makefile file

Version of a :( Terminal instruction version )

mymath:
	gcc mymath.c add.c sub.c -I ./include/ -o mymath
clean:			
	rm mymath

   This version is almost the same as calling instructions directly at the terminal , Attention should be paid to :
    1️⃣ The ultimate goal must be .
    2️⃣ The command line must start with 【Tab】 Start .

Version 2 :( Display rule Standard Version )

mymath:mymath.o add.o sub.o
	gcc mymath.o add.o sub.o -o mymath

mymath.o:mymath.c ./include/add.h  ./include/sub.h
	gcc -c mymath.c -I ./include/ -o mymath.o

add.o:add.c ./include/add.h
	gcc  -c add.c  -I ./include/   -o add.o

sub.o:sub.c ./include/sub.h
	gcc  -c sub.c  -I ./include/  -o sub.o

clean:			
	rm -f *.o mymath

   Why does the painting style suddenly become complicated ? Here we need to explain :
  Makefile File structure :

 The goal is : Dependency list 
	 command 

It can be seen that this version strictly follows the structure , So what's the advantage of writing like this ?
mymath It's the first goal , The ultimate goal , The target has three dependent files :mymath.o add.o sub.o,
Some people say that I can delete these three documents , This is not allowed , Because these three files are gcc mymath.o add.o sub.o -o mymath what is needed ,
If delete , Then the following goals will not be implemented , Only when it exists will the corresponding target be executed
summary : The final goal is an executable file linked by three object files :mymath, Only when the three target files are used as the dependence of the final goal can we achieve the following three goals .
Think of it as a tree , The father is disconnected from the son ( Not in the dependency list ) after , Then the father has no raw materials ( Such as :add.o) You can't make it yourself , Sub production is required to provide .
The following goal is to omit the dependency list ( Raw materials can't be found , Such as add.c), But why not omit ?
   Because if you don't add it to the dependency list , It is impossible to detect whether the corresponding file is updated in real time , Cause the corresponding file to be changed without knowing that it will not be recompiled .
   Try and you will know , If you delete the file corresponding to the dependency list , You go to revise and re make It won't recompile , If it is in the dependency list, it will be recompiled .
Note that the files in the dependency list must be written to the correct location , Otherwise, the corresponding file will not be found , Such as :./include/add.h Can not write add.h
The following command line must indicate the required header file path , -I ./include/, If you don't know where, you can't find the header file .

Version 3 :( Variable version )

TARGET = mymath							# ultimate objective 
OBJECT = mymath.o add.o sub.o			# Intermediate target file 
CC = gcc								# compiler 
INCLUDE = -I ./include/					# Header file path 

$(TARGET):$(OBJECT)
	$(CC) $(OBJECT) -o $(TARGET)

mymath.o:mymath.c ./include/add.h  ./include/sub.h
	$(CC) -c mymath.c $(INCLUDE) -o mymath.o

add.o:add.c ./include/add.h
	$(CC)  -c add.c  $(INCLUDE)   -o add.o

sub.o:sub.c ./include/sub.h
	$(CC)  -c sub.c  $(INCLUDE)  -o sub.o

clean:			
	rm -f *.o $(TARGET)

Version 4 :( Automatic derivation version )

TARGET = mymath							# ultimate objective 
OBJECT = mymath.o add.o sub.o			# Intermediate target file 
CC = gcc								# compiler 
INCLUDE = -I ./include/					# Header file path 

$(TARGET):$(OBJECT)
	$(CC) $(OBJECT)  -o $(TARGET)

mymath.o:mymath.c ./include/add.h  ./include/sub.h
	$(CC) -c mymath.c $(INCLUDE)

add.o:add.c ./include/add.h
	$(CC)  -c add.c  $(INCLUDE)   

sub.o:sub.c ./include/sub.h
	$(CC)  -c sub.c  $(INCLUDE)  
	
clean:			
	rm -f *.o $(TARGET)

copyright notice
author[Bleary calf],Please bring the original link to reprint, thank you.
https://en.chowdera.com/2022/131/202205102142154703.html

Random recommended