Use of Makefile project manager

(1), Makefile

(1) Introduction to Make

1) The project manager, as the name implies, refers to the management of more files

2) The Make project manager is also an "automatic compilation manager". The "automatic" here means that it can

Automatically discovers updated files to reduce the workload of compilation, and at the same time, it performs a large amount of compilation work by reading the contents of the Makefile

3) Make will only compile the changed code files instead of compiling them completely.

(2) Basic structure of Makefile

Makefile is the only configuration file that Make reads

1) The target body (target) created by the make tool, usually an object file or an executable file

2) The file that the target body to be created depends on (dependency_file)

3) The command (command) that needs to be run when creating each target body

4) Note: There must be a "TAB key" in front of the command line, otherwise the compilation error is: *** missing separator. Stop.

Makefile format

target : dependency_files

<TAB> command

example

hello.o : hello.c hello.h

gcc –c hello.c –o hello.o

(3) Makefile variable

A more complicated example

sunq:kang.o yul.o

gcc kang.o yul.o -o sunq

kang.o : kang.c kang.h

gcc –Wall –O -g –c kang.c -o kang.o

yul.o : yul.c

gcc - Wall –O -g –c yul.c -o yul.o

Notes:

-Wall: Indicates that all useful warning messages of gcc are allowed.

-c: Just compile without linking, generate object file ".o"

-o file: means to output the output file to file

Example use:

1、创建f1.c文件

#include "stdio.h"

void printf1()
{
	printf("i am f1!\n");
}


2、创建f2.c文件

void printf2()
{
	printf("i am f2!\n");
}


3、创建函数声明文件head.c

void printf1();
void printf2();


4、创建主函数文件main.c

#include "head.h"   //先在当前目录下找这个头文件,找不到再去库函数里面去找

int main(int argc, const char *argv[])
{
	printf1();
	printf2();
	
	return 0;
}


5、创建文件Makefile

test:f1.o f2.o main.o
	gcc f1.o f2.o main.o -o test
f1.o:f1.c
	gcc -c  f1.c -o f1.o
f2.o:f2.c
	gcc -c  f2.c -o f2.o
main.o:main.c
	gcc -c  main.c -o main.o


.PHONY:clean
clean:
	rm *.o test    //删除.o文件          最后执行make clean即可


6、执行代码

 make

执行结果为;

gcc -c  f1.c -o f1.o
gcc -c  f2.c -o f2.o
gcc -c  main.c -o main.o
gcc f1.o f2.o main.o -o test

About more man tools

(4) Create and use variables

1) The purpose of creating variables:

Used in place of a text string:

1. The name of the series file

2. Parameters passed to the compiler

3. Programs that need to be run

4. Need to find the source code directory

5. The directory where you need to output information

6. Anything else you want to do.

2) Two ways of variable definition

a. Recursive expansion method VAR=var

b. Simple way VAR: =var

Variables use $(VAR)

Use "$" to use "$$" to represent,

Similar to macros in programming languages

3) The example just now

OBJS = kang.o yul.o

CC = gcc

CFLAGS = -Wall -O -g

sunq : $(OBJS)

$(CC) $(OBJS) -o sunq

kang.o : kang.c kang.h

$(CC) $(CFLAGS) -c kang.c -o kang.o

yul.o : yul.c yul.h

$(CC) $(CFLAGS) -c yul.c -o yul.o

4) Recursive expansion method VAR=var

example:

foo = $(bar)

bar = $(ugh)

ugh = Huh?

What is the value of $(foo)?

echo $(foo) to view

5) Advantages:

it can backreference variables

Disadvantage: You cannot do any expansion of this variable, e.g.

CFLAGS = $(CFLAGS) -O

will cause an endless loop

6) Simple way VAR:=var

m := mm

x := $(m)

y := $(x) bar

x := later

echo $(x) $(y)

See what information is printed?

Variables defined in this way will be expanded according to the current value of the referenced variable at the point of variable definition

This way of defining variables is more suitable for use in large programming projects, because it is more like our general programming language

7) Define variables with ?=

dir := /foo/bar

FOO ?= bar

What is FOO?

The meaning is that if FOO has not been defined, then the value of the variable FOO is "bar",

If FOO was previously defined, then this statement will do nothing, which is equivalent to:

ifeq ($(origin FOO), undefined)

FOO = bar

endif

8) Add value to variable

You can add new values ​​to already defined variables with +=

Main=hello.o hello-1.o

Main+=hello-2.o

9) Predefined variables

The name of the AR library file maintenance program, the default value is ar. AS The name of the assembler, the default is as.

