(二)Makefile的编写规则、make的运行规则

时间:2022-01-11 22:19:35

Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作 。简单说一个工程文件有很多.c文件,我一个make命令可以完成一系列的编译操作,不用一条一条gcc敲入,而具体由Makefile文件配置实现。

一:makefile的编写规则

主要三部分!
目标体(target)、依赖的文件(dependency_file)、命令(command)

target: dependency_files
< TAB >command

需要由make工具创建的目标体(target),通常是目标文件或可执行文件;
要创建的目标体所依赖的文件(dependency_file)
创建每个目标体时需要运行的命令(command),这一行必须以制表符(tab键)开头;

一个简单例子:
hello.c

#include<stdio.h> 
void hello()
{
printf("hello world\n");
}

hello.h

void hello();

main.c

#include <stdio.h>
#include "hello.h"
int main()
{
hello();
return 0;
}

Makefile文件就这样编写:

main:main.o hello.o
gcc main.o hello.o -o main
main.o:main.c
gcc -c main.c -o main.o
hello.o:hello.c
gcc -c hello.c -o hello.o
clean:
rm -f *.o main

执行命令make,就会生成可执行文件main
如果执行make clean就把生成的文件删除

Makefile的变量

用户自定义变量
预定义变量
自动变量
环境变量

1:用自定义变量简单化Makefile:

OBJS = main.o hello.o
CC = gcc
main:$(OBJS)
$(CC) $(OBJS) -o main
main.o:main.c
$(CC) -c main.c -o main.o
hello.o:hello.c
$(CC) -c hello.c -o hello.o
clean:
rm -f *.o main

自定义变量OBJS 、CC,调用时要加个$()。

makefile中常见的自动变量 和环境变量
(二)Makefile的编写规则、make的运行规则

make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量,如果用户在makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量 。

2:用自动变量简单化Makefile:

OBJS = main.o hello.o
CC = gcc
main:$(OBJS)
$(CC) $^ -o $@
main.o:main.c
$(CC) -c $^ -o $@
hello.o:hello.c
$(CC) -c $^ -o $@
clean:
rm -f *.o main

隐晦规则

隐含规则作用是能够告诉make怎样使用传统的规则完成任务,这样,当用户使用它们时就不必详细指定编译的具体细节,而只需把目标文件列出即可 。
那为什么可以不知道细节呢,就是因为make有很多隐晦规则,就是很多编译的规则和命令(比如“.o” 的目标的依赖目标会自动推导为“.s等等),当用户make 就会在这些规则中寻找所需要规则和命令。 当然, 我们也可以使用 make的参数“-r”或“–no-builtin-rules”选项来取消所有的预设置的隐含规则

1、Makefie 使用隐晦规则例子

上面的Makefile还可以这样写

OBJS = main.o hello.o

main:$(OBJS)
main.o: main.c
hello.o: hello.c

.PHONY : clean
clean:
rm -f *.o main

隐晦规则的作用,只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中
上面文件内容中,“.PHONY”表示,clean是个伪目标文件,这样可以保证clean目标每次都能被重新生成

上面的例子还可以这样写

OBJS = main.o hello.o

main:$(OBJS)
clean:
rm -f *.o main

模式规则

模式规则是可以来定义一个隐含规则。 一个模式规则就好像一个一般的规则, 只是在规则中,目标的定义需要有”%”字符。”%”的意思是表示一个或多个任意字符。在依赖目标中同样可以使用”%”,只是依赖目标中的”%”的取值,取决于其目标。

OBJS = main.o hello.o
CC = gcc
main:$(OBJS)
$(CC) $(OBJS) -o main
%.o:%.c
$(CC) -c $^ -o $@
clean:
rm -f *.o main

先把所有的[.c]文件都编译成[.o]文件,再生成可执行文件main

二、make的运行规则

(二)Makefile的编写规则、make的运行规则

执行make的时候,先在目录下寻找makefile文件,如果不存在,再继续找Makefile;

主要讲讲-C 和-f 的参数

make -C ./test-1 -f MyMakefile

在目录下的test-1文件下,make运行名字为MyMakefile的文件