Makefile规则与示例一

程序的编译过程
4个步骤:预处理,编译,汇编,链接.
预处理: 检测语法错误,把头文件包含进来,宏展开.
编译:把. c文件转换成汇编文件.s
汇编:把. s文件转换成二进制文件.o
链接:. .o文件+库文件 =可执行程序
gcc -v -o hello hello.c 就可观看到编译的细节.
gcc -c -o a.o a.c //-c 把预处理,编译,汇编 做完 链接不做.

1.Makefile的作用:高效地编译程序,在修改源文件或者头文件,只需要重新编译牵涉到的文件,就可以重新生成APP
(1) 一起编译、链接:
修改过的,没有被修改过的,都一起编译, 文件很多的时候,编译会花销很大时间

gcc main.c sub.c -o 

(2)分开编译,统一链接:
修改过的文件,只会重新生成它的 .o 文件

gcc -c main.c -o main.o
gcc -c sub.c -o sub.o
gcc main.o sub.o -o test

Makefile 自动的帮助我们查看哪个文件被修改过,然后编译它链接它

2.Makefile的简单样式:一个简单的Makefile文件包含一系列的“规则”,其样式如:
目标:依赖
命令
如果“依赖文件”比“目标文件”更加薪,那么执行“命令”来重新生成“目标文件”。命令被执行的2个条件:依赖文件比目标文件新,或者是目标文件还没生成。

由简入难的demo
main.c

#include <stdio.h>

extern void s_fun();

int main()
{
    
    
        printf("Main s_fun\n");
        s_fun();
        return 0;
}

sub.c

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

void s_fun()
{
    
    
	 printf("s_fun, A = %d\n",A);
}

sub.h

#define A 1
void s_fun();

第一个Makefile

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

第二个Makefile
make 没有指定目标会去查找第一个目标 test,要想执行第二个目标,需要指定,make clean

test : main.o sub.o 
        gcc main.o sub.o -o test
main.o : main.c
        gcc -c main.c -o main.o
sub.o : sub.c
        gcc -c sub.c -o sub.o
clean :
        rm *.o test -f

第三个Makefile
如修改了sub.h A 为2 ,重新make 无效,A 仍然为1
在这里插入图片描述

test : main.o sub.o 
        gcc main.o sub.o -o test
%.o : %.c
        gcc -c $< -o $@
clean :
        rm *.o test -f

第四个Makefile
使修改后的头文件,能够输出 A =2,两个同目标的规则,一个有命令另一个没有命令,它们将合并在一起

test : main.o sub.o
        gcc main.o sub.o -o test
%.o : %.c
        gcc -c $< -o $@
sub.o : sub.h

clean :
        rm *.o test -f

3.先介绍两个Makefile函数
(1)$(foreach var,list,text) 对list 中的每一个元素取出来赋给var,然后把var改为text所描述的形式

objs := a.o b.o
dep_files := $(foureach f, $(objs), .$(f).d)   //最终 dep_files := .a.o.d .b.o.d

(2)$(wildcard pattern) pattern 所列出的文件是否存在,把存在的文件都列出来

dep_file := $(wildcard *.c)  //最终src_files中列出了当前目录下的所以 .c文件

第五个Makefile
此Makefile不支持子目录下的文件

objs := main.o sub.o

test :  $(objs)
        gcc main.o sub.o -o test
#需要判断是否存在依赖文件
dep_files := $(foreach f, $(objs), .$(f).d)

#把依赖文件包含进来
dep_files := $(wildcard $(dep_files))

#判断
ifneq ($(dep_files), )
        include $(dep_files)
endif
%.o : %.c
        gcc -Wp,-MD,.$@.d -c $< -o $@
sub.o : sub.h

#clean :
#       rm *.o test -f
distclean : 
        rm $(dep_files) *.o test -f

猜你喜欢

转载自blog.csdn.net/qq_46777053/article/details/113420400