在这里我们介绍多文件Makefile的编写,多文件标准工程目录的Makefile的编写及通用模板。

以加、减、乘、除为基础建立一个小的计算器,源代码如下:

主函数cal.c

#include <stdio.h>

int main()
{
    printf("a + b = %d\n", add(10, 5));
    printf("a - b = %d\n", sub(10, 5));
    printf("a * b = %d\n", mul(10, 5));
    printf("a / b = %d\n", div(10, 5));

    return 0;
}

加法 add.c

int add(int a, int b)
{
    return a + b;
}

减法 sub.c

int sub(int a, int b)
{
    return a - b;
}

乘法 mul.c

int mul(int a, int b)
{
    return a * b;
}

除法 div.c

int div(int a, int b)
{
    return a / b;
}

一、多文件Makefile的编写

打开Makefile编写页面:

vim Makefile

代码如下:

cal : cal.o add.o sub.o mul.o div.o
	gcc cal.o add.o sub.o mul.o div.o -o cal
cal.o : cal.c
	gcc -c cal.c
add.o : add.c
	gcc -c add.c
sub.o : sub.c
	gcc -c sub.c
mul.o : mul.c
	gcc -c mul.c
div.o : div.c
	gcc -c div.c

从下图看到,开始只有.c文件,在编写完上图Makefile代码并执行了make之后,此时生成了目标文件和可执行文件,运行可执行文件,可以得到相应的结果。这里写图片描述

还可以用make clean删除生成的目标文件和可执行文件,Makefile代码如下:

cal : cal.o add.o sub.o mul.o div.o
	gcc cal.o add.o sub.o mul.o div.o -o cal
cal.o : cal.c
	gcc -c cal.c
add.o : add.c
	gcc -c add.c
sub.o : sub.c
	gcc -c sub.c
mul.o : mul.c
	gcc -c mul.c
div.o : div.c
	gcc -c div.c

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

结果如下,可以看到在执行了make clean之后所有的目标文件和可执行文件都被删除了:
这里写图片描述
如果有多个源文件,再利用上述方法编写Makefile,容易遗漏或者是写错文件名,并且如果一个文件名被修改,会导致我们需要把代码中所有该文件名都修改掉,麻烦而且浪费时间。那么可以用变量代替文件名。将图1所示代码修改如下:

obj = cal.o add.o sub.o mul.o div.o

cal : $(obj)
	gcc $(obj) -o cal
cal.o : cal.c
	gcc -c cal.c
add.o : add.c
	gcc -c add.c
sub.o : sub.c
	gcc -c sub.c
mul.o : mul.c
	gcc -c mul.c
div.o : div.c
	gcc -c div.c

可以看到用变量和图1所示代码最后的结果是相同的,并且利用变量更加简洁方便:这里写图片描述
二、多文件标准工程目录的Makefile编写

在上述多文件Makefile的编写中,我们将所有的源文件放在了一个目录里,如果有大量的源文件,将其放在一个目录里不利于管理,所以要按照不同的分类方法将其分别放在不同的目录里,而上述过程只能用于源文件在相同目录下,下面介绍源文件放在不同目录下的Makefile文件该如何编写。

首先创建一个目录cal,并在目录里创建分别放加、减、乘、除和主函数的目录,同时创建一个scripts目录。分别将源代码放在相应的目录的src目录里:
 这里写图片描述

在这里就要首先提一下Makefile的类型,一共分为三类:

  1. 总控Makefile:进入各个功能子目录里执行make命令,将所有的“.o”文件链接生成最终的可执行文件。
  2. 功能子目录Makefile:将src(放源代码的目录)目录下的“.c”文件编译成“.o”文件。
  3. scripts目录的Makefile:定义许多变量(相当于C语言的头文件),提高make的灵活性和维护性。

以下分别列出编写的三类Makefile的代码:

scripts目录的Makefile:

CC := gcc
CFLAGS := -Wall -O3
Libs = -lpthread
Target := cal
Source := $(wildcard src/*.c)
Objs := $(patsubst %.c,%.o,$(Source))
Modules += add sub mul div main
AllObjs := $(addsuffix /src/*.o,$(Modules))

总控Makefile:

include scripts/Makefile

modules_make = $(MAKE) -C $(1);
modules_clean = $(MAKE) clean -C $(1);

.PHONY: all mm mc clean

all: $(Target)

mm:
	@ $(foreach n,$(Modules),$(call modules_make,$(n)))
mc:
	@ $(foreach n,$(Modules),$(call modules_clean,$(n)))

$(Target): mm
	$(CC) $(CFLAGS) -o $(Target) $(AllObjs) $(Libs)
	@ echo $(Target) make done!

clean: mc
	rm -rf $(Target)
	@ echo clean done!

功能子目录Makefile(每个功能子目录的Makefile的代码是一样的):

include ../scripts/Makefile

all: $(Objs)

clean:
	rm -rf $(Objs)

执行make后目录如下:
这里写图片描述
运行可执行文件之后,得到正确的结果。
这里写图片描述
在这里,上述多文件标准工程目录的Makefile编写的三类Makefile可以作为一个模板,只需要在编写时修改部分内容即可。详情请关注下一篇文章《多文件标准工程目录的Makefile通用模板详解》。

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:23 天前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