Use Makefile to optimize the entire process of Makefile
Take a set of simple. c files as an example. The learning process from compiling commands to Makefile.
The gcc parameters are not described too much. The following files and content:
Add. c
int add(int a int b){ return a+b;}
Sub. c
int sub(int a ,int b){ return a-b;}
Cal. h
#ifndef __CAL_H_#define __CAL_H_int add(int,int);int sub(int,int);#endif
Main. c
#include
#include "cal.h"int main (void){ printf("%d\n",add(33,55)); printf("%d\n",sub(88,55)); return 0;}
There are three source files and one header file. The following command is required for compiling:
Gcc main. c add. c sub. c-o app
Suppose there are no other. c files in the current folder.
However, this command is also required for each compilation. This is an amazing thing.
So there should be a way to deal with this tough thing, right, it's Makefile.
Now, let's write a Makefile of the first version. The name of the Makefile is fixed, and the first letter must be capitalized.
As follows:
app:main.c add.c sub.c gcc main.c add.c sub.c -o app
The app is the target ':' The colon is followed by the dependency of the target. The following command is the command to be executed and tab indentation is required.
Now we can directly input make on the terminal to execute the command just now.
But now the problem is coming. I may modify only one. c file. Isn't it necessary to recompile every file. How a waste of time is c cpp compilation?
So the next version is born again.
app:main.o add.o sub.o gcc main.o add.o sub.o -o app main.o:main.c gcc -c main.c add.o:add.c gcc -c add.c sub.o:sub.c gcc -c sub.c
This file indicates that the final goal is to compile an executable file, which depends on three pre-processing files. o files, and each. o file depends on the. c file. The internal mechanism of Makefile checks whether the dependent. c and. o files match in time. If the. c file is newer, it needs to be re-compiled into a. o file. Therefore, when we only modify one source file, make compilation won't all be compiled again, and only the modified files will be compiled.
Well, it looks good.
However, I have added another mul. the c file needs to be compiled together. I have gone through it. There seems to be a lot of places to be changed. I want to add app dependencies. o modify the gcc command and add new files. o target dependency.
This is not smart enough. What should I do. Haha, I secretly tell you that the default configuration of Makefile is related to the. o file dependency. c file, and the file prefix is the same.
Therefore, you can write it like this, and there is no problem.
app:main.o add.o sub.o gcc main.o add.o sub.o -o app
In this way, the write effect is the same as above. But this still cannot achieve the desired effect, Dont do yourself
So we continue to optimize Makefile. Below we use the Makefile function to obtain the required files,
src=$(wildcard *.c)obj=$(patsubst %.c,%.o,$(src))app:$(obj)gcc $(obj) -o app
In this way, we first obtain all. c file, save it in the src variable, and then save all. replace c. o is saved in the variable obj. the following $ (obj) is only the value of the variable. Therefore, we do not need to modify the number of. c files added to the current directory. Only single directory compilation is supported.
But again, I am tired of it, but I really have to wait a moment, optimization is what programmers have been doing. Therefore, we will continue to optimize Makefile. For example, I want to easily specify parameters during compilation, output executable file names, and even change the compiler. Can this work? Okay, you can do that. But you have to look at the following:
CFLAGS= -g -WallLDFLAGS=CPPFLAGS=-I.CC=gcc#CC=clangtarget=appsrc=$(wildcard *.c)obj=$(patsubst %.c,%.o,$(src))$(target):$(obj)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ .PHONY:cleanclean:rm -f $(obj)rm -f $(targe)
OK. The single directory of the final version can be written without interfering with the general compilation Makefile OF THE c file. This file can specify the compilation options, preprocessing options, and library file options,
You can change the compiler or the output file name. You only need to modify the variables at the beginning of the file.