makefile生成多个目标文件的写法(linux程序员必须掌握的程序编译技能)

小编读完陈皓大神关于Makefile的博客之后,对Makefile的使用有了更深入的理解,在此附上陈皓大神makefile博客的链接:https://blog.csdn.net/haoel/article/details/2886。博客中针对Makefile的介绍、编译和链接原理、以及规则都做了详细的介绍,因此小编在此仅归纳两种常用的makefile文件的写法,希望可以帮助读者掌握Makefile的写法。(阅读过程中若有不理解之处,可参考陈皓大神的博客,以此来提升理解)

一、初学者和小项目可使用的makefile写法

举例:一个项目有1个头文件(wrap.h),三个源文件(server.c、client.c、wrap.c),要生成可执行目标文件server、client,最简单的写法如下所示:

all:server client    //目标文件server和client

server:server.o wrap.o  //server的依赖为server.o和wrap.o
  gcc server.o wrap.o -o server -Wall   //利用gcc编译器生成可执行文件server
  
client:client.o wrap.o  //client的依赖为client.o和wrap.o
  gcc client.o wrap.o -o client -Wall  //利用gcc编译器生成可执行文件client

server.o:server.c wrap.h  //server.o的依赖为server.c和wrap.h
  gcc -c server.c -o server.o -Wall  //利用gcc编译器生成中间目标文件server.o

client.o:client.c wrap.h  //同上
  gcc -c client.c -o client.o -Wall

wrap.o:wrap.c wrap.h   //同上
  gcc -c wrap.c -o wrap.o -Wall

在终端输入命令make,运行makefile文件可得到编译结果如下:
makefile生成多个目标文件的写法(linux程序员必须掌握的程序编译技能)_第1张图片
我们可以看到编译成功,成功生成了client.o、wrap.o、server.o等中间目标文件以及client、server等可执行目标文件,并且运行服务器端和客户端可以实现其功能,在此就不演示了。
该方法比较易懂,只需要依次对我们的.c文件形成依赖关系,就可以根据目标文件的需要生成对应的依赖目标,但是当一个项目比较大即有大量的.c文件时,程序员需要编写大量的依赖关系,工作量是非常大的,且容易遗漏出错,因此需要掌握下面的方法

二、大项目必须会使用的makefile写法

举例同上,makefile文件为:

target1=server        //服务器运行目标文件server
target2=client        //客户端目标文件client
src=$(wildcard *.c)   //用wildcard函数找到所有.c文件,server.c、client.c、wrap.c
deps=$(wildcard *.h)   //用wildcard函数找到所有的.h文件,wrap.h
obj=$(patsubst %.c,%.o,$(src))    //用patsubst函数将所有.c文件替换成.o文件

all:$(target1) $(target2)    //目标文件server和client,多个目标文件一定形成此依赖关系

$(target1):server.o wrap.o  //server的依赖为server.o和wrap.o
  gcc $^ -o $@ -Wall   //利用gcc编译器生成可执行文件server
  
$(target2):client.o wrap.o  //client的依赖为client.o和wrap.o
  gcc $^ -o $@ -Wall  //利用gcc编译器生成可执行文件client

%.o:%.c $(deps)  //任意一个.o中间目标文件的依赖是其对应的.c文件,如:client.o的依赖为client.c
  gcc -c $< -o $@ -Wall   //根据目标文件编译的需求依次将依赖编译成对应的中间目标文件

.PHONY:clean  //伪文件,需要在终端输入make clean才会调用
clean:
  -rm -rf $(target1) $(target2) $(obj)   //删除所有的目标文件以及中间目标文件,用于重新编译。

在终端输入命令make,运行makefile文件可得到编译结果如下:
makefile生成多个目标文件的写法(linux程序员必须掌握的程序编译技能)_第2张图片
我们可以看到编译结果与第一种方法是一样的,但是依赖关系的表示却十分简单,即使有几百个依赖关系也同样适用,所以这种写法对大型项目的开发是非常有好处的

常用的三个自动变量含义:

 1、$<     第一个依赖文件,若有多个目标文件,依次编译依赖文件
 2、$^     所有依赖文件的集合
 3、$@     目标文件的集合

三、常用的makefile文件模板

在本例中,因为涉及到服务器端server和客户端client有多个目标文件,但是常规项目中往往只有一个目标文件,这样makefile的写法就更为简单了,可套用以下模板:

target=main   //想要生成的可执行文件名称可自定义,此处为main
src=$(wildcard *.c)
deps=$(wildcard *.h)
obj=$(patsubst %.c,%.o,$(src))

$(target):$(obj)
  gcc $^ -o $@ -Wall

%.o:%.c $(deps)
  gcc -c $< -o $@ -Wall

.PHONY:clean
clean:
  -rm -rf $(target) $(obj) 

四、总结

常见的生成一个目标文件的makefile,直接套用第三种方法的模板即可,
生成多个目标文件的makefile,可参照第二种方法的案例再稍加修改即可。

若有疑问,可在评论区留言!

你可能感兴趣的:(makefile,linux)