CC The name of the C compiler, default is cc. The name of the CPP C precompiler, default is $(CC) –E.

The name of the CXX C++ compiler, the default is g++.

FC FORTRAN compiler name, default is f77

RM The name of the file removal program, the default is rm -f

10) Example:

Hello: main.c main.h

<tab> $(CC) –o hello main.c

clean:

<tab> $(RM) hello

11) Predefined variables

ARFLAGS Option for the library file maintainer, no default.

ASFLAGS Assembler options, no default.

CFLAGS Option for the C compiler, no default.

CPPFLAGS C precompiled options, no default value.

CXXFLAGS C++ compiler option, no default value.

FFLAGS FORTRAN compiler option, no default.

12) The previous example

OBJS = kang.o yul.o

CC = gcc

CFLAGS = -Wall -O -g

sunq : $(OBJS)

$(CC) $(OBJS) -o sunq

kang.o : kang.c kang.h

$(CC) $(CFLAGS) -c kang.c -o kang.o

yul.o : yul.c yul.h

$(CC) $(CFLAGS) -c yul.c -o yul.o

13) Automatic variables

$* object file name without extension

$+ All dependent files, separated by spaces, in order of appearance, may contain duplicate dependent files

$< the name of the first dependent file

$? All dependent files with timestamps later than the target file, separated by spaces

$@ the full name of the object file

$^ All non-repeating target dependent files, separated by spaces

$% If the target is an archive member, this variable represents the target's archive member name

14) The previous example:

OBJS = kang.o yul.o

CC = gcc

CFLAGS = -Wall -O -g

sunq : $(OBJS)

$(CC) $^ -o $@

kang.o : kang.c kang.h

$(CC) $(CFLAGS) -c $< -o $@

yul.o : yul.c yul.h

$(CC) $(CFLAGS) -c $< -o $@

15) Environment variables

1) make will automatically read the environment variables currently defined by the system at startup, and will create variables with the same name and value

2) If the user defines a variable with the same name in the Makefile, the user-defined variable will override the environment variable with the same name

(2), Make use

run make directly

options

-C dir reads the Makefile in the specified directory

-f file reads the file file in the current directory as Makefile

-i ignore all command execution errors

-I dir specifies the directory where the included Makefile is located

-n only prints the commands to be executed, but does not execute them

-p show make variable database and implicit rules

-s do not display the command while executing the command

-w If make changes directories during execution, print the current directory name

(3) The implicit rules of Makefile

Implicit rule 1: Implicit rules for compiling C programs

The target-dependent target of "<n>.o" is automatically deduced as "<n>.c" and its build command is "$(CC) -c $(CPPFLAGS) $(CFLAGS)"

Implicit rule 2: The implicit rule of linking Object Enjian

The "<n>" target depends on "<n>.o", which is generated by running the linker (usually "ld") by running the C compiler,

Its generation command is: "$(CC) $(LDFLAGS) <n>.o"

"$(LOADLIBES) $(LDLIBS)", this rule is valid for projects with only one source file, and it is also valid for multiple Object files (generated from different source files)

For example as follows:

rule:

x:x.o y.o z.o

And when "xc", "yc" and "zc" all exist, the implicit rule will execute the following commands:

cc -c x.c -o x.o

cc -c y.c -o y.o

cc -c z.c -o z.o

cc x.o y.o z.o -o x

If there is no source file (xc in the example above) associated with your target name (x in the example above),

Then, you'd better write your own generation rules, otherwise, the implicit rules will report an error

(4), the usage of VPATH

(1) VPATH: virtual path

1) In some large projects, there are a large number of source files. Our usual practice is to classify these many source files.

and stored in different directories. So, when make needs to find a file's dependencies, you can do it in the file

Add the path before, but the best way is to tell make a path and let make find it automatically.

2) The special variable "VPTH" in the Makefile is used for this function. If this variable is not specified,

make will only look for dependencies and object files in the current directory. If this variable is defined, then make will be in the current

If the directory cannot be found, the file is searched in the specified directory.

3) VPATH = src:../headers

4) The above definition specifies two directories, "src" and "../headers", and make will search in this order.

Directories are separated by "colon". Of course, when the current directory is always the highest priority search place

(5), nested Makefile

(1) case

- We noticed a line @echo $(SUBDIRS)

- @(RM) is not a variable defined by us, so where did it come from?

- make -C $@

- export CC OBJS BIN OBJS_DIR BIN_DIR

Guess you like

Origin blog.csdn.net/qq_52049228/article/details/129450893